From b560daac21673e1fdfd3251b7b49f498321552f1 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 17 Oct 2016 15:30:28 -0700 Subject: [PATCH 001/112] suspend.fish: print help on -h, --help --- share/functions/suspend.fish | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/functions/suspend.fish b/share/functions/suspend.fish index 8d609dec1..af2ce5012 100644 --- a/share/functions/suspend.fish +++ b/share/functions/suspend.fish @@ -1,4 +1,8 @@ function suspend -d "Suspend the current shell." + if contains -- $argv --help; or contains -- $argv -h + __fish_print_help suspend + and return 0 + end if begin contains -- $argv --force or not status --is-interactive and not status --is-login end From cc31cda835a99f7646ebf976b82090350f8ee484 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 17 Oct 2016 18:36:34 -0700 Subject: [PATCH 002/112] Update CHANGELOG.md Tweak verbiage re: colors --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4911479a..ffd7f33ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,10 @@ ## Notable fixes and improvements - The `fish_realpath` builtin has been renamed to `realpath` and made compatible with GNU `realpath` when run without arguments (#3400). It is used only for systems without a `realpath` or `grealpath` utility (#3374). +- Improved color handling on terminals/consoles with 8-16 colors. Particularly bright named color usability has improved. (#3176, #3260). - `fish_indent` can now read from named files, rather than just standard input (#3037). - Fuzzy tab completions behave in a less surprising manner (#3090, #3211). - `jobs` should only print its header line once (#3127). -- Improved color handling on terminals with limited colors (#3176, #3260). - Wildcards in redirections are highlighted appropriately (#2789). - Suggestions will be offered more often, like after removing characters (#3069). - `history --merge` now correctly interleaves items in chronological order (#2312). From 8a2d6a97528b1afe8be371b7adab5fa422fe50c6 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Mon, 17 Oct 2016 16:23:29 -0700 Subject: [PATCH 003/112] fix/unify tests for chars in fish reserved ranges --- src/common.cpp | 14 ++++++++++++++ src/common.h | 3 +++ src/reader.cpp | 21 ++++----------------- src/wutil.cpp | 14 +++----------- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 9f7d9c504..22235cdad 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1935,3 +1935,17 @@ long convert_digit(wchar_t d, int base) { return res; } + +// Test if the specified character is in a range that fish uses interally to store special tokens. +// +// NOTE: This is used when tokenizing the input. It is also used when reading input, before +// tokenization, to replace such chars with REPLACEMENT_WCHAR if they're not part of a quoted +// string. We don't want external input to be able to feed reserved characters into our lexer/parser +// or code evaluator. +// +// TODO: Actually implement the replacement as documented above. +bool fish_reserved_codepoint(wchar_t c) { + return (c >= RESERVED_CHAR_BASE && c < RESERVED_CHAR_END) || + (c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) || + (c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END); +} diff --git a/src/common.h b/src/common.h index 0cf6a3bc0..2467b2429 100644 --- a/src/common.h +++ b/src/common.h @@ -776,3 +776,6 @@ long convert_digit(wchar_t d, int base); } while (0) #endif + +// Return true if the character is in a range reserved for fish's private use. +bool fish_reserved_codepoint(wchar_t c); diff --git a/src/reader.cpp b/src/reader.cpp index d044a1753..88f13cee2 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2351,20 +2351,6 @@ static int can_read(int fd) { return select(fd + 1, &fds, 0, 0, &can_read_timeout) == 1; } -// Test if the specified character is in a range that fish uses interally to store special tokens. -// -// NOTE: This is used when tokenizing the input. It is also used when reading input, before -// tokenization, to replace such chars with REPLACEMENT_WCHAR if they're not part of a quoted -// string. We don't want external input to be able to feed reserved characters into our lexer/parser -// or code evaluator. -// -// TODO: Actually implement the replacement as documented above. -static int wchar_private(wchar_t c) { - return (c >= RESERVED_CHAR_BASE && c < RESERVED_CHAR_END) || - (c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) || - (c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END); -} - /// Test if the specified character in the specified string is backslashed. pos may be at the end of /// the string, which indicates if there is a trailing backslash. static bool is_backslashed(const wcstring &str, size_t pos) { @@ -2452,7 +2438,7 @@ const wchar_t *reader_readline(int nchars) { is_interactive_read = was_interactive_read; // fprintf(stderr, "C: %lx\n", (long)c); - if (((!wchar_private(c))) && (c > 31) && (c != 127)) { + if (((!fish_reserved_codepoint(c))) && (c > 31) && (c != 127)) { if (can_read(0)) { wchar_t arr[READAHEAD_MAX + 1]; size_t i; @@ -2472,7 +2458,7 @@ const wchar_t *reader_readline(int nchars) { // need to insert on the commandline that the commmand might need to be able // to see. c = input_readch(false); - if ((!wchar_private(c)) && (c > 31) && (c != 127)) { + if ((!fish_reserved_codepoint(c)) && (c > 31) && (c != 127)) { arr[i] = c; c = 0; } else @@ -3260,7 +3246,8 @@ const wchar_t *reader_readline(int nchars) { } default: { // Other, if a normal character, we add it to the command. - if (!wchar_private(c) && (c >= L' ' || c == L'\n' || c == L'\r') && c != 0x7F) { + if (!fish_reserved_codepoint(c) && (c >= L' ' || c == L'\n' || c == L'\r') && + c != 0x7F) { bool allow_expand_abbreviations = false; if (data->is_navigating_pager_contents()) { data->pager.set_search_field_shown(true); diff --git a/src/wutil.cpp b/src/wutil.cpp index 0461b9a38..608caf7f8 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -448,14 +448,6 @@ int wrename(const wcstring &old, const wcstring &newv) { return rename(old_narrow.c_str(), new_narrow.c_str()); } -/// Return one if the code point is in the range we reserve for internal use. -int fish_is_reserved_codepoint(wint_t wc) { - if (RESERVED_CHAR_BASE <= wc && wc < RESERVED_CHAR_END) return 1; - if (EXPAND_RESERVED_BASE <= wc && wc < EXPAND_RESERVED_END) return 1; - if (WILDCARD_RESERVED_BASE <= wc && wc < WILDCARD_RESERVED_END) return 1; - return 0; -} - /// Return one if the code point is in a Unicode private use area. int fish_is_pua(wint_t wc) { if (PUA1_START <= wc && wc < PUA1_END) return 1; @@ -467,7 +459,7 @@ int fish_is_pua(wint_t wc) { /// We need this because there are too many implementations that don't return the proper answer for /// some code points. See issue #3050. int fish_iswalnum(wint_t wc) { - if (fish_is_reserved_codepoint(wc)) return 0; + if (fish_reserved_codepoint(wc)) return 0; if (fish_is_pua(wc)) return 0; return iswalnum(wc); } @@ -475,7 +467,7 @@ int fish_iswalnum(wint_t wc) { /// We need this because there are too many implementations that don't return the proper answer for /// some code points. See issue #3050. int fish_iswalpha(wint_t wc) { - if (fish_is_reserved_codepoint(wc)) return 0; + if (fish_reserved_codepoint(wc)) return 0; if (fish_is_pua(wc)) return 0; return iswalpha(wc); } @@ -483,7 +475,7 @@ int fish_iswalpha(wint_t wc) { /// We need this because there are too many implementations that don't return the proper answer for /// some code points. See issue #3050. int fish_iswgraph(wint_t wc) { - if (fish_is_reserved_codepoint(wc)) return 0; + if (fish_reserved_codepoint(wc)) return 0; if (fish_is_pua(wc)) return 1; return iswgraph(wc); } From dcb39af8c0860abea04bce9d5fa502fd7ba9e2b6 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 17 Oct 2016 18:47:55 -0700 Subject: [PATCH 004/112] Fix lexicon_filter verbosity the `mv $@.tmp $@; test -x $@ || chmod a+x $@;` bit was printing out. --- Makefile.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.in b/Makefile.in index ee373324d..adea719c5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -453,8 +453,9 @@ lexicon_filter: lexicon.txt lexicon_filter.in | show-SED WORDBL='[[:<:]]'; WORDBR='[[:>:]]'; \ else \ WORDBL='\\<'; WORDBR='\\>'; \ - fi; $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p'; - mv $@.tmp $@; test -x $@ || chmod a+x $@; + fi + $v $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p' + $v mv $@.tmp $@; test -x $@ || chmod a+x $@; # From 3eb7a8fa09ac94cf4a76109b896f7ba58959f5a8 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 18 Oct 2016 21:57:07 +0800 Subject: [PATCH 005/112] CHANGELOG: some grammar changes --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffd7f33ae..4e56b963c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,14 @@ - `history search` is now case-insensitive by default (which also affects `history delete`) (#3236). - `history delete` now correctly handles multiline commands (#31). - Vi-style bindings no longer include all of the default emacs-style bindings; instead, they share some definitions (#3068). -- If there is no locale set in the environment, various known system configuration files will be checked for a default, otherwise forcing en_US-UTF.8 (#277). +- If there is no locale set in the environment, various known system configuration files will be checked for a default. If no locale can be found, `en_US-UTF.8` will be used (#277). - A number followed by a caret (e.g. `5^`) is no longer treated as a redirection (#1873). - The `$version` special variable can be overwritten, so that it can be used for other purposes if required. ## Notable fixes and improvements - The `fish_realpath` builtin has been renamed to `realpath` and made compatible with GNU `realpath` when run without arguments (#3400). It is used only for systems without a `realpath` or `grealpath` utility (#3374). -- Improved color handling on terminals/consoles with 8-16 colors. Particularly bright named color usability has improved. (#3176, #3260). -- `fish_indent` can now read from named files, rather than just standard input (#3037). +- Improved color handling on terminals/consoles with 8-16 colors, particularly the use of bright named color (#3176, #3260). +- `fish_indent` can now read from files given as arguments, rather than just standard input (#3037). - Fuzzy tab completions behave in a less surprising manner (#3090, #3211). - `jobs` should only print its header line once (#3127). - Wildcards in redirections are highlighted appropriately (#2789). From 345950ac1b15595edc73ff5ea126cd2b1f9ff627 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 19 Oct 2016 13:35:30 -0700 Subject: [PATCH 006/112] workaround broken groff man page config Fixes #2673 --- Makefile.in | 2 ++ share/functions/__fish_print_help.fish | 5 +++-- share/groff/fish.tmac | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 share/groff/fish.tmac diff --git a/Makefile.in b/Makefile.in index adea719c5..243d8fde4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -650,6 +650,7 @@ install-force: all install-translations | show-datadir show-sysconfdir show-extr $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/completions $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/functions + $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/groff $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/man/man1 $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/tools $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/tools/web_config @@ -674,6 +675,7 @@ install-force: all install-translations | show-datadir show-sysconfdir show-extr $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \ done; @echo "Installing $(bo)man pages$(sgr0)"; + $v $(INSTALL) -m 644 share/groff/* $(DESTDIR)$(datadir)/fish/groff/ $v for i in $(wildcard share/man/man1/*.1); do \ $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/man/man1/; \ done; diff --git a/share/functions/__fish_print_help.fish b/share/functions/__fish_print_help.fish index 265f96159..31190e552 100644 --- a/share/functions/__fish_print_help.fish +++ b/share/functions/__fish_print_help.fish @@ -39,10 +39,11 @@ function __fish_print_help --description "Print help message for the specified f set cols (math $cols - 4) # leave a bit of space on the right set rLL -rLL=$cols[1]n end + set -lx GROFF_TMAC_PATH $__fish_datadir/groff if test -e "$__fish_datadir/man/man1/$item.1" - set help (nroff -man -c -t $rLL "$__fish_datadir/man/man1/$item.1" ^/dev/null) + set help (nroff -c -man -mfish -t $rLL "$__fish_datadir/man/man1/$item.1" ^/dev/null) else if test -e "$__fish_datadir/man/man1/$item.1.gz" - set help (gunzip -c "$__fish_datadir/man/man1/$item.1.gz" ^/dev/null | nroff -man -c -t $rLL ^/dev/null) + set help (gunzip -c "$__fish_datadir/man/man1/$item.1.gz" ^/dev/null | nroff -c -man -mfish -t $rLL ^/dev/null) end # The original implementation trimmed off the top 5 lines and bottom 3 lines diff --git a/share/groff/fish.tmac b/share/groff/fish.tmac new file mode 100644 index 000000000..cf8dbe8fa --- /dev/null +++ b/share/groff/fish.tmac @@ -0,0 +1,14 @@ +.\" This is needed on systems that ship with groff versions older than 1.20; +.\" such as macOS up thru Sierra (10.12). See fish issue #2673. +.\" +.\" For UTF-8, map some characters conservatively for the sake +.\" of easy cut and paste. +. +.if '\*[.T]'utf8' \{\ +. rchar \- - ' ` +. +. char \- \N'45' +. char - \N'45' +. char ' \N'39' +. char ` \N'96' +.\} From 00303ed07ffd3687d01e5e3ac43904e8e48efcd0 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 20 Oct 2016 18:53:31 -0700 Subject: [PATCH 007/112] lint cleanup: parameter reassignment --- src/builtin.cpp | 2 +- src/builtin_commandline.cpp | 10 ++++------ src/builtin_set.cpp | 23 ++++++----------------- src/common.cpp | 2 +- src/common.h | 2 +- src/env.cpp | 5 +++-- src/env_universal_common.cpp | 2 +- src/fallback.cpp | 2 +- src/output.cpp | 9 +++------ src/parse_util.cpp | 9 +++------ src/parser.cpp | 4 +--- src/reader.cpp | 6 +++--- src/util.cpp | 4 ++-- src/wgetopt.cpp | 5 +++-- 14 files changed, 33 insertions(+), 52 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 06944591b..5b5fa6683 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -412,7 +412,7 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u } int res = 0; - if (mode == NULL) mode = DEFAULT_BIND_MODE; + if (mode == NULL) mode = DEFAULT_BIND_MODE; //!OCLINT(parameter reassignment) while (*seq) { if (use_terminfo) { diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp index fd44975dd..4afa04f7d 100644 --- a/src/builtin_commandline.cpp +++ b/src/builtin_commandline.cpp @@ -165,16 +165,14 @@ static void write_part(const wchar_t *begin, const wchar_t *end, int cut_at_curs } streams.out.append(out); - free(buff); } else { if (cut_at_cursor) { - end = begin + pos; + streams.out.append(begin, pos); + } else { + streams.out.append(begin, end - begin); } - - // debug( 0, L"woot2 %ls -> %ls", buff, esc ); - streams.out.append(begin, end - begin); - streams.out.append(L"\n"); + streams.out.push_back(L'\n'); } } diff --git a/src/builtin_set.cpp b/src/builtin_set.cpp index 9eeea3172..0427427ec 100644 --- a/src/builtin_set.cpp +++ b/src/builtin_set.cpp @@ -159,7 +159,6 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, static int parse_index(std::vector &indexes, const wchar_t *src, const wchar_t *name, size_t var_count, io_streams_t &streams) { size_t len; - int count = 0; const wchar_t *src_orig = src; @@ -167,9 +166,7 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch return 0; } - while (*src != L'\0' && (iswalnum(*src) || *src == L'_')) { - src++; - } + while (*src != L'\0' && (iswalnum(*src) || *src == L'_')) src++; if (*src != L'[') { streams.err.append_format(_(BUILTIN_SET_ARG_COUNT), L"set"); @@ -177,7 +174,6 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch } len = src - src_orig; - if ((wcsncmp(src_orig, name, len) != 0) || (wcslen(name) != (len))) { streams.err.append_format( _(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"), L"set", @@ -186,37 +182,29 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch } src++; - - while (iswspace(*src)) { - src++; - } + while (iswspace(*src)) src++; while (*src != L']') { wchar_t *end; - long l_ind; errno = 0; - l_ind = wcstol(src, &end, 10); - if (end == src || errno) { streams.err.append_format(_(L"%ls: Invalid index starting at '%ls'\n"), L"set", src); return 0; } - if (l_ind < 0) { - l_ind = var_count + l_ind + 1; - } + if (l_ind < 0) l_ind = var_count + l_ind + 1; - src = end; + src = end; //!OCLINT(parameter reassignment) if (*src == L'.' && *(src + 1) == L'.') { src += 2; long l_ind2 = wcstol(src, &end, 10); if (end == src || errno) { return 1; } - src = end; + src = end; //!OCLINT(parameter reassignment) if (l_ind2 < 0) { l_ind2 = var_count + l_ind2 + 1; @@ -231,6 +219,7 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch indexes.push_back(l_ind); count++; } + while (iswspace(*src)) src++; } diff --git a/src/common.cpp b/src/common.cpp index 22235cdad..5c9d40e0a 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -107,6 +107,7 @@ demangled_backtrace(int max_frames, int skip_levels) { void __attribute__((noinline)) show_stackframe(const wchar_t msg_level, int frame_count, int skip_levels) { ASSERT_IS_NOT_FORKED_CHILD(); + if (frame_count < 1) return; // TODO: Decide if this is still needed. I'm commenting it out because it caused me some grief // while trying to debug a test failure. And the tests run just fine without spurious failures @@ -115,7 +116,6 @@ show_stackframe(const wchar_t msg_level, int frame_count, int skip_levels) { // Hack to avoid showing backtraces in the tester. // if (program_name && !wcscmp(program_name, L"(ignore)")) return; - if (frame_count < 1) frame_count = 999; debug_shared(msg_level, L"Backtrace:"); std::vector bt = demangled_backtrace(frame_count, skip_levels + 2); for (int i = 0; (size_t)i < bt.size(); i++) { diff --git a/src/common.h b/src/common.h index 2467b2429..3afae7a6c 100644 --- a/src/common.h +++ b/src/common.h @@ -258,7 +258,7 @@ extern bool has_working_tty_timestamps; #define contains(str, ...) contains_internal(str, 0, __VA_ARGS__, NULL) /// Print a stack trace to stderr. -void show_stackframe(const wchar_t msg_level, int frame_count = -1, int skip_levels = 0); +void show_stackframe(const wchar_t msg_level, int frame_count = 100, int skip_levels = 0); /// Read a line from the stream f into the string. Returns the number of bytes read or -1 on /// failure. diff --git a/src/env.cpp b/src/env.cpp index 79a1e0f0c..b708298b8 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -521,7 +521,7 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) // Zero element arrays are internaly not coded as null but as this placeholder string. if (!val) { - val = ENV_NULL; + val = ENV_NULL; //!OCLINT(parameter reassignment) } if (var_mode & ENV_UNIVERSAL) { @@ -569,7 +569,8 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) { // use existing entry's exportv - var_mode = preexisting_entry_exportv ? ENV_EXPORT : 0; + var_mode = + preexisting_entry_exportv ? ENV_EXPORT : 0; //!OCLINT(parameter reassignment) } } else { if (!get_proc_had_barrier()) { diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index a77eb6a6e..2bb11c521 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -1460,7 +1460,7 @@ universal_notifier_t &universal_notifier_t::default_notifier() { universal_notifier_t *universal_notifier_t::new_notifier_for_strategy( universal_notifier_t::notifier_strategy_t strat, const wchar_t *test_path) { if (strat == strategy_default) { - strat = resolve_default_strategy(); + strat = resolve_default_strategy(); //!OCLINT(parameter reassignment) } switch (strat) { case strategy_shmem_polling: { diff --git a/src/fallback.cpp b/src/fallback.cpp index 0c386fa1e..a9e9140f3 100644 --- a/src/fallback.cpp +++ b/src/fallback.cpp @@ -353,7 +353,7 @@ static int bisearch(wchar_t ucs, const struct interval *table, int max) { if (ucs > table[mid].last) min = mid + 1; else if (ucs < table[mid].first) - max = mid - 1; + max = mid - 1; //!OCLINT(parameter reassignment) else return 1; } diff --git a/src/output.cpp b/src/output.cpp index 2533a0dd1..9243730d4 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -312,13 +312,10 @@ int writech(wint_t ch) { if (ch >= ENCODE_DIRECT_BASE && ch < ENCODE_DIRECT_BASE + 256) { buff[0] = ch - ENCODE_DIRECT_BASE; len = 1; - } else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) - { + } else if (MB_CUR_MAX == 1) { + // single-byte locale (C/POSIX/ISO-8859) // If `wc` contains a wide character we emit a question-mark. - if (ch & ~0xFF) { - ch = '?'; - } - buff[0] = ch; + buff[0] = ch & ~0xFF ? '?' : ch; len = 1; } else { mbstate_t state = {}; diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 509c6a612..1cd4f895c 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -88,13 +88,11 @@ size_t parse_util_get_offset(const wcstring &str, int line, long line_offset) { size_t off2 = parse_util_get_offset_from_line(buff, line + 1); if (off == (size_t)-1) return (size_t)-1; - if (off2 == (size_t)-1) off2 = wcslen(buff) + 1; - - if (line_offset < 0) line_offset = 0; + if (line_offset < 0) line_offset = 0; //!OCLINT(parameter reassignment) if ((size_t)line_offset >= off2 - off - 1) { - line_offset = off2 - off - 1; + line_offset = off2 - off - 1; //!OCLINT(parameter reassignment) } return off + line_offset; @@ -763,10 +761,9 @@ static int parser_is_pipe_forbidden(const wcstring &word) { bool parse_util_argument_is_help(const wchar_t *s, int min_match) { CHECK(s, 0); - size_t len = wcslen(s); - min_match = maxi(min_match, 3); + min_match = maxi(min_match, 3); //!OCLINT(parameter reassignment) return wcscmp(L"-h", s) == 0 || (len >= (size_t)min_match && (wcsncmp(L"--help", s, len) == 0)); } diff --git a/src/parser.cpp b/src/parser.cpp index 17ada81c0..d81ccac77 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -713,9 +713,7 @@ bool parser_t::detect_errors_in_argument_list(const wcstring &arg_list_src, wcst parse_error_list_t errors; // Use empty string for the prefix if it's NULL. - if (prefix == NULL) { - prefix = L""; - } + if (!prefix) prefix = L""; //!OCLINT(parameter reassignment) // Parse the string as an argument list. parse_node_tree_t tree; diff --git a/src/reader.cpp b/src/reader.cpp index 88f13cee2..947cd09bc 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -135,8 +135,8 @@ static void set_command_line_and_position(editable_line_t *el, const wcstring &n void editable_line_t::insert_string(const wcstring &str, size_t start, size_t len) { // Clamp the range to something valid. size_t string_length = str.size(); - start = mini(start, string_length); - len = mini(len, string_length - start); + start = mini(start, string_length); //!OCLINT(parameter reassignment) + len = mini(len, string_length - start); //!OCLINT(parameter reassignment) this->text.insert(this->position, str, start, len); this->position += len; } @@ -1898,7 +1898,7 @@ static void reader_set_buffer_maintaining_pager(const wcstring &b, size_t pos) { data->command_line_changed(&data->command_line); // Don't set a position past the command line length. - if (pos > command_line_len) pos = command_line_len; + if (pos > command_line_len) pos = command_line_len; //!OCLINT(parameter reassignment) update_buff_pos(&data->command_line, pos); diff --git a/src/util.cpp b/src/util.cpp index f13334807..b8f868094 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -47,8 +47,8 @@ int wcsfilecmp(const wchar_t *a, const wchar_t *b) { secondary_diff = (aend - a) - (bend - b); - a = aend - 1; - b = bend - 1; + a = aend - 1; //!OCLINT(parameter reassignment) + b = bend - 1; //!OCLINT(parameter reassignment) } else { int diff = towlower(*a) - towlower(*b); if (diff != 0) return diff > 0 ? 2 : -2; diff --git a/src/wgetopt.cpp b/src/wgetopt.cpp index f31b623b0..091bceeab 100644 --- a/src/wgetopt.cpp +++ b/src/wgetopt.cpp @@ -161,8 +161,9 @@ const wchar_t *wgetopter_t::_wgetopt_initialize(const wchar_t *optstring) { } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; - } else + } else { ordering = PERMUTE; + } return optstring; } @@ -211,7 +212,7 @@ int wgetopter_t::_wgetopt_internal(int argc, wchar_t **argv, const wchar_t *opts const struct woption *longopts, int *longind, int long_only) { woptarg = NULL; - if (woptind == 0) optstring = _wgetopt_initialize(optstring); + if (woptind == 0) optstring = _wgetopt_initialize(optstring); //!OCLINT(parameter reassignment) if (nextchar == NULL || *nextchar == '\0') { // Advance to the next ARGV-element. From 6e6b294a3f237b86e960f92ffe9fa15d7b57c1ee Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 20 Oct 2016 21:14:40 -0700 Subject: [PATCH 008/112] lint: deal with "double negative" warnings --- .oclint | 7 +++++++ src/builtin_test.cpp | 6 +++--- src/color.h | 4 ++-- src/common.cpp | 10 +++++----- src/complete.cpp | 6 ++++-- src/expand.cpp | 4 ++-- src/highlight.cpp | 2 +- src/output.cpp | 5 +++-- src/parse_tree.h | 4 +++- src/proc.cpp | 2 +- src/reader.cpp | 10 +++++----- src/tokenizer.cpp | 8 ++++---- src/wildcard.cpp | 2 +- src/wutil.cpp | 2 +- 14 files changed, 42 insertions(+), 30 deletions(-) diff --git a/.oclint b/.oclint index 86f1f7402..5eea63aea 100644 --- a/.oclint +++ b/.oclint @@ -51,3 +51,10 @@ disable-rules: # and is therefore just noise. Disable this rule. # - InvertedLogic + # + # The idea behind the "double negative" rule is sound since constructs + # like "!!(var & flag)" should be written as "static_cast(var & + # flag)". Unfortunately this rule has way too many false positives; + # especially in the context of assert statements. So disable this rule. + # + - DoubleNegative diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp index 334cbfb50..3c45be8a3 100644 --- a/src/builtin_test.cpp +++ b/src/builtin_test.cpp @@ -595,14 +595,14 @@ bool combining_expression::evaluate(wcstring_list_t &errors) { switch (token) { case test_combine_and: case test_combine_or: { + assert(!subjects.empty()); + assert(combiners.size() + 1 == subjects.size()); + // One-element case. if (subjects.size() == 1) return subjects.at(0)->evaluate(errors); // Evaluate our lists, remembering that AND has higher precedence than OR. We can // visualize this as a sequence of OR expressions of AND expressions. - assert(combiners.size() + 1 == subjects.size()); - assert(!subjects.empty()); - size_t idx = 0, max = subjects.size(); bool or_result = false; while (idx < max) { diff --git a/src/color.h b/src/color.h index fd756d0a2..05f1fa930 100644 --- a/src/color.h +++ b/src/color.h @@ -96,7 +96,7 @@ class rgb_color_t { color24_t to_color24() const; /// Returns whether the color is bold. - bool is_bold() const { return !!(flags & flag_bold); } + bool is_bold() const { return static_cast(flags & flag_bold); } /// Set whether the color is bold. void set_bold(bool x) { @@ -107,7 +107,7 @@ class rgb_color_t { } /// Returns whether the color is underlined. - bool is_underline() const { return !!(flags & flag_underline); } + bool is_underline() const { return static_cast(flags & flag_underline); } /// Set whether the color is underlined. void set_underline(bool x) { diff --git a/src/common.cpp b/src/common.cpp index 5c9d40e0a..ceea4ba84 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -768,9 +768,9 @@ static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstri assert(orig_in != NULL); const wchar_t *in = orig_in; - bool escape_all = !!(flags & ESCAPE_ALL); - bool no_quoted = !!(flags & ESCAPE_NO_QUOTED); - bool no_tilde = !!(flags & ESCAPE_NO_TILDE); + bool escape_all = static_cast(flags & ESCAPE_ALL); + bool no_quoted = static_cast(flags & ESCAPE_NO_QUOTED); + bool no_tilde = static_cast(flags & ESCAPE_NO_TILDE); int need_escape = 0; int need_complex_escape = 0; @@ -1117,8 +1117,8 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in wcstring result; result.reserve(input_len); - const bool unescape_special = !!(flags & UNESCAPE_SPECIAL); - const bool allow_incomplete = !!(flags & UNESCAPE_INCOMPLETE); + const bool unescape_special = static_cast(flags & UNESCAPE_SPECIAL); + const bool allow_incomplete = static_cast(flags & UNESCAPE_INCOMPLETE); int bracket_count = 0; diff --git a/src/complete.cpp b/src/complete.cpp index 9491c58b8..e4aac9939 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -289,9 +289,11 @@ class completer_t { return flags & COMPLETION_REQUEST_AUTOSUGGESTION ? COMPLETE_AUTOSUGGEST : COMPLETE_DEFAULT; } - bool wants_descriptions() const { return !!(flags & COMPLETION_REQUEST_DESCRIPTIONS); } + bool wants_descriptions() const { + return static_cast(flags & COMPLETION_REQUEST_DESCRIPTIONS); + } - bool fuzzy() const { return !!(flags & COMPLETION_REQUEST_FUZZY_MATCH); } + bool fuzzy() const { return static_cast(flags & COMPLETION_REQUEST_FUZZY_MATCH); } fuzzy_match_type_t max_fuzzy_match_type() const { // If we are doing fuzzy matching, request all types; if not request only prefix matching. diff --git a/src/expand.cpp b/src/expand.cpp index 1c2a92eb1..040216c16 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -1401,8 +1401,8 @@ static expand_error_t expand_stage_wildcards(const wcstring &input, std::vector< // which may be CDPATH if the special flag is set. const wcstring working_dir = env_get_pwd_slash(); wcstring_list_t effective_working_dirs; - bool for_cd = !!(flags & EXPAND_SPECIAL_FOR_CD); - bool for_command = !!(flags & EXPAND_SPECIAL_FOR_COMMAND); + bool for_cd = static_cast(flags & EXPAND_SPECIAL_FOR_CD); + bool for_command = static_cast(flags & EXPAND_SPECIAL_FOR_COMMAND); if (!for_cd && !for_command) { // Common case. effective_working_dirs.push_back(working_dir); diff --git a/src/highlight.cpp b/src/highlight.cpp index 21b75bce3..08ca3ada0 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -87,7 +87,7 @@ bool is_potential_path(const wcstring &potential_path_fragment, const wcstring_l path_flags_t flags) { ASSERT_IS_BACKGROUND_THREAD(); - const bool require_dir = !!(flags & PATH_REQUIRE_DIR); + const bool require_dir = static_cast(flags & PATH_REQUIRE_DIR); wcstring clean_potential_path_fragment; int has_magic = 0; bool result = false; diff --git a/src/output.cpp b/src/output.cpp index 9243730d4..6287b4329 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -115,7 +115,8 @@ static bool write_background_color(unsigned char idx) { // Exported for builtin_set_color's usage only. bool write_color(rgb_color_t color, bool is_fg) { - bool supports_term24bit = !!(output_get_color_support() & color_support_term24bit); + bool supports_term24bit = + static_cast(output_get_color_support() & color_support_term24bit); if (!supports_term24bit || !color.is_rgb()) { // Indexed or non-24 bit color. unsigned char idx = index_for_color(color); @@ -386,7 +387,7 @@ rgb_color_t best_color(const std::vector &candidates, color_support } // If we have both RGB and named colors, then prefer rgb if term256 is supported. rgb_color_t result = rgb_color_t::none(); - bool has_term256 = !!(support & color_support_term256); + bool has_term256 = static_cast(support & color_support_term256); if ((!first_rgb.is_none() && has_term256) || first_named.is_none()) { result = first_rgb; } else { diff --git a/src/parse_tree.h b/src/parse_tree.h index a5245aca6..0582fc947 100644 --- a/src/parse_tree.h +++ b/src/parse_tree.h @@ -118,7 +118,9 @@ class parse_node_t { } /// Indicate if the node has comment nodes. - bool has_comments() const { return !!(this->flags & parse_node_flag_has_comments); } + bool has_comments() const { + return static_cast(this->flags & parse_node_flag_has_comments); + } /// Gets source for the node, or the empty string if it has no source. wcstring get_source(const wcstring &str) const { diff --git a/src/proc.cpp b/src/proc.cpp index a5199c71b..d3e7b733d 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -247,7 +247,7 @@ void job_set_flag(job_t *j, unsigned int flag, int set) { } } -int job_get_flag(const job_t *j, unsigned int flag) { return !!(j->flags & flag); } +int job_get_flag(const job_t *j, unsigned int flag) { return static_cast(j->flags & flag); } int job_signal(job_t *j, int signal) { pid_t my_pid = getpid(); diff --git a/src/reader.cpp b/src/reader.cpp index 947cd09bc..2b6b82ccb 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1027,9 +1027,9 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag const wcstring &command_line, size_t *inout_cursor_pos, bool append_only) { const wchar_t *val = val_str.c_str(); - bool add_space = !(flags & COMPLETE_NO_SPACE); - bool do_replace = !!(flags & COMPLETE_REPLACES_TOKEN); - bool do_escape = !(flags & COMPLETE_DONT_ESCAPE); + bool add_space = !static_cast(flags & COMPLETE_NO_SPACE); + bool do_replace = static_cast(flags & COMPLETE_REPLACES_TOKEN); + bool do_escape = !static_cast(flags & COMPLETE_DONT_ESCAPE); const size_t cursor_pos = *inout_cursor_pos; bool back_into_trailing_quote = false; @@ -1046,7 +1046,7 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag if (do_escape) { // Respect COMPLETE_DONT_ESCAPE_TILDES. - bool no_tilde = !!(flags & COMPLETE_DONT_ESCAPE_TILDES); + bool no_tilde = static_cast(flags & COMPLETE_DONT_ESCAPE_TILDES); wcstring escaped = escape(val, ESCAPE_ALL | ESCAPE_NO_QUOTED | (no_tilde ? ESCAPE_NO_TILDE : 0)); sb.append(escaped); @@ -1426,7 +1426,7 @@ static bool handle_completions(const std::vector &comp, if (el.match.type > best_match_type) continue; // Only use completions that match replace_token. - bool completion_replace_token = !!(el.flags & COMPLETE_REPLACES_TOKEN); + bool completion_replace_token = static_cast(el.flags & COMPLETE_REPLACES_TOKEN); if (completion_replace_token != will_replace_token) continue; // Don't use completions that want to replace, if we cannot replace them. diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index cc19615c3..61ea9e349 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -64,10 +64,10 @@ tokenizer_t::tokenizer_t(const wchar_t *b, tok_flags_t flags) continue_line_after_comment(false) { assert(b != NULL); - this->accept_unfinished = !!(flags & TOK_ACCEPT_UNFINISHED); - this->show_comments = !!(flags & TOK_SHOW_COMMENTS); - this->squash_errors = !!(flags & TOK_SQUASH_ERRORS); - this->show_blank_lines = !!(flags & TOK_SHOW_BLANK_LINES); + this->accept_unfinished = static_cast(flags & TOK_ACCEPT_UNFINISHED); + this->show_comments = static_cast(flags & TOK_SHOW_COMMENTS); + this->squash_errors = static_cast(flags & TOK_SQUASH_ERRORS); + this->show_blank_lines = static_cast(flags & TOK_SHOW_BLANK_LINES); this->has_next = (*b != L'\0'); this->tok_next(); diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 5d57ead80..50468c706 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -502,7 +502,7 @@ class wildcard_expander_t { void add_expansion_result(const wcstring &result) { // This function is only for the non-completions case. - assert(!(this->flags & EXPAND_FOR_COMPLETIONS)); + assert(!static_cast(this->flags & EXPAND_FOR_COMPLETIONS)); if (this->completion_set.insert(result).second) { append_completion(this->resolved_completions, result); this->did_add = true; diff --git a/src/wutil.cpp b/src/wutil.cpp index 608caf7f8..b8897de3b 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -79,7 +79,7 @@ bool wreaddir_resolving(DIR *dir, const std::wstring &dir_path, std::wstring &ou if (stat(fullpath.c_str(), &buf) != 0) { is_dir = false; } else { - is_dir = !!(S_ISDIR(buf.st_mode)); + is_dir = static_cast(S_ISDIR(buf.st_mode)); } } *out_is_dir = is_dir; From c7e26e494e90406f02937914dbb477fbfe6443b9 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 22 Oct 2016 10:47:46 -0700 Subject: [PATCH 009/112] Fix Terminal.app title Defining fish_title here is too late because there will already be a title set. Work around issue by clearing it at same time. --- share/functions/__fish_config_interactive.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 691593379..4f57c95c6 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -220,6 +220,7 @@ function __fish_config_interactive -d "Initializations that should be performed # Notify terminals when $PWD changes (issue #906) # VTE and Terminal.app support this in practice. if test "0$VTE_VERSION" -ge 3405 -o "$TERM_PROGRAM" = "Apple_Terminal" + echo -n \e\]0\;\a # clear existing title function fish_title; end function __update_cwd_osc --on-variable PWD --description 'Notify capable terminals when $PWD changes' status --is-command-substitution From e16f6ca2aa15c2638ffd57e2eda9c3ad41319e2b Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Fri, 21 Oct 2016 13:56:45 +0200 Subject: [PATCH 010/112] add listFilesystems to diskutil completion --- share/completions/diskutil.fish | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/completions/diskutil.fish b/share/completions/diskutil.fish index 89e1c61e7..86315ade9 100644 --- a/share/completions/diskutil.fish +++ b/share/completions/diskutil.fish @@ -1,4 +1,4 @@ -#completion for diskutil +# completion for diskutil (macOS) function __fish_diskutil_devices set -l mountpoints /dev/disk*; printf '%s\n' $mountpoints @@ -22,6 +22,10 @@ complete -f -c diskutil -n '__fish_seen_subcommand_from info' -o 'all' -d 'Proce # activity complete -f -c diskutil -n '__fish_use_subcommand' -a activity -d 'Continuously display system-wide disk manipulation activity' +# listFilesystems +complete -f -c diskutil -n '__fish_use_subcommand' -a listFilesystems -d 'Show the file system personalities available' +complete -f -c diskutil -n '__fish_seen_subcommand_from listFilesystems' -o 'plist' -d 'Return a property list' + # umount complete -f -c diskutil -n '__fish_use_subcommand' -a umount -d 'Unmount a single volume' complete -f -c diskutil -n '__fish_seen_subcommand_from umount' -a '(__fish_diskutil_mounted_volumes)' From 7878dbc4f05c3b602567d6cf0cc0e6af48ed51b5 Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Fri, 21 Oct 2016 13:57:13 +0200 Subject: [PATCH 011/112] add defaults (macOS) completion --- share/completions/defaults.fish | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 share/completions/defaults.fish diff --git a/share/completions/defaults.fish b/share/completions/defaults.fish new file mode 100644 index 000000000..6df6e6dd4 --- /dev/null +++ b/share/completions/defaults.fish @@ -0,0 +1,33 @@ +# completion for defaults (macOS) + +function __fish_defaults_domains + defaults domains | string split ", " +end + +complete -f -c defaults -o 'currentHost' -d 'Restricts preferences operations to the host the user is currently logged in on' +complete -f -c defaults -o 'host' -d 'Restricts preferences operations to hostname' + +# read +complete -f -c defaults -n '__fish_use_subcommand' -a read -d 'Shows defaults for all or the given domain' +complete -f -c defaults -n '__fish_seen_subcommand_from read read-type write rename delete' -a '(__fish_defaults_domains)' +complete -f -c defaults -n '__fish_seen_subcommand_from read read-type write rename delete' -o 'app' + +# write +complete -f -c defaults -n '__fish_use_subcommand' -a write -d 'Writes domain or or a key in the domain' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'string' -d 'String as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'data' -d 'Abunch of raw data bytes as the value for the given prefer ence key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'int' -d 'Integer as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'float' -d 'Floating point number as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'bool' -d 'Boolean as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'date' -d 'Date as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array' -d 'Array as the value for the given preference key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array-add' -d 'Allows to add new elements to the end of an array' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict' -d 'Dictionary to the defaults database for a domain' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict-add' -d 'Allows to add new key/value pairs to a dictionary' + +complete -f -c defaults -n '__fish_use_subcommand' -a read-type -d 'Shows the type for the given domain, key' +complete -f -c defaults -n '__fish_use_subcommand' -a rename -d 'Renames old_key to new_key' +complete -f -c defaults -n '__fish_use_subcommand' -a delete -d 'Deletes domain or a key in the domain' +complete -f -c defaults -n '__fish_use_subcommand' -a domains -d 'Prints the names of all domains in the users defaults system' +complete -f -c defaults -n '__fish_use_subcommand' -a find -d 'Searches for word in the domain names, keys, and values of the users defaults' +complete -f -c defaults -n '__fish_use_subcommand' -a help -d 'Prints a list of possible command formats' From cbe2d4b5f120802788bc839b2fa57b9b91293447 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 22 Oct 2016 12:34:15 -0700 Subject: [PATCH 012/112] defaults completions: shorten and improve brevity At 80 columns the description obscured 'find' in 'default find'. Improve others. --- share/completions/defaults.fish | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/share/completions/defaults.fish b/share/completions/defaults.fish index 6df6e6dd4..408bfe688 100644 --- a/share/completions/defaults.fish +++ b/share/completions/defaults.fish @@ -4,30 +4,30 @@ function __fish_defaults_domains defaults domains | string split ", " end -complete -f -c defaults -o 'currentHost' -d 'Restricts preferences operations to the host the user is currently logged in on' +complete -f -c defaults -o 'currentHost' -d 'Restricts preferences operations to the current logged-in host' complete -f -c defaults -o 'host' -d 'Restricts preferences operations to hostname' # read -complete -f -c defaults -n '__fish_use_subcommand' -a read -d 'Shows defaults for all or the given domain' +complete -f -c defaults -n '__fish_use_subcommand' -a read -d 'Shows defaults entire given domain' complete -f -c defaults -n '__fish_seen_subcommand_from read read-type write rename delete' -a '(__fish_defaults_domains)' complete -f -c defaults -n '__fish_seen_subcommand_from read read-type write rename delete' -o 'app' # write complete -f -c defaults -n '__fish_use_subcommand' -a write -d 'Writes domain or or a key in the domain' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'string' -d 'String as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'data' -d 'Abunch of raw data bytes as the value for the given prefer ence key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'int' -d 'Integer as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'float' -d 'Floating point number as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'bool' -d 'Boolean as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'date' -d 'Date as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array' -d 'Array as the value for the given preference key' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array-add' -d 'Allows to add new elements to the end of an array' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict' -d 'Dictionary to the defaults database for a domain' -complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict-add' -d 'Allows to add new key/value pairs to a dictionary' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'string' -d 'String as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'data' -d 'Raw data bytes for given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'int' -d 'Integer as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'float' -d 'Floating point number as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'bool' -d 'Boolean as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'date' -d 'Date as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array' -d 'Array as the value for the given key' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'array-add' -d 'Add new elements to the end of an array' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict' -d 'Add a dictionary to domain' +complete -f -c defaults -n '__fish_seen_subcommand_from write' -o 'dict-add' -d 'Add new key/value pairs to a dictionary' complete -f -c defaults -n '__fish_use_subcommand' -a read-type -d 'Shows the type for the given domain, key' complete -f -c defaults -n '__fish_use_subcommand' -a rename -d 'Renames old_key to new_key' complete -f -c defaults -n '__fish_use_subcommand' -a delete -d 'Deletes domain or a key in the domain' complete -f -c defaults -n '__fish_use_subcommand' -a domains -d 'Prints the names of all domains in the users defaults system' -complete -f -c defaults -n '__fish_use_subcommand' -a find -d 'Searches for word in the domain names, keys, and values of the users defaults' +complete -f -c defaults -n '__fish_use_subcommand' -a find -d 'Searches for word in domain names, keys, and values' complete -f -c defaults -n '__fish_use_subcommand' -a help -d 'Prints a list of possible command formats' From 100a0ea549ba6909328d2eccf98d2524c3fd6e18 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 18:23:03 -0700 Subject: [PATCH 013/112] Revert "Fix lexicon_filter verbosity" This reverts commit dcb39af8c0860abea04bce9d5fa502fd7ba9e2b6. It breaks building the documentation because splitting the sed invocation in the `lexicon_filter` target from the preceding `if` block means the `WORDBL` and `WORDBR` shell vars aren't available. --- Makefile.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile.in b/Makefile.in index 243d8fde4..30f2f3372 100644 --- a/Makefile.in +++ b/Makefile.in @@ -453,9 +453,8 @@ lexicon_filter: lexicon.txt lexicon_filter.in | show-SED WORDBL='[[:<:]]'; WORDBR='[[:>:]]'; \ else \ WORDBL='\\<'; WORDBR='\\>'; \ - fi - $v $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p' - $v mv $@.tmp $@; test -x $@ || chmod a+x $@; + fi; $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p'; + mv $@.tmp $@; test -x $@ || chmod a+x $@; # From a8c9019a39fcd0cac5890ca9cacb23dcbf5873e3 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 22 Oct 2016 18:37:11 -0700 Subject: [PATCH 014/112] Re-fix 'fix lexicon_filter verbosity' --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 30f2f3372..09cfac2e8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -454,7 +454,7 @@ lexicon_filter: lexicon.txt lexicon_filter.in | show-SED else \ WORDBL='\\<'; WORDBR='\\>'; \ fi; $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p'; - mv $@.tmp $@; test -x $@ || chmod a+x $@; + $v mv $@.tmp $@; test -x $@ || chmod a+x $@; # From 42458ff7ab358475488db7c51fbff121f522d78a Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 11:21:13 -0700 Subject: [PATCH 015/112] lint: "collapsible if statements" warnings --- src/builtin.cpp | 9 +-- src/builtin_complete.cpp | 52 ++++++------- src/builtin_set_color.cpp | 22 +++--- src/common.cpp | 18 ++--- src/complete.cpp | 48 ++++++------ src/env.cpp | 6 +- src/env_universal_common.cpp | 42 +++++----- src/exec.cpp | 69 ++++++++--------- src/expand.cpp | 56 ++++++-------- src/function.cpp | 4 +- src/highlight.cpp | 62 ++++++--------- src/output.cpp | 8 +- src/parse_execution.cpp | 10 +-- src/parse_productions.cpp | 8 +- src/parse_tree.cpp | 12 ++- src/parse_util.cpp | 49 +++++------- src/postfork.cpp | 27 +++---- src/print_help.cpp | 6 +- src/proc.cpp | 143 ++++++++++++++++------------------- src/reader.cpp | 91 ++++++++++------------ src/util.cpp | 10 +-- src/wildcard.cpp | 43 +++++------ 22 files changed, 349 insertions(+), 446 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 5b5fa6683..8e0f027be 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -3284,11 +3284,10 @@ int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &stre cmd = (int (*)(parser_t & parser, io_streams_t & streams, const wchar_t *const *))( data ? data->func : NULL); - if (argv[1] != NULL && !builtin_handles_help(argv[0])) { - if (argv[2] == NULL && (parse_util_argument_is_help(argv[1], 0))) { - builtin_print_help(parser, streams, argv[0], streams.out); - return STATUS_BUILTIN_OK; - } + if (argv[1] != NULL && !builtin_handles_help(argv[0]) && argv[2] == NULL && + parse_util_argument_is_help(argv[1], 0)) { + builtin_print_help(parser, streams, argv[0], streams.out); + return STATUS_BUILTIN_OK; } if (data != NULL) { diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp index 9dd180106..ec14f8ffe 100644 --- a/src/builtin_complete.cpp +++ b/src/builtin_complete.cpp @@ -286,39 +286,35 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } - if (!res) { - if (condition && wcslen(condition)) { - const wcstring condition_string = condition; - parse_error_list_t errors; - if (parse_util_detect_errors(condition_string, &errors, - false /* do not accept incomplete */)) { - streams.err.append_format(L"%ls: Condition '%ls' contained a syntax error", argv[0], - condition); - for (size_t i = 0; i < errors.size(); i++) { - streams.err.append_format(L"\n%s: ", argv[0]); - streams.err.append(errors.at(i).describe(condition_string)); - } - res = true; + if (!res && condition && wcslen(condition)) { + const wcstring condition_string = condition; + parse_error_list_t errors; + if (parse_util_detect_errors(condition_string, &errors, + false /* do not accept incomplete */)) { + streams.err.append_format(L"%ls: Condition '%ls' contained a syntax error", argv[0], + condition); + for (size_t i = 0; i < errors.size(); i++) { + streams.err.append_format(L"\n%s: ", argv[0]); + streams.err.append(errors.at(i).describe(condition_string)); } + res = true; } } - if (!res) { - if (comp && wcslen(comp)) { - wcstring prefix; - if (argv[0]) { - prefix.append(argv[0]); - prefix.append(L": "); - } + if (!res && comp && wcslen(comp)) { + wcstring prefix; + if (argv[0]) { + prefix.append(argv[0]); + prefix.append(L": "); + } - wcstring err_text; - if (parser.detect_errors_in_argument_list(comp, &err_text, prefix.c_str())) { - streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n", - argv[0], comp); - streams.err.append(err_text); - streams.err.push_back(L'\n'); - res = true; - } + wcstring err_text; + if (parser.detect_errors_in_argument_list(comp, &err_text, prefix.c_str())) { + streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n", argv[0], + comp); + streams.err.append(err_text); + streams.err.push_back(L'\n'); + res = true; } } diff --git a/src/builtin_set_color.cpp b/src/builtin_set_color.cpp index a99882c2c..b12c39229 100644 --- a/src/builtin_set_color.cpp +++ b/src/builtin_set_color.cpp @@ -159,19 +159,17 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) { builtin_set_color_output.clear(); output_set_writer(set_color_builtin_outputter); - if (bold) { - if (enter_bold_mode) writembs(tparm(enter_bold_mode)); + if (bold && enter_bold_mode) { + writembs(tparm(enter_bold_mode)); } - if (underline) { - if (enter_underline_mode) writembs(enter_underline_mode); + if (underline && enter_underline_mode) { + writembs(enter_underline_mode); } - if (bgcolor != NULL) { - if (bg.is_normal()) { - write_color(rgb_color_t::black(), false /* not is_fg */); - writembs(tparm(exit_attribute_mode)); - } + if (bgcolor != NULL && bg.is_normal()) { + write_color(rgb_color_t::black(), false /* not is_fg */); + writembs(tparm(exit_attribute_mode)); } if (!fg.is_none()) { @@ -188,10 +186,8 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } - if (bgcolor != NULL) { - if (!bg.is_normal() && !bg.is_reset()) { - write_color(bg, false /* not is_fg */); - } + if (bgcolor != NULL && !bg.is_normal() && !bg.is_reset()) { + write_color(bg, false /* not is_fg */); } // Restore saved writer function. diff --git a/src/common.cpp b/src/common.cpp index ceea4ba84..9740b0ce2 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1505,7 +1505,7 @@ bool list_contains_string(const wcstring_list_t &list, const wcstring &str) { } int create_directory(const wcstring &d) { - int ok = 0; + bool ok = false; struct stat buf; int stat_res = 0; @@ -1514,18 +1514,10 @@ int create_directory(const wcstring &d) { } if (stat_res == 0) { - if (S_ISDIR(buf.st_mode)) { - ok = 1; - } - } else { - if (errno == ENOENT) { - wcstring dir = wdirname(d); - if (!create_directory(dir)) { - if (!wmkdir(d, 0700)) { - ok = 1; - } - } - } + if (S_ISDIR(buf.st_mode)) ok = true; + } else if (errno == ENOENT) { + wcstring dir = wdirname(d); + if (!create_directory(dir) && !wmkdir(d, 0700)) ok = true; } return ok ? 0 : -1; diff --git a/src/complete.cpp b/src/complete.cpp index e4aac9939..b580ece60 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -670,22 +670,22 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool std::vector possible_comp; if (use_command) { - if (expand_string(str_cmd, &this->completions, - EXPAND_SPECIAL_FOR_COMMAND | EXPAND_FOR_COMPLETIONS | EXECUTABLES_ONLY | - this->expand_flags(), - NULL) != EXPAND_ERROR) { - if (this->wants_descriptions()) { - this->complete_cmd_desc(str_cmd); + expand_error_t result = expand_string(str_cmd, &this->completions, + EXPAND_SPECIAL_FOR_COMMAND | EXPAND_FOR_COMPLETIONS | + EXECUTABLES_ONLY | this->expand_flags(), + NULL); + if (result != EXPAND_ERROR && this->wants_descriptions()) { + this->complete_cmd_desc(str_cmd); } - } } - if (use_implicit_cd) { - if (!expand_string(str_cmd, &this->completions, - EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), - NULL)) { - // Not valid as implicit cd. - } + + // WTF? This seems to be a noop. + if (use_implicit_cd && + !expand_string(str_cmd, &this->completions, + EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), NULL)) { + // Not valid as implicit cd. } + if (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~') { if (use_function) { wcstring_list_t names = function_get_names(str_cmd.at(0) == L'_'); @@ -877,11 +877,10 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop if (this->type() == COMPLETE_DEFAULT) { ASSERT_IS_MAIN_THREAD(); complete_load(cmd, true); - } else if (this->type() == COMPLETE_AUTOSUGGEST) { - // Maybe load this command (on the main thread). - if (!completion_autoloader.has_tried_loading(cmd)) { - iothread_perform_on_main(complete_load_no_reload, &cmd); - } + } else if (this->type() == COMPLETE_AUTOSUGGEST && + !completion_autoloader.has_tried_loading(cmd)) { + // Load this command (on the main thread). + iothread_perform_on_main(complete_load_no_reload, &cmd); } // Make a list of lists of all options that we care about. @@ -927,13 +926,12 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop for (option_list_t::const_iterator oiter = options.begin(); oiter != options.end(); ++oiter) { const complete_entry_opt_t *o = &*oiter; - if (o->type == option_type_single_long) { - if (param_match(o, popt) && this->condition_test(o->condition)) { - old_style_match = true; - if (o->result_mode & NO_COMMON) use_common = false; - if (o->result_mode & NO_FILES) use_files = false; - complete_from_args(str, o->comp, o->localized_desc(), o->flags); - } + if (o->type == option_type_single_long && param_match(o, popt) && + this->condition_test(o->condition)) { + old_style_match = true; + if (o->result_mode & NO_COMMON) use_common = false; + if (o->result_mode & NO_FILES) use_files = false; + complete_from_args(str, o->comp, o->localized_desc(), o->flags); } } diff --git a/src/env.cpp b/src/env.cpp index b708298b8..8c588c7b8 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -865,9 +865,7 @@ void env_push(bool new_scope) { node->next = top; node->new_scope = new_scope; - if (new_scope) { - if (local_scope_exports(top)) mark_changed_exported(); - } + if (new_scope && local_scope_exports(top)) mark_changed_exported(); top = node; } @@ -885,7 +883,7 @@ void env_pop() { } } - if (killme->new_scope) { + if (killme->new_scope) { //!OCLINT(collapsible if statements) if (killme->exportv || local_scope_exports(killme->next)) mark_changed_exported(); } diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 2bb11c521..24ba53686 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -932,17 +932,16 @@ static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN], if (getifaddrs(&ifap) == 0) { for (const ifaddrs *p = ifap; p; p = p->ifa_next) { - if (p->ifa_addr && p->ifa_addr->sa_family == AF_LINK) { - if (p->ifa_name && p->ifa_name[0] && - !strcmp((const char *)p->ifa_name, interface)) { - const sockaddr_dl &sdl = *reinterpret_cast(p->ifa_addr); + bool is_af_link = p->ifa_addr && p->ifa_addr->sa_family == AF_LINK; + if (is_af_link && p->ifa_name && p->ifa_name[0] && + !strcmp((const char *)p->ifa_name, interface)) { + const sockaddr_dl &sdl = *reinterpret_cast(p->ifa_addr); - size_t alen = sdl.sdl_alen; - if (alen > MAC_ADDRESS_MAX_LEN) alen = MAC_ADDRESS_MAX_LEN; - memcpy(macaddr, sdl.sdl_data + sdl.sdl_nlen, alen); - ok = true; - break; - } + size_t alen = sdl.sdl_alen; + if (alen > MAC_ADDRESS_MAX_LEN) alen = MAC_ADDRESS_MAX_LEN; + memcpy(macaddr, sdl.sdl_data + sdl.sdl_nlen, alen); + ok = true; + break; } } freeifaddrs(ifap); @@ -1033,12 +1032,11 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t { } // Set the size, if it's too small. - if (!errored && size < (off_t)sizeof(universal_notifier_shmem_t)) { - if (ftruncate(fd, sizeof(universal_notifier_shmem_t)) < 0) { - int err = errno; - report_error(err, L"Unable to truncate shared memory object with path '%s'", path); - errored = true; - } + bool set_size = !errored && size < (off_t)sizeof(universal_notifier_shmem_t); + if (set_size && ftruncate(fd, sizeof(universal_notifier_shmem_t)) < 0) { + int err = errno; + report_error(err, L"Unable to truncate shared memory object with path '%s'", path); + errored = true; } // Memory map the region. @@ -1237,10 +1235,12 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { int fd = wopen_cloexec(vars_path, O_RDWR | O_NONBLOCK, 0600); if (fd < 0 && errno == ENOENT) { // File doesn't exist, try creating it. - if (mkfifo(narrow_path.c_str(), 0600) >= 0) { + int mkfifo_status = mkfifo(narrow_path.c_str(), 0600); + if (mkfifo_status != -1) { fd = wopen_cloexec(vars_path, O_RDWR | O_NONBLOCK, 0600); } } + if (fd < 0) { // Maybe open failed, maybe mkfifo failed. int err = errno; @@ -1316,11 +1316,9 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { // it back. Nobody is expected to read it except us. int pid_nbo = htonl(getpid()); ssize_t amt_written = write(this->pipe_fd, &pid_nbo, sizeof pid_nbo); - if (amt_written < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { - // Very unsual: the pipe is full! - drain_excessive_data(); - } + if (amt_written < 0 && errno == EWOULDBLOCK || errno == EAGAIN) { + // Very unsual: the pipe is full! + drain_excessive_data(); } // Now schedule a read for some time in the future. diff --git a/src/exec.cpp b/src/exec.cpp index 777f8e354..b37d4f835 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -353,7 +353,7 @@ static void internal_exec_helper(parser_t &parser, const wcstring &def, node_off // foreground process group, we don't use posix_spawn if we're going to foreground the process. (If // we use fork(), we can call tcsetpgrp after the fork, before the exec, and avoid the race). static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *process) { - if (job_get_flag(job, JOB_CONTROL)) { + if (job_get_flag(job, JOB_CONTROL)) { //!OCLINT(collapsible if statements) // We are going to use job control; therefore when we launch this job it will get its own // process group ID. But will it be foregrounded? if (job_get_flag(job, JOB_TERMINAL) && job_get_flag(job, JOB_FOREGROUND)) { @@ -913,45 +913,42 @@ void exec_job(parser_t &parser, job_t *j) { // output, so that we can truncate the file. Does not apply to /dev/null. bool must_fork = redirection_is_to_real_file(stdout_io.get()) || redirection_is_to_real_file(stderr_io.get()); - if (!must_fork) { - if (p->next == NULL) { - const bool stdout_is_to_buffer = - stdout_io && stdout_io->io_mode == IO_BUFFER; - const bool no_stdout_output = stdout_buffer.empty(); - const bool no_stderr_output = stderr_buffer.empty(); + if (!must_fork && p->next == NULL) { + const bool stdout_is_to_buffer = stdout_io && stdout_io->io_mode == IO_BUFFER; + const bool no_stdout_output = stdout_buffer.empty(); + const bool no_stderr_output = stderr_buffer.empty(); - if (no_stdout_output && no_stderr_output) { - // The builtin produced no output and is not inside of a pipeline. No - // need to fork or even output anything. - debug(3, L"Skipping fork: no output for internal builtin '%ls'", - p->argv0()); - fork_was_skipped = true; - } else if (no_stderr_output && stdout_is_to_buffer) { - // The builtin produced no stderr, and its stdout is going to an - // internal buffer. There is no need to fork. This helps out the - // performance quite a bit in complex completion code. - debug(3, L"Skipping fork: buffered output for internal builtin '%ls'", - p->argv0()); + if (no_stdout_output && no_stderr_output) { + // The builtin produced no output and is not inside of a pipeline. No + // need to fork or even output anything. + debug(3, L"Skipping fork: no output for internal builtin '%ls'", + p->argv0()); + fork_was_skipped = true; + } else if (no_stderr_output && stdout_is_to_buffer) { + // The builtin produced no stderr, and its stdout is going to an + // internal buffer. There is no need to fork. This helps out the + // performance quite a bit in complex completion code. + debug(3, L"Skipping fork: buffered output for internal builtin '%ls'", + p->argv0()); - io_buffer_t *io_buffer = static_cast(stdout_io.get()); - const std::string res = wcs2string(builtin_io_streams->out.buffer()); + io_buffer_t *io_buffer = static_cast(stdout_io.get()); + const std::string res = wcs2string(builtin_io_streams->out.buffer()); - io_buffer->out_buffer_append(res.data(), res.size()); - fork_was_skipped = true; - } else if (stdout_io.get() == NULL && stderr_io.get() == NULL) { - // We are writing to normal stdout and stderr. Just do it - no need to - // fork. - debug(3, L"Skipping fork: ordinary output for internal builtin '%ls'", - p->argv0()); - const std::string outbuff = wcs2string(stdout_buffer); - const std::string errbuff = wcs2string(stderr_buffer); - bool builtin_io_done = do_builtin_io(outbuff.data(), outbuff.size(), - errbuff.data(), errbuff.size()); - if (!builtin_io_done && errno != EPIPE) { - show_stackframe(L'E'); - } - fork_was_skipped = true; + io_buffer->out_buffer_append(res.data(), res.size()); + fork_was_skipped = true; + } else if (stdout_io.get() == NULL && stderr_io.get() == NULL) { + // We are writing to normal stdout and stderr. Just do it - no need to + // fork. + debug(3, L"Skipping fork: ordinary output for internal builtin '%ls'", + p->argv0()); + const std::string outbuff = wcs2string(stdout_buffer); + const std::string errbuff = wcs2string(stderr_buffer); + bool builtin_io_done = do_builtin_io(outbuff.data(), outbuff.size(), + errbuff.data(), errbuff.size()); + if (!builtin_io_done && errno != EPIPE) { + show_stackframe(L'E'); } + fork_was_skipped = true; } } diff --git a/src/expand.cpp b/src/expand.cpp index 040216c16..200ed98d4 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -225,10 +225,8 @@ static bool match_pid(const wcstring &cmd, const wchar_t *proc, size_t *offset) const wcstring base_cmd = wbasename(cmd); bool result = string_prefixes_string(proc, base_cmd); - if (result) { - // It's a match. Return the offset within the full command. - if (offset) *offset = cmd.size() - base_cmd.size(); - } + // It's a match. Return the offset within the full command. + if (result && offset) *offset = cmd.size() - base_cmd.size(); return result; } @@ -632,13 +630,11 @@ static bool expand_pid(const wcstring &instr_with_sep, expand_flags_t flags, const size_t prev_count = out->size(); find_process(in + 1, flags, out); - if (prev_count == out->size()) { - if (!(flags & EXPAND_FOR_COMPLETIONS)) { - // We failed to find anything. - append_syntax_error(errors, 1, FAILED_EXPANSION_PROCESS_ERR_MSG, - escape(in + 1, ESCAPE_NO_QUOTED).c_str()); - return false; - } + if (prev_count == out->size() && !(flags & EXPAND_FOR_COMPLETIONS)) { + // We failed to find anything. + append_syntax_error(errors, 1, FAILED_EXPANSION_PROCESS_ERR_MSG, + escape(in + 1, ESCAPE_NO_QUOTED).c_str()); + return false; } return true; @@ -1025,21 +1021,19 @@ static expand_error_t expand_brackets(const wcstring &instr, expand_flags_t flag tot_len = length_preceding_brackets + length_following_brackets; item_begin = bracket_begin + 1; for (const wchar_t *pos = (bracket_begin + 1); true; pos++) { - if (bracket_count == 0) { - if ((*pos == BRACKET_SEP) || (pos == bracket_end)) { - assert(pos >= item_begin); - size_t item_len = pos - item_begin; + if (bracket_count == 0 && ((*pos == BRACKET_SEP) || (pos == bracket_end))) { + assert(pos >= item_begin); + size_t item_len = pos - item_begin; - wcstring whole_item; - whole_item.reserve(tot_len + item_len + 2); - whole_item.append(in, length_preceding_brackets); - whole_item.append(item_begin, item_len); - whole_item.append(bracket_end + 1); - expand_brackets(whole_item, flags, out, errors); + wcstring whole_item; + whole_item.reserve(tot_len + item_len + 2); + whole_item.append(in, length_preceding_brackets); + whole_item.append(item_begin, item_len); + whole_item.append(bracket_end + 1); + expand_brackets(whole_item, flags, out, errors); - item_begin = pos + 1; - if (pos == bracket_end) break; - } + item_begin = pos + 1; + if (pos == bracket_end) break; } if (*pos == BRACKET_BEGIN) { @@ -1517,19 +1511,17 @@ expand_error_t expand_string(const wcstring &input, std::vector *o bool expand_one(wcstring &string, expand_flags_t flags, parse_error_list_t *errors) { std::vector completions; - bool result = false; - if ((!(flags & EXPAND_FOR_COMPLETIONS)) && expand_is_clean(string)) { + if (!(flags & EXPAND_FOR_COMPLETIONS) && expand_is_clean(string)) { return true; } - if (expand_string(string, &completions, flags | EXPAND_NO_DESCRIPTIONS, errors)) { - if (completions.size() == 1) { - string = completions.at(0).completion; - result = true; - } + if (expand_string(string, &completions, flags | EXPAND_NO_DESCRIPTIONS, errors) && + completions.size() == 1) { + string = completions.at(0).completion; + return true; } - return result; + return false; } // https://github.com/fish-shell/fish-shell/issues/367 diff --git a/src/function.cpp b/src/function.cpp index 34dbd85cd..6ca086aba 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -311,8 +311,8 @@ wcstring_list_t function_get_names(int get_hidden) { const wcstring &name = iter->first; // Maybe skip hidden. - if (!get_hidden) { - if (name.empty() || name.at(0) == L'_') continue; + if (!get_hidden && (name.empty() || name.at(0) == L'_')) { + continue; } names.insert(name); } diff --git a/src/highlight.cpp b/src/highlight.cpp index 08ca3ada0..1f1dcac52 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -224,19 +224,16 @@ static bool is_potential_cd_path(const wcstring &path, const wcstring &working_d bool plain_statement_get_expanded_command(const wcstring &src, const parse_node_tree_t &tree, const parse_node_t &plain_statement, wcstring *out_cmd) { assert(plain_statement.type == symbol_plain_statement); - bool result = false; - // Get the command. + // Get the command. Try expanding it. If we cannot, it's an error. wcstring cmd; - if (tree.command_for_plain_statement(plain_statement, src, &cmd)) { - // Try expanding it. If we cannot, it's an error. - if (expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS)) { - // Success, return the expanded string by reference. - out_cmd->swap(cmd); - result = true; - } + if (tree.command_for_plain_statement(plain_statement, src, &cmd) && + expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS)) { + // Success, return the expanded string by reference. + out_cmd->swap(cmd); + return true; } - return result; + return false; } rgb_color_t highlight_get_color(highlight_spec_t highlight, bool is_background) { @@ -297,8 +294,6 @@ static bool has_expand_reserved(const wcstring &str) { // (as a copied node), if any. This is used by autosuggestions. static bool autosuggest_parse_command(const wcstring &buff, wcstring *out_expanded_command, parse_node_t *out_last_arg) { - bool result = false; - // Parse the buffer. parse_node_tree_t parse_tree; parse_tree_from_string(buff, @@ -308,21 +303,17 @@ static bool autosuggest_parse_command(const wcstring &buff, wcstring *out_expand // Find the last statement. const parse_node_t *last_statement = parse_tree.find_last_node_of_type(symbol_plain_statement, NULL); - if (last_statement != NULL) { - if (plain_statement_get_expanded_command(buff, parse_tree, *last_statement, - out_expanded_command)) { - // We got it. - result = true; - - // Find the last argument. If we don't get one, return an invalid node. - const parse_node_t *last_arg = - parse_tree.find_last_node_of_type(symbol_argument, last_statement); - if (last_arg != NULL) { - *out_last_arg = *last_arg; - } + if (last_statement != NULL && plain_statement_get_expanded_command( + buff, parse_tree, *last_statement, out_expanded_command)) { + // Find the last argument. If we don't get one, return an invalid node. + const parse_node_t *last_arg = + parse_tree.find_last_node_of_type(symbol_argument, last_statement); + if (last_arg != NULL) { + *out_last_arg = *last_arg; } + return true; } - return result; + return false; } bool autosuggest_validate_from_history(const history_item_t &item, @@ -1163,18 +1154,15 @@ const highlighter_t::color_array_t &highlighter_t::highlight() { // backspacing (and the cursor is just beyond the last token), we may still underline // it. if (this->cursor_pos >= node.source_start && - this->cursor_pos - node.source_start <= node.source_length) { - // See if this is a valid path. - if (node_is_potential_path(buff, node, working_directory)) { - // It is, underline it. - for (size_t i = node.source_start; i < node.source_start + node.source_length; - i++) { - // Don't color highlight_spec_error because it looks dorky. For example, - // trying to cd into a non-directory would show an underline and also red. - if (highlight_get_primary(this->color_array.at(i)) != - highlight_spec_error) { - this->color_array.at(i) |= highlight_modifier_valid_path; - } + this->cursor_pos - node.source_start <= node.source_length && + node_is_potential_path(buff, node, working_directory)) { + // It is, underline it. + for (size_t i = node.source_start; i < node.source_start + node.source_length; + i++) { + // Don't color highlight_spec_error because it looks dorky. For example, + // trying to cd into a non-directory would show an underline and also red. + if (highlight_get_primary(this->color_array.at(i)) != highlight_spec_error) { + this->color_array.at(i) |= highlight_modifier_valid_path; } } } diff --git a/src/output.cpp b/src/output.cpp index 6287b4329..03c1f9fa5 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -272,12 +272,8 @@ void set_color(rgb_color_t c, rgb_color_t c2) { } // Lastly, we set bold mode and underline mode correctly. - if ((enter_bold_mode != 0) && (strlen(enter_bold_mode) > 0) && !bg_set) { - if (is_bold && !was_bold) { - if (enter_bold_mode) { - writembs(tparm(enter_bold_mode)); - } - } + if (is_bold && !was_bold && enter_bold_mode && strlen(enter_bold_mode) > 0 && !bg_set) { + writembs(tparm(enter_bold_mode)); was_bold = is_bold; } diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index a4a87c99e..b52dbfd7f 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -1208,12 +1208,10 @@ parse_execution_result_t parse_execution_context_t::run_1_job(const parse_node_t // Get terminal modes. struct termios tmodes = {}; - if (shell_is_interactive()) { - if (tcgetattr(STDIN_FILENO, &tmodes)) { - // Need real error handling here. - wperror(L"tcgetattr"); - return parse_execution_errored; - } + if (shell_is_interactive() && tcgetattr(STDIN_FILENO, &tmodes)) { + // Need real error handling here. + wperror(L"tcgetattr"); + return parse_execution_errored; } // Increment the eval_level for the duration of this command. diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp index 3c1fcbcb2..0455b50fa 100644 --- a/src/parse_productions.cpp +++ b/src/parse_productions.cpp @@ -500,11 +500,9 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n PARSE_ASSERT(resolver != NULL); const production_t *result = resolver(input1, input2, out_tag); - if (result == NULL) { - if (log_it) { - fprintf(stderr, "Node type '%ls' has no production for input '%ls' (in %s)\n", - token_type_description(node_type), input1.describe().c_str(), __FUNCTION__); - } + if (result == NULL && log_it) { + fprintf(stderr, "Node type '%ls' has no production for input '%ls' (in %s)\n", + token_type_description(node_type), input1.describe().c_str(), __FUNCTION__); } return result; diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index b524f59fe..350eff9ca 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -1370,13 +1370,11 @@ const parse_node_t *parse_node_tree_t::find_last_node_of_type(parse_token_type_t size_t idx = this->size(); while (idx--) { const parse_node_t &node = this->at(idx); - if (node.type == type) { - // Types match. Check if it has the right parent. - if (parent == NULL || node_has_ancestor(*this, node, *parent)) { - // Success - result = &node; - break; - } + bool expected_type = (node.type == type); + if (expected_type && (parent == NULL || node_has_ancestor(*this, node, *parent))) { + // The types match and it has the right parent. + result = &node; + break; } } return result; diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 1cd4f895c..ff0f01883 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -471,7 +471,6 @@ void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_ size_t *offset, enum token_type *out_type) { size_t prev_pos = 0; wchar_t last_quote = '\0'; - int unfinished; tokenizer_t tok(cmd.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS); tok_t token; @@ -488,30 +487,25 @@ void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_ wchar_t *cmd_tmp = wcsdup(cmd.c_str()); cmd_tmp[pos] = 0; size_t cmdlen = wcslen(cmd_tmp); - unfinished = (cmdlen == 0); - if (!unfinished) { - unfinished = (quote != 0); - - if (!unfinished) { - if (wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1]) != 0) { - if ((cmdlen == 1) || (cmd_tmp[cmdlen - 2] != L'\\')) { - unfinished = 1; - } - } + bool finished = (cmdlen != 0); + if (finished) { + finished = (quote == NULL); + if (finished && wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1]) == 0) { + finished = (cmdlen == 1) || (cmd_tmp[cmdlen - 2] != L'\\'); } } if (quote) *quote = last_quote; if (offset != 0) { - if (!unfinished) { + if (finished) { while ((cmd_tmp[prev_pos] != 0) && (wcschr(L";|", cmd_tmp[prev_pos]) != 0)) prev_pos++; - *offset = prev_pos; } else { *offset = pos; } } + free(cmd_tmp); } @@ -927,22 +921,21 @@ static parser_test_error_bits_t detect_dollar_cmdsub_errors(size_t arg_src_offse parse_error_list_t *out_errors) { parser_test_error_bits_t result_bits = 0; wcstring unescaped_arg_src; - if (unescape_string(arg_src, &unescaped_arg_src, UNESCAPE_SPECIAL)) { - if (!unescaped_arg_src.empty()) { - wchar_t last = unescaped_arg_src.at(unescaped_arg_src.size() - 1); - if (last == VARIABLE_EXPAND) { - result_bits |= PARSER_TEST_ERROR; - if (out_errors != NULL) { - wcstring subcommand_first_token = tok_first(cmdsubst_src); - if (subcommand_first_token.empty()) { - // e.g. $(). Report somthing. - subcommand_first_token = L"..."; - } - append_syntax_error( - out_errors, - arg_src_offset + arg_src.size() - 1, // global position of the dollar - ERROR_BAD_VAR_SUBCOMMAND1, truncate_string(subcommand_first_token).c_str()); + if (unescape_string(arg_src, &unescaped_arg_src, UNESCAPE_SPECIAL) && + !unescaped_arg_src.empty()) { + wchar_t last = unescaped_arg_src.at(unescaped_arg_src.size() - 1); + if (last == VARIABLE_EXPAND) { + result_bits |= PARSER_TEST_ERROR; + if (out_errors != NULL) { + wcstring subcommand_first_token = tok_first(cmdsubst_src); + if (subcommand_first_token.empty()) { + // e.g. $(). Report somthing. + subcommand_first_token = L"..."; } + append_syntax_error( + out_errors, + arg_src_offset + arg_src.size() - 1, // global position of the dollar + ERROR_BAD_VAR_SUBCOMMAND1, truncate_string(subcommand_first_token).c_str()); } } } diff --git a/src/postfork.cpp b/src/postfork.cpp index 5f15f9954..792ee2917 100644 --- a/src/postfork.cpp +++ b/src/postfork.cpp @@ -66,7 +66,9 @@ int set_child_group(job_t *j, process_t *p, int print_errors) { j->pgid = p->pid; } - if (setpgid(p->pid, j->pgid)) { + if (setpgid(p->pid, j->pgid)) { //!OCLINT(collapsible if statements) + // TODO: Figure out why we're testing whether the pgid is correct after attempting to + // set it failed. This was added in commit 4e912ef8 from 2012-02-27. if (getpgid(p->pid) != j->pgid && print_errors) { char pid_buff[128]; char job_id_buff[128]; @@ -95,7 +97,8 @@ int set_child_group(job_t *j, process_t *p, int print_errors) { } if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND)) { - if (tcsetpgrp(0, j->pgid) && print_errors) { + int result = tcsetpgrp(0, j->pgid); + if (result == -1 && print_errors) { char job_id_buff[64]; char command_buff[64]; format_long_safe(job_id_buff, j->job_id); @@ -485,20 +488,14 @@ void safe_report_exec_error(int err, const char *actual_cmd, const char *const * /// allocate memory, etc. bool do_builtin_io(const char *out, size_t outlen, const char *err, size_t errlen) { bool success = true; - if (out && outlen) { - if (write_loop(STDOUT_FILENO, out, outlen) < 0) { - int e = errno; - debug_safe(0, "Error while writing to stdout"); - safe_perror("write_loop"); - success = false; - errno = e; - } + if (out && outlen && write_loop(STDOUT_FILENO, out, outlen) < 0) { + int e = errno; + debug_safe(0, "Error while writing to stdout"); + safe_perror("write_loop"); + success = false; + errno = e; } - if (err && errlen) { - if (write_loop(STDERR_FILENO, err, errlen) < 0) { - success = false; - } - } + if (err && errlen && write_loop(STDERR_FILENO, err, errlen) < 0) success = false; return success; } diff --git a/src/print_help.cpp b/src/print_help.cpp index 03ae38593..c19a51dfc 100644 --- a/src/print_help.cpp +++ b/src/print_help.cpp @@ -16,9 +16,7 @@ void print_help(const char *c, int fd) { char cmd[CMD_LEN]; int printed = snprintf(cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd); - if (printed < CMD_LEN) { - if ((system(cmd) == -1)) { - write_loop(2, HELP_ERR, strlen(HELP_ERR)); - } + if (printed < CMD_LEN && system(cmd) == -1) { + write_loop(2, HELP_ERR, strlen(HELP_ERR)); } } diff --git a/src/proc.cpp b/src/proc.cpp index d3e7b733d..f415df14d 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -257,13 +257,9 @@ int job_signal(job_t *j, int signal) { res = killpg(j->pgid, signal); } else { for (process_t *p = j->first_process; p; p = p->next) { - if (!p->completed) { - if (p->pid) { - if (kill(p->pid, signal)) { - res = -1; - break; - } - } + if (!p->completed && p->pid && kill(p->pid, signal)) { + res = -1; + break; } } } @@ -312,10 +308,8 @@ static void handle_child_status(pid_t pid, int status) { for (p = j->first_process; p; p = p->next) { if (pid == p->pid) { mark_process_status(p, status); - if (p->completed && prev != 0) { - if (!prev->completed && prev->pid) { - kill(prev->pid, SIGPIPE); - } + if (p->completed && prev && !prev->completed && prev->pid) { + kill(prev->pid, SIGPIPE); } found_proc = true; break; @@ -568,61 +562,57 @@ int job_reap(bool allow_interactive) { proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, p->pid, (WIFSIGNALED(s) ? -1 : WEXITSTATUS(s))); - if (WIFSIGNALED(s)) { - // Ignore signal SIGPIPE.We issue it ourselves to the pipe writer when the pipe - // reader dies. - if (WTERMSIG(s) != SIGPIPE) { - int proc_is_job = ((p == j->first_process) && (p->next == 0)); - if (proc_is_job) job_set_flag(j, JOB_NOTIFIED, 1); - if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) { - // Print nothing if we get SIGINT in the foreground process group, to avoid - // spamming obvious stuff on the console (#1119). If we get SIGINT for the - // foreground process, assume the user typed ^C and can see it working. It's - // possible they didn't, and the signal was delivered via pkill, etc., but - // the SIGINT/SIGTERM distinction is precisely to allow INT to be from a UI - // and TERM to be programmatic, so this assumption is keeping with the - // design of signals. If echoctl is on, then the terminal will have written - // ^C to the console. If off, it won't have. We don't echo ^C either way, so - // as to respect the user's preference. - if (WTERMSIG(p->status) != SIGINT || !job_get_flag(j, JOB_FOREGROUND)) { - if (proc_is_job) { - // We want to report the job number, unless it's the only job, in - // which case we don't need to. - const wcstring job_number_desc = - (job_count == 1) ? wcstring() - : format_string(L"Job %d, ", j->job_id); - fwprintf(stdout, - _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"), - program_name, job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); - } else { - const wcstring job_number_desc = - (job_count == 1) ? wcstring() - : format_string(L"from job %d, ", j->job_id); - fwprintf(stdout, _(L"%ls: Process %d, \'%ls\' %ls\'%ls\' " - L"terminated by signal %ls (%ls)"), - program_name, p->pid, p->argv0(), job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); - } - - if (cur_term != NULL) - tputs(clr_eol, 1, &writeb); - else - fwprintf(stdout, - L"\x1b[K"); // no term set up - do clr_eol manually - - fwprintf(stdout, L"\n"); + // Ignore signal SIGPIPE.We issue it ourselves to the pipe writer when the pipe + // reader dies. + if (WIFSIGNALED(s) && WTERMSIG(s) != SIGPIPE) { + int proc_is_job = ((p == j->first_process) && (p->next == 0)); + if (proc_is_job) job_set_flag(j, JOB_NOTIFIED, 1); + if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) { + // Print nothing if we get SIGINT in the foreground process group, to avoid + // spamming obvious stuff on the console (#1119). If we get SIGINT for the + // foreground process, assume the user typed ^C and can see it working. It's + // possible they didn't, and the signal was delivered via pkill, etc., but + // the SIGINT/SIGTERM distinction is precisely to allow INT to be from a UI + // and TERM to be programmatic, so this assumption is keeping with the + // design of signals. If echoctl is on, then the terminal will have written + // ^C to the console. If off, it won't have. We don't echo ^C either way, so + // as to respect the user's preference. + if (WTERMSIG(p->status) != SIGINT || !job_get_flag(j, JOB_FOREGROUND)) { + if (proc_is_job) { + // We want to report the job number, unless it's the only job, in + // which case we don't need to. + const wcstring job_number_desc = + (job_count == 1) ? wcstring() + : format_string(L"Job %d, ", j->job_id); + fwprintf(stdout, _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"), + program_name, job_number_desc.c_str(), + truncate_command(j->command()).c_str(), + sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); + } else { + const wcstring job_number_desc = + (job_count == 1) ? wcstring() + : format_string(L"from job %d, ", j->job_id); + fwprintf(stdout, _(L"%ls: Process %d, \'%ls\' %ls\'%ls\' " + L"terminated by signal %ls (%ls)"), + program_name, p->pid, p->argv0(), job_number_desc.c_str(), + truncate_command(j->command()).c_str(), + sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); } - found = 1; - } - // Clear status so it is not reported more than once. - p->status = 0; + if (cur_term != NULL) + tputs(clr_eol, 1, &writeb); + else + fwprintf(stdout, L"\x1b[K"); // no term set up - do clr_eol manually + + fwprintf(stdout, L"\n"); + } + found = 1; } + + // Clear status so it is not reported more than once. + p->status = 0; } } @@ -803,13 +793,10 @@ static bool terminal_give_to_job(job_t *j, int cont) { return false; } - if (cont) { - if (tcsetattr(0, TCSADRAIN, &j->tmodes)) { - debug(1, _(L"Could not send job %d ('%ls') to foreground"), j->job_id, - j->command_wcstr()); - wperror(L"tcsetattr"); - return false; - } + if (cont && tcsetattr(0, TCSADRAIN, &j->tmodes)) { + debug(1, _(L"Could not send job %d ('%ls') to foreground"), j->job_id, j->command_wcstr()); + wperror(L"tcsetattr"); + return false; } return true; } @@ -944,15 +931,13 @@ void job_continue(job_t *j, bool cont) { process_t *p = j->first_process; while (p->next) p = p->next; - if (WIFEXITED(p->status) || WIFSIGNALED(p->status)) { - // Mark process status only if we are in the foreground and the last process in a - // pipe, and it is not a short circuited builtin. - if (p->pid) { - int status = proc_format_status(p->status); - // wprintf(L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE - // )?!status:status, j->command); - proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? !status : status); - } + // Mark process status only if we are in the foreground and the last process in a pipe, + // and it is not a short circuited builtin. + if ((WIFEXITED(p->status) || WIFSIGNALED(p->status)) && p->pid) { + int status = proc_format_status(p->status); + // wprintf(L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE + // )?!status:status, j->command); + proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? !status : status); } } diff --git a/src/reader.cpp b/src/reader.cpp index 2b6b82ccb..e4c04bad0 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -697,14 +697,13 @@ void reader_write_title(const wcstring &cmd, bool reset_cursor_position) { wcstring_list_t lst; proc_push_interactive(0); - if (exec_subshell(fish_title_command, lst, false /* do not apply exit status */) != -1) { - if (!lst.empty()) { - writestr(L"\x1b]0;"); - for (size_t i = 0; i < lst.size(); i++) { - writestr(lst.at(i).c_str()); - } - writestr(L"\7"); + if (exec_subshell(fish_title_command, lst, false /* ignore exit status */) != -1 && + !lst.empty()) { + writestr(L"\x1b]0;"); + for (size_t i = 0; i < lst.size(); i++) { + writestr(lst.at(i).c_str()); } + writestr(L"\7"); } proc_pop_interactive(); set_color(rgb_color_t::reset(), rgb_color_t::reset()); @@ -1531,10 +1530,8 @@ static bool check_for_orphaned_process(unsigned long loop_count, pid_t shell_pgi // Try kill-0'ing the process whose pid corresponds to our process group ID. It's possible this // will fail because we don't have permission to signal it. But more likely it will fail because // it no longer exists, and we are orphaned. - if (loop_count % 64 == 0) { - if (kill(shell_pgid, 0) < 0 && errno == ESRCH) { - we_think_we_are_orphaned = true; - } + if (loop_count % 64 == 0 && kill(shell_pgid, 0) < 0 && errno == ESRCH) { + we_think_we_are_orphaned = true; } if (!we_think_we_are_orphaned && loop_count % 128 == 0) { @@ -1646,12 +1643,10 @@ static void reader_interactive_init() { // Put ourselves in our own process group. shell_pgid = getpid(); - if (getpgrp() != shell_pgid) { - if (setpgid(shell_pgid, shell_pgid) < 0) { - debug(1, _(L"Couldn't put the shell in its own process group")); - wperror(L"setpgid"); - exit_without_destructors(1); - } + if (getpgrp() != shell_pgid && setpgid(shell_pgid, shell_pgid) < 0) { + debug(1, _(L"Couldn't put the shell in its own process group")); + wperror(L"setpgid"); + exit_without_destructors(1); } // Grab control of the terminal. @@ -2438,42 +2433,40 @@ const wchar_t *reader_readline(int nchars) { is_interactive_read = was_interactive_read; // fprintf(stderr, "C: %lx\n", (long)c); - if (((!fish_reserved_codepoint(c))) && (c > 31) && (c != 127)) { - if (can_read(0)) { - wchar_t arr[READAHEAD_MAX + 1]; - size_t i; - size_t limit = 0 < nchars ? std::min((size_t)nchars - data->command_line.size(), - (size_t)READAHEAD_MAX) - : READAHEAD_MAX; + if (((!fish_reserved_codepoint(c))) && (c > 31) && (c != 127) && can_read(0)) { + wchar_t arr[READAHEAD_MAX + 1]; + size_t i; + size_t limit = 0 < nchars ? std::min((size_t)nchars - data->command_line.size(), + (size_t)READAHEAD_MAX) + : READAHEAD_MAX; - memset(arr, 0, sizeof(arr)); - arr[0] = c; + memset(arr, 0, sizeof(arr)); + arr[0] = c; - for (i = 1; i < limit; ++i) { - if (!can_read(0)) { - c = 0; - break; - } - // Only allow commands on the first key; otherwise, we might have data we - // need to insert on the commandline that the commmand might need to be able - // to see. - c = input_readch(false); - if ((!fish_reserved_codepoint(c)) && (c > 31) && (c != 127)) { - arr[i] = c; - c = 0; - } else - break; + for (i = 1; i < limit; ++i) { + if (!can_read(0)) { + c = 0; + break; } - - editable_line_t *el = data->active_edit_line(); - insert_string(el, arr, true); - - // End paging upon inserting into the normal command line. - if (el == &data->command_line) { - clear_pager(); - } - last_char = c; + // Only allow commands on the first key; otherwise, we might have data we + // need to insert on the commandline that the commmand might need to be able + // to see. + c = input_readch(false); + if (!fish_reserved_codepoint(c) && c > 31 && c != 127) { + arr[i] = c; + c = 0; + } else + break; } + + editable_line_t *el = data->active_edit_line(); + insert_string(el, arr, true); + + // End paging upon inserting into the normal command line. + if (el == &data->command_line) { + clear_pager(); + } + last_char = c; } if (c != 0) break; diff --git a/src/util.cpp b/src/util.cpp index b8f868094..7caba32bc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -58,12 +58,10 @@ int wcsfilecmp(const wchar_t *a, const wchar_t *b) { int res = wcsfilecmp(a + 1, b + 1); - if (abs(res) < 2) { - // No primary difference in rest of string. Use secondary difference on this element if - // found. - if (secondary_diff) { - return secondary_diff > 0 ? 1 : -1; - } + // If no primary difference in rest of string use secondary difference on this element if + // found. + if (abs(res) < 2 && secondary_diff) { + return secondary_diff > 0 ? 1 : -1; } return res; diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 50468c706..f2ef9fed7 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -328,14 +328,12 @@ static wcstring file_get_desc(const wcstring &filename, int lstat_res, const str if (S_ISDIR(buf.st_mode)) { return COMPLETE_DIRECTORY_SYMLINK_DESC; } - if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { - if (waccess(filename, X_OK) == 0) { - // Weird group permissions and other such issues make it non-trivial to - // find out if we can actually execute a file using the result from - // stat. It is much safer to use the access function, since it tells us - // exactly what we want to know. - return COMPLETE_EXEC_LINK_DESC; - } + if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) && waccess(filename, X_OK) == 0) { + // Weird group permissions and other such issues make it non-trivial to + // find out if we can actually execute a file using the result from + // stat. It is much safer to use the access function, since it tells us + // exactly what we want to know. + return COMPLETE_EXEC_LINK_DESC; } return COMPLETE_SYMLINK_DESC; @@ -364,14 +362,12 @@ static wcstring file_get_desc(const wcstring &filename, int lstat_res, const str } else if (S_ISDIR(buf.st_mode)) { return COMPLETE_DIRECTORY_DESC; } else { - if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXGRP)) { - if (waccess(filename, X_OK) == 0) { - // Weird group permissions and other such issues make it non-trivial to find out - // if we can actually execute a file using the result from stat. It is much - // safer to use the access function, since it tells us exactly what we want to - // know. - return COMPLETE_EXEC_DESC; - } + if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXGRP) && waccess(filename, X_OK) == 0) { + // Weird group permissions and other such issues make it non-trivial to find out + // if we can actually execute a file using the result from stat. It is much + // safer to use the access function, since it tells us exactly what we want to + // know. + return COMPLETE_EXEC_DESC; } } } @@ -415,15 +411,14 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc const bool is_directory = stat_res == 0 && S_ISDIR(stat_buf.st_mode); const bool is_executable = stat_res == 0 && S_ISREG(stat_buf.st_mode); - if (expand_flags & DIRECTORIES_ONLY) { - if (!is_directory) { - return false; - } + const bool need_directory = expand_flags & DIRECTORIES_ONLY; + if (need_directory && !is_directory) { + return false; } - if (expand_flags & EXECUTABLES_ONLY) { - if (!is_executable || waccess(filepath, X_OK) != 0) { - return false; - } + + const bool executables_only = expand_flags & EXECUTABLES_ONLY; + if (executables_only && (!is_executable || waccess(filepath, X_OK) != 0)) { + return false; } // Compute the description. From 21521b295397f44d073e94276b8b761f009410ea Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 20:32:25 -0700 Subject: [PATCH 016/112] lint: too few branches in switch statement Someone was way too enamored of the `switch` statement. Using it in places where a simple `if...else if...else` was clearer and shorter. --- src/builtin.cpp | 244 +++++++++++++++--------------------- src/builtin_commandline.cpp | 42 +++---- src/builtin_test.cpp | 147 ++++++++++------------ src/builtin_ulimit.cpp | 72 +++++------ src/expand.cpp | 41 +++--- src/input.cpp | 10 +- src/input_common.cpp | 29 ++--- src/iothread.cpp | 22 ++-- src/parse_tree.cpp | 22 ++-- src/parse_util.cpp | 33 +++-- src/path.cpp | 14 +-- src/reader.cpp | 114 ++++++++--------- src/wildcard.cpp | 16 +-- 13 files changed, 339 insertions(+), 467 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 8e0f027be..104a07e40 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -345,23 +345,16 @@ static int get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_strea if (input_terminfo_get_sequence(seq, out_seq)) { return 1; } + wcstring eseq = escape_string(seq, 0); - switch (errno) { - case ENOENT: { - streams.err.append_format(_(L"%ls: No key with name '%ls' found\n"), L"bind", - eseq.c_str()); - break; - } - case EILSEQ: { - streams.err.append_format(_(L"%ls: Key with name '%ls' does not have any mapping\n"), - L"bind", eseq.c_str()); - break; - } - default: { - streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"), - L"bind", eseq.c_str()); - break; - } + if (errno == ENOENT) { + streams.err.append_format(_(L"%ls: No key with name '%ls' found\n"), L"bind", eseq.c_str()); + } else if (errno == EILSEQ) { + streams.err.append_format(_(L"%ls: Key with name '%ls' does not have any mapping\n"), + L"bind", eseq.c_str()); + } else { + streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"), + L"bind", eseq.c_str()); } return 0; } @@ -525,43 +518,37 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) break; } case BIND_INSERT: { - switch (argc - w.woptind) { - case 0: { - builtin_bind_list(bind_mode_given ? bind_mode : NULL, streams); - break; + int arg_count = argc - w.woptind; + if (arg_count == 0) { + builtin_bind_list(bind_mode_given ? bind_mode : NULL, streams); + } else if (arg_count == 1) { + wcstring seq; + if (use_terminfo) { + if (!get_terminfo_sequence(argv[w.woptind], &seq, streams)) { + res = STATUS_BUILTIN_ERROR; + // get_terminfo_sequence already printed the error. + break; + } + } else { + seq = argv[w.woptind]; } - case 1: { - wcstring seq; + if (!builtin_bind_list_one(seq, bind_mode, streams)) { + res = STATUS_BUILTIN_ERROR; + wcstring eseq = escape_string(argv[w.woptind], 0); if (use_terminfo) { - if (!get_terminfo_sequence(argv[w.woptind], &seq, streams)) { - res = STATUS_BUILTIN_ERROR; - // get_terminfo_sequence already printed the error. - break; - } + streams.err.append_format(_(L"%ls: No binding found for key '%ls'\n"), + argv[0], eseq.c_str()); } else { - seq = argv[w.woptind]; + streams.err.append_format(_(L"%ls: No binding found for sequence '%ls'\n"), + argv[0], eseq.c_str()); } - if (!builtin_bind_list_one(seq, bind_mode, streams)) { - res = STATUS_BUILTIN_ERROR; - wcstring eseq = escape_string(argv[w.woptind], 0); - if (use_terminfo) { - streams.err.append_format(_(L"%ls: No binding found for key '%ls'\n"), - argv[0], eseq.c_str()); - } else { - streams.err.append_format( - _(L"%ls: No binding found for sequence '%ls'\n"), argv[0], - eseq.c_str()); - } - } - break; } - default: { - if (builtin_bind_add(argv[w.woptind], argv + (w.woptind + 1), - argc - (w.woptind + 1), bind_mode, sets_bind_mode, - use_terminfo, streams)) { - res = STATUS_BUILTIN_ERROR; - } - break; + break; + } else { + if (builtin_bind_add(argv[w.woptind], argv + (w.woptind + 1), + argc - (w.woptind + 1), bind_mode, sets_bind_mode, + use_terminfo, streams)) { + res = STATUS_BUILTIN_ERROR; } } break; @@ -1776,39 +1763,33 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg } } - switch (argc - w.woptind) { - case 0: { - long res; - if (!seeded) { - seeded = 1; - srand48_r(time(0), &seed_buffer); - } - lrand48_r(&seed_buffer, &res); - streams.out.append_format(L"%ld\n", res % 32768); - break; - } - case 1: { - long foo; - wchar_t *end = 0; - - errno = 0; - foo = wcstol(argv[w.woptind], &end, 10); - if (errno || *end) { - streams.err.append_format(_(L"%ls: Seed value '%ls' is not a valid number\n"), - argv[0], argv[w.woptind]); - - return STATUS_BUILTIN_ERROR; - } + int arg_count = argc - w.woptind; + if (arg_count == 0) { + long res; + if (!seeded) { seeded = 1; - srand48_r(foo, &seed_buffer); - break; + srand48_r(time(0), &seed_buffer); } - default: { - streams.err.append_format(_(L"%ls: Expected zero or one argument, got %d\n"), argv[0], - argc - w.woptind); - builtin_print_help(parser, streams, argv[0], streams.err); + lrand48_r(&seed_buffer, &res); + streams.out.append_format(L"%ld\n", res % 32768); + } else if (arg_count == 1) { + long foo; + wchar_t *end = 0; + + errno = 0; + foo = wcstol(argv[w.woptind], &end, 10); + if (errno || *end) { + streams.err.append_format(_(L"%ls: Seed value '%ls' is not a valid number\n"), argv[0], + argv[w.woptind]); return STATUS_BUILTIN_ERROR; } + seeded = 1; + srand48_r(foo, &seed_buffer); + } else { + streams.err.append_format(_(L"%ls: Expected zero or one argument, got %d\n"), argv[0], + argc - w.woptind); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; } return STATUS_BUILTIN_OK; } @@ -1900,19 +1881,16 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) errno = 0; nchars = fish_wcstoi(w.woptarg, &end, 10); if (errno || *end != 0) { - switch (errno) { - case ERANGE: { - streams.err.append_format(_(L"%ls: Argument '%ls' is out of range\n"), - argv[0], w.woptarg); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; - } - default: { - streams.err.append_format( - _(L"%ls: Argument '%ls' must be an integer\n"), argv[0], w.woptarg); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; - } + if (errno == ERANGE) { + streams.err.append_format(_(L"%ls: Argument '%ls' is out of range\n"), + argv[0], w.woptarg); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; + } else { + streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), + argv[0], w.woptarg); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; } } break; @@ -2045,18 +2023,10 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) finished = 1; } else { size_t sz = mbrtowc(&res, &b, 1, &state); - switch (sz) { - case (size_t)-1: { - memset(&state, 0, sizeof(state)); - break; - } - case (size_t)-2: { - break; - } - default: { - finished = 1; - break; - } + if (sz == (size_t)-1) { + memset(&state, 0, sizeof(state)); + } else if (sz != (size_t)-2) { + finished = 1; } } } @@ -2310,27 +2280,22 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv) { int argc = builtin_count_args(argv); - long ec = 0; - switch (argc) { - case 1: { - ec = proc_get_last_status(); - break; - } - case 2: { - wchar_t *end; - errno = 0; - ec = wcstol(argv[1], &end, 10); - if (errno || *end != 0) { - streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], - argv[1]); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; - } - break; - } - default: { - streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); + if (argc > 2) { + streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; + } + long ec; + if (argc == 1) { + ec = proc_get_last_status(); + } else { + wchar_t *end; + errno = 0; + ec = wcstol(argv[1], &end, 10); + if (errno || *end != 0) { + streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], + argv[1]); builtin_print_help(parser, streams, argv[0], streams.err); return STATUS_BUILTIN_ERROR; } @@ -2752,29 +2717,26 @@ static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t * /// Function for handling the \c return builtin. static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **argv) { int argc = builtin_count_args(argv); - int status = proc_get_last_status(); - switch (argc) { - case 1: { - break; - } - case 2: { - wchar_t *end; - errno = 0; - status = fish_wcstoi(argv[1], &end, 10); - if (errno || *end != 0) { - streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], - argv[1]); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; - } - break; - } - default: { - streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]); + if (argc > 2) { + streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; + } + + int status; + if (argc == 2) { + wchar_t *end; + errno = 0; + status = fish_wcstoi(argv[1], &end, 10); + if (errno || *end != 0) { + streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], + argv[1]); builtin_print_help(parser, streams, argv[0], streams.err); return STATUS_BUILTIN_ERROR; } + } else { + status = proc_get_last_status(); } // Find the function block. diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp index 4afa04f7d..1836b2377 100644 --- a/src/builtin_commandline.cpp +++ b/src/builtin_commandline.cpp @@ -152,15 +152,11 @@ static void write_part(const wchar_t *begin, const wchar_t *end, int cut_at_curs while (tok.next(&token)) { if ((cut_at_cursor) && (token.offset + token.text.size() >= pos)) break; - switch (token.type) { - case TOK_STRING: { - wcstring tmp = token.text; - unescape_string_in_place(&tmp, UNESCAPE_INCOMPLETE); - out.append(tmp); - out.push_back(L'\n'); - break; - } - default: { break; } + if (token.type == TOK_STRING) { + wcstring tmp = token.text; + unescape_string_in_place(&tmp, UNESCAPE_INCOMPLETE); + out.append(tmp); + out.push_back(L'\n'); } } @@ -476,24 +472,18 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv) } } - switch (argc - w.woptind) { - case 0: { - write_part(begin, end, cut_at_cursor, tokenize, streams); - break; - } - case 1: { - replace_part(begin, end, argv[w.woptind], append_mode); - break; - } - default: { - wcstring sb = argv[w.woptind]; - for (int i = w.woptind + 1; i < argc; i++) { - sb.push_back(L'\n'); - sb.append(argv[i]); - } - replace_part(begin, end, sb.c_str(), append_mode); - break; + int arg_count = argc - w.woptind; + if (arg_count == 0) { + write_part(begin, end, cut_at_cursor, tokenize, streams); + } else if (arg_count == 1) { + replace_part(begin, end, argv[w.woptind], append_mode); + } else { + wcstring sb = argv[w.woptind]; + for (int i = w.woptind + 1; i < argc; i++) { + sb.push_back(L'\n'); + sb.append(argv[i]); } + replace_part(begin, end, sb.c_str(), append_mode); } return 0; diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp index 3c45be8a3..9d8744d35 100644 --- a/src/builtin_test.cpp +++ b/src/builtin_test.cpp @@ -579,62 +579,55 @@ bool binary_primary::evaluate(wcstring_list_t &errors) { } bool unary_operator::evaluate(wcstring_list_t &errors) { - switch (token) { - case test_bang: { - assert(subject.get()); - return !subject->evaluate(errors); - } - default: { - errors.push_back(format_string(L"Unknown token type in %s", __func__)); - return false; - } + if (token == test_bang) { + assert(subject.get()); + return !subject->evaluate(errors); } + + errors.push_back(format_string(L"Unknown token type in %s", __func__)); + return false; } bool combining_expression::evaluate(wcstring_list_t &errors) { - switch (token) { - case test_combine_and: - case test_combine_or: { - assert(!subjects.empty()); - assert(combiners.size() + 1 == subjects.size()); + if (token == test_combine_and || token == test_combine_or) { + assert(!subjects.empty()); + assert(combiners.size() + 1 == subjects.size()); - // One-element case. - if (subjects.size() == 1) return subjects.at(0)->evaluate(errors); + // One-element case. + if (subjects.size() == 1) return subjects.at(0)->evaluate(errors); - // Evaluate our lists, remembering that AND has higher precedence than OR. We can - // visualize this as a sequence of OR expressions of AND expressions. - size_t idx = 0, max = subjects.size(); - bool or_result = false; - while (idx < max) { - if (or_result) { // short circuit + // Evaluate our lists, remembering that AND has higher precedence than OR. We can + // visualize this as a sequence of OR expressions of AND expressions. + size_t idx = 0, max = subjects.size(); + bool or_result = false; + while (idx < max) { + if (or_result) { // short circuit + break; + } + + // Evaluate a stream of AND starting at given subject index. It may only have one + // element. + bool and_result = true; + for (; idx < max; idx++) { + // Evaluate it, short-circuiting. + and_result = and_result && subjects.at(idx)->evaluate(errors); + + // If the combiner at this index (which corresponding to how we combine with the + // next subject) is not AND, then exit the loop. + if (idx + 1 < max && combiners.at(idx) != test_combine_and) { + idx++; break; } - - // Evaluate a stream of AND starting at given subject index. It may only have one - // element. - bool and_result = true; - for (; idx < max; idx++) { - // Evaluate it, short-circuiting. - and_result = and_result && subjects.at(idx)->evaluate(errors); - - // If the combiner at this index (which corresponding to how we combine with the - // next subject) is not AND, then exit the loop. - if (idx + 1 < max && combiners.at(idx) != test_combine_and) { - idx++; - break; - } - } - - // OR it in. - or_result = or_result || and_result; } - return or_result; - } - default: { - errors.push_back(format_string(L"Unknown token type in %s", __func__)); - return BUILTIN_TEST_FAIL; + + // OR it in. + or_result = or_result || and_result; } + return or_result; } + + errors.push_back(format_string(L"Unknown token type in %s", __func__)); + return BUILTIN_TEST_FAIL; } bool parenthetical_expression::evaluate(wcstring_list_t &errors) { @@ -798,42 +791,36 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) { // Collect the arguments into a list. const wcstring_list_t args(argv + 1, argv + 1 + argc); - switch (argc) { - case 0: { - // Per 1003.1, exit false. - return BUILTIN_TEST_FAIL; - } - case 1: { - // Per 1003.1, exit true if the arg is non-empty. - return args.at(0).empty() ? BUILTIN_TEST_FAIL : BUILTIN_TEST_SUCCESS; - } - default: { - // Try parsing. If expr is not nil, we are responsible for deleting it. - wcstring err; - expression *expr = test_parser::parse_args(args, err); - if (!expr) { -#if 0 - printf("Oops! test was given args:\n"); - for (size_t i=0; i < argc; i++) { - printf("\t%ls\n", args.at(i).c_str()); - } - printf("and returned parse error: %ls\n", err.c_str()); -#endif - streams.err.append(err); - return BUILTIN_TEST_FAIL; - } + if (argc == 0) { + return BUILTIN_TEST_FAIL; // Per 1003.1, exit false. + } else if (argc == 1) { + // Per 1003.1, exit true if the arg is non-empty. + return args.at(0).empty() ? BUILTIN_TEST_FAIL : BUILTIN_TEST_SUCCESS; + } - wcstring_list_t eval_errors; - bool result = expr->evaluate(eval_errors); - if (!eval_errors.empty()) { - printf("test returned eval errors:\n"); - for (size_t i = 0; i < eval_errors.size(); i++) { - printf("\t%ls\n", eval_errors.at(i).c_str()); - } - } - delete expr; - return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL; + // Try parsing. If expr is not nil, we are responsible for deleting it. + wcstring err; + expression *expr = test_parser::parse_args(args, err); + if (!expr) { +#if 0 + printf("Oops! test was given args:\n"); + for (size_t i=0; i < argc; i++) { + printf("\t%ls\n", args.at(i).c_str()); + } + printf("and returned parse error: %ls\n", err.c_str()); +#endif + streams.err.append(err); + return BUILTIN_TEST_FAIL; + } + + wcstring_list_t eval_errors; + bool result = expr->evaluate(eval_errors); + if (!eval_errors.empty()) { + printf("test returned eval errors:\n"); + for (size_t i = 0; i < eval_errors.size(); i++) { + printf("\t%ls\n", eval_errors.at(i).c_str()); } } - return 1; + delete expr; + return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL; } diff --git a/src/builtin_ulimit.cpp b/src/builtin_ulimit.cpp index 6399cbdfe..6c67eb9f1 100644 --- a/src/builtin_ulimit.cpp +++ b/src/builtin_ulimit.cpp @@ -278,46 +278,42 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) { return 0; } - switch (argc - w.woptind) { - case 0: { // show current limit value - print(what, hard, streams); - break; - } - case 1: { // change current limit value - rlim_t new_limit; - wchar_t *end; + int arg_count = argc - w.woptind; + if (arg_count == 0) { + // Show current limit value. + print(what, hard, streams); + } else if (arg_count == 1) { + // Change current limit value. + rlim_t new_limit; + wchar_t *end; - // Set both hard and soft limits if nothing else was specified. - if (!(hard + soft)) { - hard = soft = 1; + // Set both hard and soft limits if nothing else was specified. + if (!(hard + soft)) { + hard = soft = 1; + } + + if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) { + new_limit = RLIM_INFINITY; + } else if (wcscasecmp(argv[w.woptind], L"hard") == 0) { + new_limit = get(what, 1); + } else if (wcscasecmp(argv[w.woptind], L"soft") == 0) { + new_limit = get(what, soft); + } else { + errno = 0; + new_limit = wcstol(argv[w.woptind], &end, 10); + if (errno || *end) { + streams.err.append_format(L"%ls: Invalid limit '%ls'\n", argv[0], argv[w.woptind]); + builtin_print_help(parser, streams, argv[0], streams.err); + return 1; } - - if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) { - new_limit = RLIM_INFINITY; - } else if (wcscasecmp(argv[w.woptind], L"hard") == 0) { - new_limit = get(what, 1); - } else if (wcscasecmp(argv[w.woptind], L"soft") == 0) { - new_limit = get(what, soft); - } else { - errno = 0; - new_limit = wcstol(argv[w.woptind], &end, 10); - if (errno || *end) { - streams.err.append_format(L"%ls: Invalid limit '%ls'\n", argv[0], - argv[w.woptind]); - builtin_print_help(parser, streams, argv[0], streams.err); - return 1; - } - new_limit *= get_multiplier(what); - } - - return set(what, hard, soft, new_limit, streams); - } - default: { - streams.err.append(argv[0]); - streams.err.append(L": Too many arguments\n"); - builtin_print_help(parser, streams, argv[0], streams.err); - return 1; + new_limit *= get_multiplier(what); } + + return set(what, hard, soft, new_limit, streams); } - return 0; + + streams.err.append(argv[0]); + streams.err.append(L": Too many arguments\n"); + builtin_print_help(parser, streams, argv[0], streams.err); + return 1; } diff --git a/src/expand.cpp b/src/expand.cpp index 200ed98d4..04937de30 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -166,36 +166,31 @@ wcstring expand_escape_variable(const wcstring &in) { tokenize_variable_array(in, lst); - switch (lst.size()) { - case 0: { - buff.append(L"''"); - break; - } - case 1: { - const wcstring &el = lst.at(0); + int size = lst.size(); + if (size == 0) { + buff.append(L"''"); + } else if (size == 1) { + const wcstring &el = lst.at(0); - if (el.find(L' ') != wcstring::npos && is_quotable(el)) { + if (el.find(L' ') != wcstring::npos && is_quotable(el)) { + buff.append(L"'"); + buff.append(el); + buff.append(L"'"); + } else { + buff.append(escape_string(el, 1)); + } + } else { + for (size_t j = 0; j < lst.size(); j++) { + const wcstring &el = lst.at(j); + if (j) buff.append(L" "); + + if (is_quotable(el)) { buff.append(L"'"); buff.append(el); buff.append(L"'"); } else { buff.append(escape_string(el, 1)); } - break; - } - default: { - for (size_t j = 0; j < lst.size(); j++) { - const wcstring &el = lst.at(j); - if (j) buff.append(L" "); - - if (is_quotable(el)) { - buff.append(L"'"); - buff.append(el); - buff.append(L"'"); - } else { - buff.append(escape_string(el, 1)); - } - } } } return buff; diff --git a/src/input.cpp b/src/input.cpp index 1e6d9b726..f0febb7c7 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -223,14 +223,8 @@ void input_set_bind_mode(const wcstring &bm) { } /// Returns the arity of a given input function. -int input_function_arity(int function) { - switch (function) { - case R_FORWARD_JUMP: - case R_BACKWARD_JUMP: { - return 1; - } - default: { return 0; } - } +static int input_function_arity(int function) { + return (function == R_FORWARD_JUMP || function == R_BACKWARD_JUMP) ? 1 : 0; } /// Sets the return status of the most recently executed input function. diff --git a/src/input_common.cpp b/src/input_common.cpp index b5525d4aa..b2efae06e 100644 --- a/src/input_common.cpp +++ b/src/input_common.cpp @@ -110,26 +110,17 @@ static wint_t readb() { res = select(fd_max + 1, &fdset, 0, 0, usecs_delay > 0 ? &tv : NULL); if (res == -1) { - switch (errno) { - case EINTR: - case EAGAIN: { - if (interrupt_handler) { - int res = interrupt_handler(); - if (res) { - return res; - } - if (has_lookahead()) { - return lookahead_pop(); - } - } + if (errno == EINTR || errno == EAGAIN) { + if (interrupt_handler) { + int res = interrupt_handler(); + if (res) return res; + if (has_lookahead()) return lookahead_pop(); + } - do_loop = true; - break; - } - default: { - // The terminal has been closed. Save and exit. - return R_EOF; - } + do_loop = true; + } else { + // The terminal has been closed. Save and exit. + return R_EOF; } } else { // Assume we loop unless we see a character in stdin. diff --git a/src/iothread.cpp b/src/iothread.cpp index a83631ef8..bc7da0cb5 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -222,21 +222,15 @@ int iothread_port(void) { void iothread_service_completion(void) { ASSERT_IS_MAIN_THREAD(); - char wakeup_byte = 0; + char wakeup_byte; + VOMIT_ON_FAILURE(1 != read_loop(iothread_port(), &wakeup_byte, sizeof wakeup_byte)); - switch (wakeup_byte) { - case IO_SERVICE_MAIN_THREAD_REQUEST_QUEUE: { - iothread_service_main_thread_requests(); - break; - } - case IO_SERVICE_RESULT_QUEUE: { - iothread_service_result_queue(); - break; - } - default: { - fprintf(stderr, "Unknown wakeup byte %02x in %s\n", wakeup_byte, __FUNCTION__); - break; - } + if (wakeup_byte == IO_SERVICE_MAIN_THREAD_REQUEST_QUEUE) { + iothread_service_main_thread_requests(); + } else if (wakeup_byte == IO_SERVICE_RESULT_QUEUE) { + iothread_service_result_queue(); + } else { + fprintf(stderr, "Unknown wakeup byte %02x in %s\n", wakeup_byte, __FUNCTION__); } } diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 350eff9ca..75db04fe5 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -924,18 +924,13 @@ bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) { // Now see if we actually matched bool matched = false; if (stack_top.type == token.type) { - switch (stack_top.type) { - case parse_token_type_string: { - // We matched if the keywords match, or no keyword was required. - matched = (stack_top.keyword == parse_keyword_none || - stack_top.keyword == token.keyword); - break; - } - default: { - // For other types, we only require that the types match. - matched = true; - break; - } + if (stack_top.type == parse_token_type_string) { + // We matched if the keywords match, or no keyword was required. + matched = + (stack_top.keyword == parse_keyword_none || stack_top.keyword == token.keyword); + } else { + // For other types, we only require that the types match. + matched = true; } } @@ -1550,8 +1545,7 @@ enum parse_bool_statement_type_t parse_node_tree_t::statement_boolean_type( bool parse_node_tree_t::job_should_be_backgrounded(const parse_node_t &job) const { assert(job.type == symbol_job); const parse_node_t *opt_background = get_child(job, 2, symbol_optional_background); - bool result = opt_background != NULL && opt_background->tag == parse_background; - return result; + return opt_background != NULL && opt_background->tag == parse_background; } const parse_node_t *parse_node_tree_t::next_node_in_node_list( diff --git a/src/parse_util.cpp b/src/parse_util.cpp index ff0f01883..a394425be 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -1019,28 +1019,23 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t // Check for invalid variable expansions. const size_t unesc_size = unesc.size(); for (size_t idx = 0; idx < unesc_size; idx++) { - switch (unesc.at(idx)) { - case VARIABLE_EXPAND: - case VARIABLE_EXPAND_SINGLE: { - wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0'; + if (unesc.at(idx) == VARIABLE_EXPAND || unesc.at(idx) == VARIABLE_EXPAND_SINGLE) { + wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0'; - if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE && - !wcsvarchr(next_char)) { - err = 1; - if (out_errors) { - // We have something like $$$^.... Back up until we reach the first $. - size_t first_dollar = idx; - while (first_dollar > 0 && - (unesc.at(first_dollar - 1) == VARIABLE_EXPAND || - unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) { - first_dollar--; - } - parse_util_expand_variable_error(unesc, node.source_start, first_dollar, - out_errors); + if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE && + !wcsvarchr(next_char)) { + err = 1; + if (out_errors) { + // We have something like $$$^.... Back up until we reach the first $. + size_t first_dollar = idx; + while (first_dollar > 0 && + (unesc.at(first_dollar - 1) == VARIABLE_EXPAND || + unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) { + first_dollar--; } + parse_util_expand_variable_error(unesc, node.source_start, first_dollar, + out_errors); } - - break; } } } diff --git a/src/path.cpp b/src/path.cpp index c84789ce5..0771e2ed7 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -190,16 +190,10 @@ wcstring path_apply_working_directory(const wcstring &path, const wcstring &work // We're going to make sure that if we want to prepend the wd, that the string has no leading // "/". bool prepend_wd; - switch (path.at(0)) { - case L'/': - case HOME_DIRECTORY: { - prepend_wd = false; - break; - } - default: { - prepend_wd = true; - break; - } + if (path.at(0) == L'/' || path.at(0) == HOME_DIRECTORY) { + prepend_wd = false; + } else { + prepend_wd = true; } if (!prepend_wd) { diff --git a/src/reader.cpp b/src/reader.cpp index e4c04bad0..71d752bab 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1379,27 +1379,23 @@ static bool handle_completions(const std::vector &comp, const wcstring tok(begin, end - begin); // Check trivial cases. - switch (comp.size()) { - case 0: { - // No suitable completions found, flash screen and return. - reader_flash(); - done = true; - success = false; - break; - } - case 1: { - // Exactly one suitable completion found - insert it. - const completion_t &c = comp.at(0); + int size = comp.size(); + if (size == 0) { + // No suitable completions found, flash screen and return. + reader_flash(); + done = true; + success = false; + } else if (size == 1) { + // Exactly one suitable completion found - insert it. + const completion_t &c = comp.at(0); - // If this is a replacement completion, check that we know how to replace it, e.g. that - // the token doesn't contain evil operators like {}. - if (!(c.flags & COMPLETE_REPLACES_TOKEN) || reader_can_replace(tok, c.flags)) { - completion_insert(c.completion.c_str(), c.flags); - } - done = true; - success = true; - break; + // If this is a replacement completion, check that we know how to replace it, e.g. that + // the token doesn't contain evil operators like {}. + if (!(c.flags & COMPLETE_REPLACES_TOKEN) || reader_can_replace(tok, c.flags)) { + completion_insert(c.completion.c_str(), c.flags); } + done = true; + success = true; } if (!done) { @@ -1790,24 +1786,22 @@ static void handle_token_history(int forward, int reset) { tokenizer_t tok(data->token_history_buff.c_str(), TOK_ACCEPT_UNFINISHED); tok_t token; while (tok.next(&token)) { - switch (token.type) { - case TOK_STRING: { - if (token.text.find(data->search_buff) != wcstring::npos) { - // debug( 3, L"Found token at pos %d\n", tok_get_pos( &tok ) ); - if (token.offset >= current_pos) { - break; - } - // debug( 3, L"ok pos" ); - - if (find(data->search_prev.begin(), data->search_prev.end(), - token.text) == data->search_prev.end()) { - data->token_history_pos = token.offset; - str = token.text; - } + if (token.type == TOK_STRING) { + if (token.text.find(data->search_buff) != wcstring::npos) { + // debug( 3, L"Found token at pos %d\n", tok_get_pos( &tok ) ); + if (token.offset >= current_pos) { + break; + } + // debug( 3, L"ok pos" ); + + if (find(data->search_prev.begin(), data->search_prev.end(), token.text) == + data->search_prev.end()) { + data->token_history_pos = token.offset; + str = token.text; } - break; } - default: { break; } + } else { + break; } } } @@ -2873,36 +2867,30 @@ const wchar_t *reader_readline(int nchars) { data->history_search.skip_matches(skip_list); } - switch (data->search_mode) { - case LINE_SEARCH: { - if ((c == R_HISTORY_SEARCH_BACKWARD) || - (c == R_HISTORY_TOKEN_SEARCH_BACKWARD)) { - data->history_search.go_backwards(); - } else { - if (!data->history_search.go_forwards()) { - // If you try to go forwards past the end, we just go to the end. - data->history_search.go_to_end(); - } + if (data->search_mode == LINE_SEARCH) { + if ((c == R_HISTORY_SEARCH_BACKWARD) || + (c == R_HISTORY_TOKEN_SEARCH_BACKWARD)) { + data->history_search.go_backwards(); + } else { + if (!data->history_search.go_forwards()) { + // If you try to go forwards past the end, we just go to the end. + data->history_search.go_to_end(); } - - wcstring new_text; - if (data->history_search.is_at_end()) { - new_text = data->search_buff; - } else { - new_text = data->history_search.current_string(); - } - set_command_line_and_position(&data->command_line, new_text, - new_text.size()); - break; } - case TOKEN_SEARCH: { - if ((c == R_HISTORY_SEARCH_BACKWARD) || - (c == R_HISTORY_TOKEN_SEARCH_BACKWARD)) { - handle_token_history(SEARCH_BACKWARD, reset); - } else { - handle_token_history(SEARCH_FORWARD, reset); - } - break; + + wcstring new_text; + if (data->history_search.is_at_end()) { + new_text = data->search_buff; + } else { + new_text = data->history_search.current_string(); + } + set_command_line_and_position(&data->command_line, new_text, new_text.size()); + } else if (data->search_mode == TOKEN_SEARCH) { + if ((c == R_HISTORY_SEARCH_BACKWARD) || + (c == R_HISTORY_TOKEN_SEARCH_BACKWARD)) { + handle_token_history(SEARCH_BACKWARD, reset); + } else { + handle_token_history(SEARCH_FORWARD, reset); } } break; diff --git a/src/wildcard.cpp b/src/wildcard.cpp index f2ef9fed7..59256a2c1 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -339,18 +339,10 @@ static wcstring file_get_desc(const wcstring &filename, int lstat_res, const str return COMPLETE_SYMLINK_DESC; } - switch (err) { - case ENOENT: { - return COMPLETE_ROTTEN_SYMLINK_DESC; - } - case ELOOP: { - return COMPLETE_LOOP_SYMLINK_DESC; - } - default: { - // On unknown errors we do nothing. The file will be given the default 'File' - // description or one based on the suffix. - } - } + if (err == ENOENT) return COMPLETE_ROTTEN_SYMLINK_DESC; + if (err == ELOOP) return COMPLETE_LOOP_SYMLINK_DESC; + // On unknown errors we do nothing. The file will be given the default 'File' + // description or one based on the suffix. } else if (S_ISCHR(buf.st_mode)) { return COMPLETE_CHAR_DESC; } else if (S_ISBLK(buf.st_mode)) { From d9824272164c74ce50eabbb3ff2a95f6a93266e1 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 21:08:53 -0700 Subject: [PATCH 017/112] remove unused function The fish_key_reader program was the only user of the `set_wait_on_escape_ms()` function and that use was removed with commit 0461743. So remove it from the main fish code. This was found by `make lint`. --- src/input_common.cpp | 3 --- src/input_common.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/input_common.cpp b/src/input_common.cpp index b2efae06e..a82e801ce 100644 --- a/src/input_common.cpp +++ b/src/input_common.cpp @@ -158,9 +158,6 @@ static wint_t readb() { return arr[0]; } -// Directly set the input timeout. -void set_wait_on_escape_ms(int ms) { wait_on_escape_ms = ms; } - // Update the wait_on_escape_ms value in response to the fish_escape_delay_ms user variable being // set. void update_wait_on_escape_ms() { diff --git a/src/input_common.h b/src/input_common.h index 5b39d41ff..88e75c0fd 100644 --- a/src/input_common.h +++ b/src/input_common.h @@ -86,9 +86,6 @@ void input_common_destroy(); /// Adjust the escape timeout. void update_wait_on_escape_ms(); -/// Set the escape timeout directly. -void set_wait_on_escape_ms(int ms); - /// Function used by input_readch to read bytes from stdin until enough bytes have been read to /// convert them to a wchar_t. Conversion is done using mbrtowc. If a character has previously been /// read and then 'unread' using \c input_common_unreadch, that character is returned. If timed is From 25e0a39165a20c2f588249d1394187726d4eb3cc Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 21:14:01 -0700 Subject: [PATCH 018/112] fix bug introduced by lint cleanup commit 42458ff --- src/env_universal_common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 24ba53686..08134855e 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -1316,7 +1316,7 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { // it back. Nobody is expected to read it except us. int pid_nbo = htonl(getpid()); ssize_t amt_written = write(this->pipe_fd, &pid_nbo, sizeof pid_nbo); - if (amt_written < 0 && errno == EWOULDBLOCK || errno == EAGAIN) { + if (amt_written < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { // Very unsual: the pipe is full! drain_excessive_data(); } From a90b521eb43c9db5dc785717a542a099394e7855 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 21:28:46 -0700 Subject: [PATCH 019/112] lint: remove unused function --- src/path.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/path.cpp b/src/path.cpp index 0771e2ed7..2e83b8bb4 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -292,16 +292,6 @@ bool path_get_data(wcstring &path) { return !result.empty(); } -__attribute__((unused)) static void replace_all(wcstring &str, const wchar_t *needle, - const wchar_t *replacement) { - size_t needle_len = wcslen(needle); - size_t offset = 0; - while ((offset = str.find(needle, offset)) != wcstring::npos) { - str.replace(offset, needle_len, replacement); - offset += needle_len; - } -} - void path_make_canonical(wcstring &path) { // Ignore trailing slashes, unless it's the first character. size_t len = path.size(); From cdb82e45ac7651f3a7f1e6b057a32f862adf1293 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 22 Oct 2016 22:12:22 -0700 Subject: [PATCH 020/112] lint: remove another "too few branches in switch statement" --- src/reader.cpp | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/reader.cpp b/src/reader.cpp index 71d752bab..b5f9863b6 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2808,31 +2808,24 @@ const wchar_t *reader_readline(int nchars) { } } - switch (command_test_result) { - case 0: { - // Finished command, execute it. Don't add items that start with a leading - // space. - const editable_line_t *el = &data->command_line; - if (data->history != NULL && !el->empty() && el->text.at(0) != L' ') { - data->history->add_pending_with_file_detection(el->text); - } - finished = 1; - update_buff_pos(&data->command_line, data->command_line.size()); - reader_repaint(); - break; - } - case PARSER_TEST_INCOMPLETE: { - // We are incomplete, continue editing. - insert_char(el, '\n'); - break; - } - default: { - // Result must be some combination including an error. The error message - // will already be printed, all we need to do is repaint. - s_reset(&data->screen, screen_reset_abandon_line); - reader_repaint_needed(); - break; + if (command_test_result == 0) { + // Finished command, execute it. Don't add items that start with a leading + // space. + const editable_line_t *el = &data->command_line; + if (data->history != NULL && !el->empty() && el->text.at(0) != L' ') { + data->history->add_pending_with_file_detection(el->text); } + finished = 1; + update_buff_pos(&data->command_line, data->command_line.size()); + reader_repaint(); + } else if (command_test_result == PARSER_TEST_INCOMPLETE) { + // We are incomplete, continue editing. + insert_char(el, '\n'); + } else { + // Result must be some combination including an error. The error message will + // already be printed, all we need to do is repaint. + s_reset(&data->screen, screen_reset_abandon_line); + reader_repaint_needed(); } break; From 668de88e695e5d0d6a37ea46196ee52d8d378129 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sun, 23 Oct 2016 11:58:29 -0700 Subject: [PATCH 021/112] Supress fish_title only for Terminal.app VTE terminals apparently do not use the OSC sequence to compose title components. --- share/functions/__fish_config_interactive.fish | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 4f57c95c6..c7143dd65 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -220,14 +220,18 @@ function __fish_config_interactive -d "Initializations that should be performed # Notify terminals when $PWD changes (issue #906) # VTE and Terminal.app support this in practice. if test "0$VTE_VERSION" -ge 3405 -o "$TERM_PROGRAM" = "Apple_Terminal" - echo -n \e\]0\;\a # clear existing title - function fish_title; end function __update_cwd_osc --on-variable PWD --description 'Notify capable terminals when $PWD changes' status --is-command-substitution or test -n "$INSIDE_EMACS" and return printf \e\]7\;file://\%s\%s\a (hostname) (echo -n $PWD | __fish_urlencode) end + if test "$TERM_PROGRAM" = "Apple_Terminal" + # Suppress duplicative title display on Terminal.app + echo -n \e\]0\;\a # clear existing title + function fish_title + end + end __update_cwd_osc # Run once because we might have already inherited a PWD from an old tab end From 07de13f61f4fcfc979cc16237e7fb22b8856e9a1 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 23 Oct 2016 14:20:54 -0700 Subject: [PATCH 022/112] implement a fish_prompt_hostname function Standardize how the host name is included in the prompts that do so. Fixes #3480 --- share/functions/fish_fallback_prompt.fish | 7 +------ share/functions/fish_prompt.fish | 7 +------ share/tools/web_config/sample_prompts/classic.fish | 7 +------ .../web_config/sample_prompts/classic_status.fish | 7 +------ .../tools/web_config/sample_prompts/classic_vcs.fish | 12 +++--------- .../web_config/sample_prompts/debian_chroot.fish | 10 ++-------- .../tools/web_config/sample_prompts/informative.fish | 9 ++------- share/tools/web_config/sample_prompts/lonetwin.fish | 8 +------- share/tools/web_config/sample_prompts/nim.fish | 2 +- .../tools/web_config/sample_prompts/pythonista.fish | 2 +- .../web_config/sample_prompts/screen_savvy.fish | 4 ++-- share/tools/web_config/sample_prompts/sorin.fish | 2 +- share/tools/web_config/sample_prompts/terlar.fish | 2 +- .../web_config/sample_prompts/user_host_path.fish | 2 +- 14 files changed, 19 insertions(+), 62 deletions(-) diff --git a/share/functions/fish_fallback_prompt.fish b/share/functions/fish_fallback_prompt.fish index ae4fa0210..ec5bfb7d5 100644 --- a/share/functions/fish_fallback_prompt.fish +++ b/share/functions/fish_fallback_prompt.fish @@ -3,11 +3,6 @@ # Set the default prompt command. function fish_fallback_prompt --description "A simple fallback prompt without too much color or special characters for linux VTs" - # Just calculate this once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - set -l color_cwd set -l suffix switch $USER @@ -23,5 +18,5 @@ function fish_fallback_prompt --description "A simple fallback prompt without to set suffix '>' end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/functions/fish_prompt.fish b/share/functions/fish_prompt.fish index b4a350b8f..5a0e6243a 100644 --- a/share/functions/fish_prompt.fish +++ b/share/functions/fish_prompt.fish @@ -3,11 +3,6 @@ # Set the default prompt command. function fish_prompt --description "Write out the prompt" - # Just calculate this once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - set -l color_cwd set -l suffix switch $USER @@ -23,5 +18,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic.fish b/share/tools/web_config/sample_prompts/classic.fish index b092803e4..0be38222b 100644 --- a/share/tools/web_config/sample_prompts/classic.fish +++ b/share/tools/web_config/sample_prompts/classic.fish @@ -1,10 +1,5 @@ # name: Classic function fish_prompt --description "Write out the prompt" - # Just calculate this once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - set -l color_cwd set -l suffix switch $USER @@ -20,5 +15,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic_status.fish b/share/tools/web_config/sample_prompts/classic_status.fish index fe64f7934..a004d6073 100644 --- a/share/tools/web_config/sample_prompts/classic_status.fish +++ b/share/tools/web_config/sample_prompts/classic_status.fish @@ -10,11 +10,6 @@ function fish_prompt --description "Write out the prompt" printf "%s(%d)%s " (set_color red --bold) $last_status (set_color normal) end - # Just calculate this once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - set -l color_cwd set -l suffix switch $USER @@ -30,5 +25,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic_vcs.fish b/share/tools/web_config/sample_prompts/classic_vcs.fish index 755c95027..92513ef10 100644 --- a/share/tools/web_config/sample_prompts/classic_vcs.fish +++ b/share/tools/web_config/sample_prompts/classic_vcs.fish @@ -4,12 +4,6 @@ function fish_prompt --description 'Write out the prompt' set -l last_status $status - - # Just calculate this once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - set -l normal (set_color normal) # Hack; fish_config only copies the fish_prompt function (see #736) @@ -21,13 +15,13 @@ function fish_prompt --description 'Write out the prompt' commandline -f repaint ^/dev/null end end - + function __fish_repaint_host --on-variable fish_color_host --description "Event handler, repaint when fish_color_host changes" if status --is-interactive commandline -f repaint ^/dev/null end end - + function __fish_repaint_status --on-variable fish_color_status --description "Event handler; repaint when fish_color_status changes" if status --is-interactive commandline -f repaint ^/dev/null @@ -69,5 +63,5 @@ function fish_prompt --description 'Write out the prompt' set prompt_status ' ' (set_color $fish_color_status) "[$last_status]" "$normal" end - echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) "$__fish_prompt_hostname" $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " + echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) (fish_prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " end diff --git a/share/tools/web_config/sample_prompts/debian_chroot.fish b/share/tools/web_config/sample_prompts/debian_chroot.fish index 80acfa9a5..1f6fffe7f 100644 --- a/share/tools/web_config/sample_prompts/debian_chroot.fish +++ b/share/tools/web_config/sample_prompts/debian_chroot.fish @@ -2,12 +2,6 @@ # author: Maurizio De Santis function fish_prompt --description 'Write out the prompt, prepending the Debian chroot environment if present' - - # Just calculate these once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - if not set -q __fish_prompt_normal set -g __fish_prompt_normal (set_color normal) end @@ -41,7 +35,7 @@ function fish_prompt --description 'Write out the prompt, prepending the Debian end end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' case '*' @@ -49,7 +43,7 @@ function fish_prompt --description 'Write out the prompt, prepending the Debian set -g __fish_prompt_cwd (set_color $fish_color_cwd) end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' end end diff --git a/share/tools/web_config/sample_prompts/informative.fish b/share/tools/web_config/sample_prompts/informative.fish index 749d81713..40df49e7e 100644 --- a/share/tools/web_config/sample_prompts/informative.fish +++ b/share/tools/web_config/sample_prompts/informative.fish @@ -6,11 +6,6 @@ function fish_prompt --description 'Write out the prompt' #Save the return status of the previous command set stat $status -# Just calculate these once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname|cut -d . -f 1) - end - if not set -q __fish_prompt_normal set -g __fish_prompt_normal (set_color normal) end @@ -37,7 +32,7 @@ if not set -q __fish_prompt_cwd end end -printf '%s@%s %s%s%s# ' $USER $__fish_prompt_hostname "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" +printf '%s@%s %s%s%s# ' $USER (fish_prompt_hostname) "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" case '*' @@ -45,7 +40,7 @@ if not set -q __fish_prompt_cwd set -g __fish_prompt_cwd (set_color $fish_color_cwd) end -printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER $__fish_prompt_hostname "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" +printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER (fish_prompt_hostname) "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" end end diff --git a/share/tools/web_config/sample_prompts/lonetwin.fish b/share/tools/web_config/sample_prompts/lonetwin.fish index d22beff41..4b448d313 100644 --- a/share/tools/web_config/sample_prompts/lonetwin.fish +++ b/share/tools/web_config/sample_prompts/lonetwin.fish @@ -2,11 +2,6 @@ # author: Steve function fish_prompt --description 'Write out the prompt' - # Just calculate these once, to save a few cycles when displaying the prompt - if not set -q __fish_prompt_hostname - set -g __fish_prompt_hostname (hostname -s) - end - if not set -q __fish_prompt_normal set -g __fish_prompt_normal (set_color normal) end @@ -15,6 +10,5 @@ function fish_prompt --description 'Write out the prompt' set -g __fish_prompt_cwd (set_color $fish_color_cwd) end - echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' - + echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' end diff --git a/share/tools/web_config/sample_prompts/nim.fish b/share/tools/web_config/sample_prompts/nim.fish index 5d2dac394..e9392e13f 100644 --- a/share/tools/web_config/sample_prompts/nim.fish +++ b/share/tools/web_config/sample_prompts/nim.fish @@ -26,7 +26,7 @@ function fish_prompt else set_color -o cyan end - echo -n (hostname) + echo -n (fish_prompt_hostname) set_color -o white #echo -n :(prompt_pwd) echo -n :(pwd|sed "s=$HOME=~=") diff --git a/share/tools/web_config/sample_prompts/pythonista.fish b/share/tools/web_config/sample_prompts/pythonista.fish index ad772e2f7..d4597a25d 100644 --- a/share/tools/web_config/sample_prompts/pythonista.fish +++ b/share/tools/web_config/sample_prompts/pythonista.fish @@ -12,7 +12,7 @@ function fish_prompt printf ' at ' set_color magenta - printf '%s' (hostname|cut -d . -f 1) + echo -n (fish_prompt_hostname) set_color normal printf ' in ' diff --git a/share/tools/web_config/sample_prompts/screen_savvy.fish b/share/tools/web_config/sample_prompts/screen_savvy.fish index 83c7db641..c75b81466 100644 --- a/share/tools/web_config/sample_prompts/screen_savvy.fish +++ b/share/tools/web_config/sample_prompts/screen_savvy.fish @@ -2,8 +2,8 @@ # author: Matthias function fish_prompt -d "Write out the prompt" if test -z $WINDOW - printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (fish_prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) else - printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (hostname|cut -d . -f 1) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (fish_prompt_hostname) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) end end diff --git a/share/tools/web_config/sample_prompts/sorin.fish b/share/tools/web_config/sample_prompts/sorin.fish index cab4b8c58..ad0c89b9d 100644 --- a/share/tools/web_config/sample_prompts/sorin.fish +++ b/share/tools/web_config/sample_prompts/sorin.fish @@ -2,7 +2,7 @@ # author: Ivan Tham function fish_prompt - test $SSH_TTY; and printf (set_color red)(whoami)(set_color white)'@'(set_color yellow)(hostname)' ' + test $SSH_TTY; and printf (set_color red)(whoami)(set_color white)'@'(set_color yellow)(fish_prompt_hostname)' ' test $USER = 'root'; and echo (set_color red)"#" diff --git a/share/tools/web_config/sample_prompts/terlar.fish b/share/tools/web_config/sample_prompts/terlar.fish index d75b17b58..612d50ac5 100644 --- a/share/tools/web_config/sample_prompts/terlar.fish +++ b/share/tools/web_config/sample_prompts/terlar.fish @@ -13,7 +13,7 @@ function fish_prompt --description 'Write out the prompt' # Host set_color $fish_color_host - echo -n (hostname -s) + echo -n (fish_prompt_hostname) set_color normal echo -n ':' diff --git a/share/tools/web_config/sample_prompts/user_host_path.fish b/share/tools/web_config/sample_prompts/user_host_path.fish index de917ee71..b4a1be6a1 100644 --- a/share/tools/web_config/sample_prompts/user_host_path.fish +++ b/share/tools/web_config/sample_prompts/user_host_path.fish @@ -9,5 +9,5 @@ function fish_prompt -d "Write out the prompt" case root toor; set prompt_symbol '#' case '*'; set prompt_symbol '$' end - printf "[%s@%s %s%s%s]%s " $USER (hostname -s) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol + printf "[%s@%s %s%s%s]%s " $USER (fish_prompt_hostname) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol end From 8dfee7ff76b3eff03ea502173230adf2171ed253 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 23 Oct 2016 14:56:18 -0700 Subject: [PATCH 023/112] add new file to change --- share/functions/fish_prompt_hostname.fish | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 share/functions/fish_prompt_hostname.fish diff --git a/share/functions/fish_prompt_hostname.fish b/share/functions/fish_prompt_hostname.fish new file mode 100644 index 000000000..be9fba9dc --- /dev/null +++ b/share/functions/fish_prompt_hostname.fish @@ -0,0 +1,10 @@ +# Fetching the host name can be expensive if there is a problem with DNS or whatever subsystem the +# hostname command uses. So cache the answer so including it in the prompt doesn't make fish seem +# slow. +if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname | string split '.')[1] +end + +function fish_prompt_hostname + echo $__fish_prompt_hostname +end From 37d91d0c293ded842c2e14c854dbc544df605f8b Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 23 Oct 2016 15:02:14 -0700 Subject: [PATCH 024/112] change name of the function --- share/functions/fish_fallback_prompt.fish | 2 +- share/functions/fish_prompt.fish | 2 +- .../{fish_prompt_hostname.fish => prompt_hostname.fish} | 2 +- share/tools/web_config/sample_prompts/classic.fish | 2 +- share/tools/web_config/sample_prompts/classic_status.fish | 2 +- share/tools/web_config/sample_prompts/classic_vcs.fish | 2 +- share/tools/web_config/sample_prompts/debian_chroot.fish | 4 ++-- share/tools/web_config/sample_prompts/informative.fish | 4 ++-- share/tools/web_config/sample_prompts/lonetwin.fish | 2 +- share/tools/web_config/sample_prompts/nim.fish | 2 +- share/tools/web_config/sample_prompts/pythonista.fish | 2 +- share/tools/web_config/sample_prompts/screen_savvy.fish | 4 ++-- share/tools/web_config/sample_prompts/sorin.fish | 2 +- share/tools/web_config/sample_prompts/terlar.fish | 2 +- share/tools/web_config/sample_prompts/user_host_path.fish | 2 +- 15 files changed, 18 insertions(+), 18 deletions(-) rename share/functions/{fish_prompt_hostname.fish => prompt_hostname.fish} (92%) diff --git a/share/functions/fish_fallback_prompt.fish b/share/functions/fish_fallback_prompt.fish index ec5bfb7d5..1910eeaea 100644 --- a/share/functions/fish_fallback_prompt.fish +++ b/share/functions/fish_fallback_prompt.fish @@ -18,5 +18,5 @@ function fish_fallback_prompt --description "A simple fallback prompt without to set suffix '>' end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/functions/fish_prompt.fish b/share/functions/fish_prompt.fish index 5a0e6243a..7f8581971 100644 --- a/share/functions/fish_prompt.fish +++ b/share/functions/fish_prompt.fish @@ -18,5 +18,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/functions/fish_prompt_hostname.fish b/share/functions/prompt_hostname.fish similarity index 92% rename from share/functions/fish_prompt_hostname.fish rename to share/functions/prompt_hostname.fish index be9fba9dc..4348bce21 100644 --- a/share/functions/fish_prompt_hostname.fish +++ b/share/functions/prompt_hostname.fish @@ -5,6 +5,6 @@ if not set -q __fish_prompt_hostname set -g __fish_prompt_hostname (hostname | string split '.')[1] end -function fish_prompt_hostname +function prompt_hostname echo $__fish_prompt_hostname end diff --git a/share/tools/web_config/sample_prompts/classic.fish b/share/tools/web_config/sample_prompts/classic.fish index 0be38222b..4310d9594 100644 --- a/share/tools/web_config/sample_prompts/classic.fish +++ b/share/tools/web_config/sample_prompts/classic.fish @@ -15,5 +15,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic_status.fish b/share/tools/web_config/sample_prompts/classic_status.fish index a004d6073..d180a4d74 100644 --- a/share/tools/web_config/sample_prompts/classic_status.fish +++ b/share/tools/web_config/sample_prompts/classic_status.fish @@ -25,5 +25,5 @@ function fish_prompt --description "Write out the prompt" set suffix '>' end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic_vcs.fish b/share/tools/web_config/sample_prompts/classic_vcs.fish index 92513ef10..683e91778 100644 --- a/share/tools/web_config/sample_prompts/classic_vcs.fish +++ b/share/tools/web_config/sample_prompts/classic_vcs.fish @@ -63,5 +63,5 @@ function fish_prompt --description 'Write out the prompt' set prompt_status ' ' (set_color $fish_color_status) "[$last_status]" "$normal" end - echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) (fish_prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " + echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) (prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " end diff --git a/share/tools/web_config/sample_prompts/debian_chroot.fish b/share/tools/web_config/sample_prompts/debian_chroot.fish index 1f6fffe7f..a1666ea97 100644 --- a/share/tools/web_config/sample_prompts/debian_chroot.fish +++ b/share/tools/web_config/sample_prompts/debian_chroot.fish @@ -35,7 +35,7 @@ function fish_prompt --description 'Write out the prompt, prepending the Debian end end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' case '*' @@ -43,7 +43,7 @@ function fish_prompt --description 'Write out the prompt, prepending the Debian set -g __fish_prompt_cwd (set_color $fish_color_cwd) end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' end end diff --git a/share/tools/web_config/sample_prompts/informative.fish b/share/tools/web_config/sample_prompts/informative.fish index 40df49e7e..41468b39e 100644 --- a/share/tools/web_config/sample_prompts/informative.fish +++ b/share/tools/web_config/sample_prompts/informative.fish @@ -32,7 +32,7 @@ if not set -q __fish_prompt_cwd end end -printf '%s@%s %s%s%s# ' $USER (fish_prompt_hostname) "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" +printf '%s@%s %s%s%s# ' $USER (prompt_hostname) "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" case '*' @@ -40,7 +40,7 @@ if not set -q __fish_prompt_cwd set -g __fish_prompt_cwd (set_color $fish_color_cwd) end -printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER (fish_prompt_hostname) "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" +printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER (prompt_hostname) "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" end end diff --git a/share/tools/web_config/sample_prompts/lonetwin.fish b/share/tools/web_config/sample_prompts/lonetwin.fish index 4b448d313..cd4abfdc8 100644 --- a/share/tools/web_config/sample_prompts/lonetwin.fish +++ b/share/tools/web_config/sample_prompts/lonetwin.fish @@ -10,5 +10,5 @@ function fish_prompt --description 'Write out the prompt' set -g __fish_prompt_cwd (set_color $fish_color_cwd) end - echo -n -s "$USER" @ (fish_prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' end diff --git a/share/tools/web_config/sample_prompts/nim.fish b/share/tools/web_config/sample_prompts/nim.fish index e9392e13f..ef3de3242 100644 --- a/share/tools/web_config/sample_prompts/nim.fish +++ b/share/tools/web_config/sample_prompts/nim.fish @@ -26,7 +26,7 @@ function fish_prompt else set_color -o cyan end - echo -n (fish_prompt_hostname) + echo -n (prompt_hostname) set_color -o white #echo -n :(prompt_pwd) echo -n :(pwd|sed "s=$HOME=~=") diff --git a/share/tools/web_config/sample_prompts/pythonista.fish b/share/tools/web_config/sample_prompts/pythonista.fish index d4597a25d..6607e5b87 100644 --- a/share/tools/web_config/sample_prompts/pythonista.fish +++ b/share/tools/web_config/sample_prompts/pythonista.fish @@ -12,7 +12,7 @@ function fish_prompt printf ' at ' set_color magenta - echo -n (fish_prompt_hostname) + echo -n (prompt_hostname) set_color normal printf ' in ' diff --git a/share/tools/web_config/sample_prompts/screen_savvy.fish b/share/tools/web_config/sample_prompts/screen_savvy.fish index c75b81466..3d72178ec 100644 --- a/share/tools/web_config/sample_prompts/screen_savvy.fish +++ b/share/tools/web_config/sample_prompts/screen_savvy.fish @@ -2,8 +2,8 @@ # author: Matthias function fish_prompt -d "Write out the prompt" if test -z $WINDOW - printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (fish_prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) else - printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (fish_prompt_hostname) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) end end diff --git a/share/tools/web_config/sample_prompts/sorin.fish b/share/tools/web_config/sample_prompts/sorin.fish index ad0c89b9d..0608047f2 100644 --- a/share/tools/web_config/sample_prompts/sorin.fish +++ b/share/tools/web_config/sample_prompts/sorin.fish @@ -2,7 +2,7 @@ # author: Ivan Tham function fish_prompt - test $SSH_TTY; and printf (set_color red)(whoami)(set_color white)'@'(set_color yellow)(fish_prompt_hostname)' ' + test $SSH_TTY; and printf (set_color red)(whoami)(set_color white)'@'(set_color yellow)(prompt_hostname)' ' test $USER = 'root'; and echo (set_color red)"#" diff --git a/share/tools/web_config/sample_prompts/terlar.fish b/share/tools/web_config/sample_prompts/terlar.fish index 612d50ac5..c8dfefc39 100644 --- a/share/tools/web_config/sample_prompts/terlar.fish +++ b/share/tools/web_config/sample_prompts/terlar.fish @@ -13,7 +13,7 @@ function fish_prompt --description 'Write out the prompt' # Host set_color $fish_color_host - echo -n (fish_prompt_hostname) + echo -n (prompt_hostname) set_color normal echo -n ':' diff --git a/share/tools/web_config/sample_prompts/user_host_path.fish b/share/tools/web_config/sample_prompts/user_host_path.fish index b4a1be6a1..c7483b6a0 100644 --- a/share/tools/web_config/sample_prompts/user_host_path.fish +++ b/share/tools/web_config/sample_prompts/user_host_path.fish @@ -9,5 +9,5 @@ function fish_prompt -d "Write out the prompt" case root toor; set prompt_symbol '#' case '*'; set prompt_symbol '$' end - printf "[%s@%s %s%s%s]%s " $USER (fish_prompt_hostname) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol + printf "[%s@%s %s%s%s]%s " $USER (prompt_hostname) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol end From 2bb52c65c2afc449da8b55ded82e271116bd13d8 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Mon, 24 Oct 2016 17:13:39 -0700 Subject: [PATCH 025/112] fix bug introduced by 42458ff7 There was one block of code modified by commit 42458ff7 that had convoluted, inverted, logic. In the process of collapsing nested "if" blocks the logic was modified to avoid using "!" everywhere the bool was tested. Unfortunately I neglected to modify two of the conditions used to set that var to reflect the changed polarity. --- src/parse_util.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parse_util.cpp b/src/parse_util.cpp index a394425be..f0a7f37c5 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -470,7 +470,7 @@ static wchar_t get_quote(const wcstring &cmd_str, size_t len) { void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_t *quote, size_t *offset, enum token_type *out_type) { size_t prev_pos = 0; - wchar_t last_quote = '\0'; + wchar_t last_quote = L'\0'; tokenizer_t tok(cmd.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS); tok_t token; @@ -487,11 +487,11 @@ void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_ wchar_t *cmd_tmp = wcsdup(cmd.c_str()); cmd_tmp[pos] = 0; size_t cmdlen = wcslen(cmd_tmp); - bool finished = (cmdlen != 0); + bool finished = cmdlen != 0; if (finished) { finished = (quote == NULL); - if (finished && wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1]) == 0) { - finished = (cmdlen == 1) || (cmd_tmp[cmdlen - 2] != L'\\'); + if (finished && wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1]) != L'\0') { + finished = cmdlen > 1 && cmd_tmp[cmdlen - 2] == L'\\'; } } From 075be74cc4252a60df0ef24a4d68d064896b1344 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 25 Oct 2016 20:56:15 -0700 Subject: [PATCH 026/112] fix regression introduced by commit 851e449 My earlier attempt with commit 851e449 to eliminate all the compiler warnings about mixing signed and unsigned ints in an expression introduced a subtle bug. This fixes that mistake. Fixes #3488 --- src/pager.cpp | 12 ++++++------ src/pager.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pager.cpp b/src/pager.cpp index b6663a24b..0c9a37606 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -84,16 +84,15 @@ static int print_max(const wcstring &str, highlight_spec_t color, int max, bool /// Print the specified item using at the specified amount of space. line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, - size_t column, size_t width, bool secondary, bool selected, + size_t column, int width, bool secondary, bool selected, page_rendering_t *rendering) const { UNUSED(column); UNUSED(row); UNUSED(rendering); - size_t comp_width = 0, desc_width = 0; - size_t written = 0; + int comp_width, desc_width; line_t line_data; - if (c->pref_width <= (size_t)width) { + if (c->pref_width <= width) { // The entry fits, we give it as much space as it wants. comp_width = c->comp_width; desc_width = c->desc_width; @@ -102,8 +101,8 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s // the space to the completion, and whatever is left to the description. int desc_all = c->desc_width ? c->desc_width + 4 : 0; - comp_width = maxi(mini(c->comp_width, 2 * (width - 4) / 3), width - desc_all); - if (c->desc_width) desc_width = width - comp_width - 4; + comp_width = maxi(mini((int)c->comp_width, 2 * (width - 4) / 3), width - desc_all); + desc_width = c->desc_width ? width - 4 - comp_width : 0; } int bg_color = secondary ? highlight_spec_pager_secondary : highlight_spec_normal; @@ -111,6 +110,7 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s bg_color = highlight_spec_search_match; } + int written = 0; for (size_t i = 0; i < c->comp.size(); i++) { const wcstring &comp = c->comp.at(i); diff --git a/src/pager.h b/src/pager.h index 3f7bfce0d..1376e51e7 100644 --- a/src/pager.h +++ b/src/pager.h @@ -114,7 +114,7 @@ class pager_t { const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering) const; line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column, - size_t width, bool secondary, bool selected, + int width, bool secondary, bool selected, page_rendering_t *rendering) const; public: From 56679d477628db69be7b3ceb1ebcabb5cff739b6 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Wed, 26 Oct 2016 15:48:42 +0200 Subject: [PATCH 027/112] Don't use open function if a command exists Turns out this is also the case on Haiku. It also eliminates a fork. Closes #3487. --- doc_src/open.txt | 2 ++ share/functions/open.fish | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc_src/open.txt b/doc_src/open.txt index c81c3c9a1..7207fc172 100644 --- a/doc_src/open.txt +++ b/doc_src/open.txt @@ -9,6 +9,8 @@ open FILES... `open` opens a file in its default application, using the appropriate tool for the operating system. On GNU/Linux, this requires the common but optional `xdg-open` utility, from the `xdg-utils` package. +Note that this function will not be used if a command by this name exists (which is the case on macOS or Haiku). + \subsection open-example Example diff --git a/share/functions/open.fish b/share/functions/open.fish index 533b3df19..9eaa7eda6 100644 --- a/share/functions/open.fish +++ b/share/functions/open.fish @@ -3,7 +3,7 @@ # application for the file. # -if not test (uname) = Darwin +if not command -s open >/dev/null function open --description "Open file in default application" if count $argv >/dev/null switch $argv[1] From 7ea2dc448819b4a1cb7c846554754d8785a421e0 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Thu, 27 Oct 2016 10:16:57 +0200 Subject: [PATCH 028/112] Disable vi-cursor on xterm < 282 Fixes #3499. @zanchey: This is for integration-2.4.0. --- share/functions/fish_vi_cursor.fish | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/share/functions/fish_vi_cursor.fish b/share/functions/fish_vi_cursor.fish index be04eb430..47fa7467b 100644 --- a/share/functions/fish_vi_cursor.fish +++ b/share/functions/fish_vi_cursor.fish @@ -6,6 +6,17 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' and not set -q TMUX return end + + # XTerm supports this sequence since version 282 + if test -n "$XTERM_VERSION" + # This will fail if $XTERM_VERSION is not in the "XTerm($version)" format. + # In that case, we cannot determine the terminal and should stop + # so "[1 q" does not show up on the user's screen + if not test (string replace -r 'XTerm\((\d*)\)' '$1' -- $XTERM_VERSION) -ge 282 + return + end + end + set -l terminal $argv[1] set -q terminal[1] or set terminal auto From f382fa8e8aea136428e9c933a39aa0ff8d622704 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 23 Oct 2016 13:58:12 -0700 Subject: [PATCH 029/112] lint: multiple unary operator --- src/builtin.cpp | 2 +- src/builtin_test.cpp | 2 +- src/common.cpp | 6 +++--- src/complete.cpp | 2 +- src/env.cpp | 2 +- src/exec.cpp | 2 +- src/function.cpp | 2 +- src/parse_execution.cpp | 4 ++-- src/parse_tree.cpp | 6 +++--- src/parser.cpp | 4 ++-- src/reader.cpp | 2 +- src/signal.cpp | 2 +- src/wildcard.cpp | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 104a07e40..5902a79c9 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -3228,7 +3228,7 @@ void builtin_init() { void builtin_destroy() {} /// Is there a builtin command with the given name? -bool builtin_exists(const wcstring &cmd) { return !!builtin_lookup(cmd); } +bool builtin_exists(const wcstring &cmd) { return static_cast(builtin_lookup(cmd)); } /// If builtin takes care of printing help itself static bool builtin_handles_help(const wchar_t *cmd) { diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp index 9d8744d35..942ddc2f7 100644 --- a/src/builtin_test.cpp +++ b/src/builtin_test.cpp @@ -590,7 +590,7 @@ bool unary_operator::evaluate(wcstring_list_t &errors) { bool combining_expression::evaluate(wcstring_list_t &errors) { if (token == test_combine_and || token == test_combine_or) { - assert(!subjects.empty()); + assert(!subjects.empty()); //!OCLINT(multiple unary operator) assert(combiners.size() + 1 == subjects.size()); // One-element case. diff --git a/src/common.cpp b/src/common.cpp index 9740b0ce2..d5bd5ee38 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1753,7 +1753,7 @@ void assert_is_locked(void *vmutex, const char *who, const char *caller) { } void scoped_lock::lock(void) { - assert(!locked); + assert(!locked); //!OCLINT(multiple unary operator) ASSERT_IS_NOT_FORKED_CHILD(); VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_lock(lock_obj)); locked = true; @@ -1777,7 +1777,7 @@ scoped_lock::~scoped_lock() { } void scoped_rwlock::lock(void) { - assert(!(locked || locked_shared)); + assert(!(locked || locked_shared)); //!OCLINT(multiple unary operator) ASSERT_IS_NOT_FORKED_CHILD(); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_rdlock(rwlock_obj)); locked = true; @@ -1791,7 +1791,7 @@ void scoped_rwlock::unlock(void) { } void scoped_rwlock::lock_shared(void) { - assert(!(locked || locked_shared)); + assert(!(locked || locked_shared)); //!OCLINT(multiple unary operator) ASSERT_IS_NOT_FORKED_CHILD(); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_wrlock(rwlock_obj)); locked_shared = true; diff --git a/src/complete.cpp b/src/complete.cpp index b580ece60..8cf1a4041 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -1534,7 +1534,7 @@ wcstring complete_print() { break; } case option_type_short: { - assert(!o->option.empty()); + assert(!o->option.empty()); //!OCLINT(multiple unary operator) append_format(out, L" --short-option '%lc'", o->option.at(0)); break; } diff --git a/src/env.cpp b/src/env.cpp index 8c588c7b8..75784624c 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -714,7 +714,7 @@ int env_remove(const wcstring &key, int var_mode) { } const wchar_t *env_var_t::c_str(void) const { - assert(!is_missing); + assert(!is_missing); //!OCLINT(multiple unary operator) return wcstring::c_str(); } diff --git a/src/exec.cpp b/src/exec.cpp index b37d4f835..63d5a4d2e 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -406,7 +406,7 @@ void exec_job(parser_t &parser, job_t *j) { if ((io->io_mode == IO_BUFFER)) { io_buffer_t *io_buffer = static_cast(io.get()); - assert(!io_buffer->is_input); + assert(!io_buffer->is_input); //!OCLINT(multiple unary operator) } } diff --git a/src/function.cpp b/src/function.cpp index 6ca086aba..ffd117d5e 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -161,7 +161,7 @@ void function_add(const function_data_t &data, const parser_t &parser, int defin UNUSED(parser); ASSERT_IS_MAIN_THREAD(); - CHECK(!data.name.empty(), ); + CHECK(!data.name.empty(), ); //!OCLINT(multiple unary operator) CHECK(data.definition, ); scoped_lock locker(functions_lock); diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index b52dbfd7f..69bd85632 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -1184,7 +1184,7 @@ parse_execution_result_t parse_execution_context_t::populate_job_from_job_node( // Return what happened. if (result == parse_execution_success) { // Link up the processes. - assert(!processes.empty()); + assert(!processes.empty()); //!OCLINT(multiple unary operator) j->first_process = processes.at(0); for (size_t i = 1; i < processes.size(); i++) { processes.at(i - 1)->next = processes.at(i); @@ -1368,7 +1368,7 @@ parse_execution_result_t parse_execution_context_t::run_job_list(const parse_nod parse_execution_result_t parse_execution_context_t::eval_node_at_offset( node_offset_t offset, const block_t *associated_block, const io_chain_t &io) { // Don't ever expect to have an empty tree if this is called. - assert(!tree.empty()); + assert(!tree.empty()); //!OCLINT(multiple unary operator) assert(offset < tree.size()); // Apply this block IO for the duration of this function. diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 75db04fe5..cbe6436aa 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -475,7 +475,7 @@ class parse_ll_t { /// Get the node corresponding to the top element of the stack. parse_node_t &node_for_top_symbol() { - PARSE_ASSERT(!symbol_stack.empty()); + PARSE_ASSERT(!symbol_stack.empty()); //!OCLINT(multiple unary operator) const parse_stack_element_t &top_symbol = symbol_stack.back(); PARSE_ASSERT(top_symbol.node_idx != NODE_OFFSET_INVALID); PARSE_ASSERT(top_symbol.node_idx < nodes.size()); @@ -912,7 +912,7 @@ bool parse_ll_t::report_error_for_unclosed_block() { } bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) { - PARSE_ASSERT(!symbol_stack.empty()); + PARSE_ASSERT(!symbol_stack.empty()); //!OCLINT(multiple unary operator) PARSE_ASSERT(token.type >= FIRST_PARSE_TOKEN_TYPE); bool handled = false; parse_stack_element_t &stack_top = symbol_stack.back(); @@ -1031,7 +1031,7 @@ void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) { } while (!consumed && !this->fatal_errored) { - PARSE_ASSERT(!symbol_stack.empty()); + PARSE_ASSERT(!symbol_stack.empty()); //!OCLINT(multiple unary operator) if (top_node_handle_terminal_types(token1)) { if (logit) { diff --git a/src/parser.cpp b/src/parser.cpp index d81ccac77..9406b3b9f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -344,7 +344,7 @@ void parser_t::expand_argument_list(const wcstring &arg_list_src, expand_flags_t } // Get the root argument list. - assert(!tree.empty()); + assert(!tree.empty()); //!OCLINT(multiple unary operator) const parse_node_t *arg_list = &tree.at(0); assert(arg_list->type == symbol_freestanding_argument_list); @@ -725,7 +725,7 @@ bool parser_t::detect_errors_in_argument_list(const wcstring &arg_list_src, wcst if (!errored) { // Get the root argument list. - assert(!tree.empty()); + assert(!tree.empty()); //!OCLINT(multiple unary operator) const parse_node_t *arg_list = &tree.at(0); assert(arg_list->type == symbol_freestanding_argument_list); diff --git a/src/reader.cpp b/src/reader.cpp index b5f9863b6..859500233 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -3284,7 +3284,7 @@ int reader_search_mode() { if (!data) { return -1; } - return !!data->search_mode; + return data->search_mode == NO_SEARCH ? 0 : 1; } int reader_has_pager_contents() { diff --git a/src/signal.cpp b/src/signal.cpp index a20f51cc4..a718d250e 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -403,4 +403,4 @@ void signal_unblock() { // debug( 0, L"signal block level decreased to %d", block_count ); } -bool signal_is_blocked() { return !!block_count; } +bool signal_is_blocked() { return static_cast(block_count); } diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 59256a2c1..ffd0e6273 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -489,7 +489,7 @@ class wildcard_expander_t { void add_expansion_result(const wcstring &result) { // This function is only for the non-completions case. - assert(!static_cast(this->flags & EXPAND_FOR_COMPLETIONS)); + assert(!static_cast(this->flags & EXPAND_FOR_COMPLETIONS)); //!OCLINT(multiple unary operator) if (this->completion_set.insert(result).second) { append_completion(this->resolved_completions, result); this->did_add = true; @@ -799,7 +799,7 @@ void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc, if (wc_segment.empty()) { // Handle empty segment. - assert(!segment_has_wildcards); + assert(!segment_has_wildcards); //!OCLINT(multiple unary operator) if (is_last_segment) { this->expand_trailing_slash(base_dir, effective_prefix); } else { From 2d46969d3eb20a06134c2be2d8d0caae0bd2e674 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 28 Oct 2016 14:42:57 -0700 Subject: [PATCH 030/112] alias: identify as alias in description. Like so: ~ $ alias foo=bar ~ $ functions foo function foo --description 'alias foo=bar' bar $argv; end --- share/functions/alias.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/alias.fish b/share/functions/alias.fish index 6a4973823..811214c1d 100644 --- a/share/functions/alias.fish +++ b/share/functions/alias.fish @@ -60,5 +60,5 @@ function alias --description 'Legacy function for creating shellscript functions set prefix command end end - echo "function $name --wraps $first_word; $prefix $first_word $body \$argv; end" | source + echo "function $name --wraps $first_word --description \"alias $argv\"; $prefix $first_word $body \$argv; end" | source end From 4a2aed1f8e629265af2c4250b7d5a633f263ddfb Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 28 Oct 2016 17:42:50 -0700 Subject: [PATCH 031/112] lint: unnecessary else statement --- src/autoload.cpp | 4 ++-- src/builtin.cpp | 10 +++++----- src/function.cpp | 4 ++-- src/path.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/autoload.cpp b/src/autoload.cpp index 37ca2b8f1..d97352b02 100644 --- a/src/autoload.cpp +++ b/src/autoload.cpp @@ -313,7 +313,7 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_ if (really_load) { return reloaded; - } else { - return found_file || has_script_source; } + + return found_file || has_script_source; } diff --git a/src/builtin.cpp b/src/builtin.cpp index 5902a79c9..7efd57e3b 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -1886,12 +1886,12 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) argv[0], w.woptarg); builtin_print_help(parser, streams, argv[0], streams.err); return STATUS_BUILTIN_ERROR; - } else { - streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), - argv[0], w.woptarg); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; } + + streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), + argv[0], w.woptarg); + builtin_print_help(parser, streams, argv[0], streams.err); + return STATUS_BUILTIN_ERROR; } break; } diff --git a/src/function.cpp b/src/function.cpp index ffd117d5e..3f303a468 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -272,9 +272,9 @@ bool function_get_desc(const wcstring &name, wcstring *out_desc) { if (out_desc && func && !func->description.empty()) { out_desc->assign(_(func->description.c_str())); return true; - } else { - return false; } + + return false; } void function_set_desc(const wcstring &name, const wcstring &desc) { diff --git a/src/path.cpp b/src/path.cpp index 2e83b8bb4..f9551d3b9 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -370,7 +370,7 @@ bool paths_are_same_file(const wcstring &path1, const wcstring &path2) { struct stat s1, s2; if (wstat(path1, &s1) == 0 && wstat(path2, &s2) == 0) { return s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev; - } else { - return false; } + + return false; } From 41f1232cf943f98242477135073af63e866c3eaa Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 28 Oct 2016 17:52:56 -0700 Subject: [PATCH 032/112] disable oclint BitwiseOperatorInConditional warning --- .oclint | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.oclint b/.oclint index 5eea63aea..8bd3df49a 100644 --- a/.oclint +++ b/.oclint @@ -58,3 +58,10 @@ disable-rules: # especially in the context of assert statements. So disable this rule. # - DoubleNegative + # + # Avoiding bitwise operators in a conditional is a good idea with one + # exception: testing whether a bit flag is set. Which happens to be the + # only time you'll see something like `if (j->flags & JOB_CONSTRUCTED)` + # in fish source. + # + - BitwiseOperatorInConditional From b663b0e818fbc13bd6717adae09933c1a8650197 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 28 Oct 2016 19:15:05 -0700 Subject: [PATCH 033/112] lint: redundant if statement --- src/autoload.cpp | 33 ++++++++++++++++----------------- src/path.cpp | 8 +------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/autoload.cpp b/src/autoload.cpp index d97352b02..c84606081 100644 --- a/src/autoload.cpp +++ b/src/autoload.cpp @@ -157,6 +157,19 @@ autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcs return func; } +static bool use_cached(autoload_function_t *func, bool really_load, bool allow_stale_functions) { + if (!func) { + return false; // can't use a function that doesn't exist + } + if (really_load && !func->is_placeholder && !func->is_loaded) { + return false; // can't use an unloaded function + } + if (!allow_stale_functions && is_stale(func)) { + return false; // can't use a stale function + } + return true; // I guess we can use it +} + /// This internal helper function does all the real work. By using two functions, the internal /// function can return on various places in the code, and the caller can take care of various /// cleanup work. @@ -169,35 +182,21 @@ autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcs bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload, const wcstring_list_t &path_list) { // Note that we are NOT locked in this function! - bool reloaded = 0; + bool reloaded = false; // Try using a cached function. If we really want the function to be loaded, require that it be // really loaded. If we're not reloading, allow stale functions. { bool allow_stale_functions = !reload; - scoped_lock locker(lock); autoload_function_t *func = this->get_node(cmd); // get the function - // Determine if we can use this cached function. - bool use_cached; - if (!func) { - // Can't use a function that doesn't exist. - use_cached = false; - } else if (really_load && !func->is_placeholder && !func->is_loaded) { - use_cached = false; // can't use an unloaded function - } else if (!allow_stale_functions && is_stale(func)) { - use_cached = false; // can't use a stale function - } else { - use_cached = true; // I guess we can use it - } - // If we can use this function, return whether we were able to access it. - if (use_cached) { - assert(func != NULL); + if (use_cached(func, really_load, allow_stale_functions)) { return func->is_internalized || func->access.accessible; } } + // The source of the script will end up here. wcstring script_source; bool has_script_source = false; diff --git a/src/path.cpp b/src/path.cpp index f9551d3b9..2a71680ca 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -189,13 +189,7 @@ wcstring path_apply_working_directory(const wcstring &path, const wcstring &work // We're going to make sure that if we want to prepend the wd, that the string has no leading // "/". - bool prepend_wd; - if (path.at(0) == L'/' || path.at(0) == HOME_DIRECTORY) { - prepend_wd = false; - } else { - prepend_wd = true; - } - + bool prepend_wd = path.at(0) != L'/' && path.at(0) != HOME_DIRECTORY; if (!prepend_wd) { // No need to prepend the wd, so just return the path we were given. return path; From c4bd110fcae7ae2b132905f4af5b5496f1c83b19 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 28 Oct 2016 22:29:02 -0700 Subject: [PATCH 034/112] List alias-created functions on `alias` sans args The previous change I made here makes this not hard to do, but kind of lame in implementation. --- share/functions/alias.fish | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/share/functions/alias.fish b/share/functions/alias.fish index 811214c1d..86a1e702e 100644 --- a/share/functions/alias.fish +++ b/share/functions/alias.fish @@ -1,4 +1,4 @@ -function alias --description 'Legacy function for creating shellscript functions using an alias-like syntax' +function alias --description 'Creates a function wrapping a command' if count $argv > /dev/null switch $argv[1] case -h --h --he --hel --help @@ -14,8 +14,10 @@ function alias --description 'Legacy function for creating shellscript functions switch (count $argv) case 0 - echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information." - return 1 + for func in (functions -n) + functions $func | string match -- "function * --description 'alias *" | string replace -r -- "function .* --description '" ''| string trim -c\' + end + return 0 case 1 set -l tmp (string replace -r "=" '\n' -- $argv) "" set name $tmp[1] From fb979922b3f08277c8119ef7f4e22af9e9616869 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 29 Oct 2016 13:57:05 -0700 Subject: [PATCH 035/112] Update alias docs --- doc_src/alias.txt | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/doc_src/alias.txt b/doc_src/alias.txt index cbb9508eb..f02f9d69b 100644 --- a/doc_src/alias.txt +++ b/doc_src/alias.txt @@ -2,39 +2,36 @@ \subsection alias-synopsis Synopsis \fish{synopsis} +alias alias NAME DEFINITION alias NAME=DEFINITION \endfish \subsection alias-description Description -`alias` is a simple wrapper for the `function` builtin. It exists for backwards compatibility with Posix shells. For other uses, it is recommended to define a function. +`alias` is a simple wrapper for the `function` builtin, which creates a function wrapping a command. It has similar syntax to POSIX sh `alias`. For other uses, it is recommended to define a function. -`fish` does not keep track of which functions have been defined using `alias`. They must be erased using `functions -e`. +`fish` marks functions that have been created by `alias` by including the command used to craete them in the function description. You can list alias-created functions by running `alias` without arguments. They must be erased using `functions -e`. - `NAME` is the name of the alias - - `DEFINITION` is the actual command to execute. The string `$argv` will be appended. You cannot create an alias to a function with the same name. Note that spaces need to be escaped in the call to alias just like in the commandline _even inside the quotes_. - \subsection alias-example Example The following code will create `rmi`, which runs `rm` with additional arguments on every invocation. \fish -alias rmi "rm -i" +alias rmi="rm -i" # This is equivalent to entering the following function: - -function rmi +function rmi --wraps rm --description 'alias rmi=rm -i' rm -i $argv end # This needs to have the spaces escaped or "Chrome.app..." will be seen as an argument to "/Applications/Google": - alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana' \endfish From b0b218253569d414d963367ffc4cc01b879e2eec Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 29 Oct 2016 17:25:48 -0700 Subject: [PATCH 036/112] lint: missing default in switch statements --- src/builtin.cpp | 66 +++++++++++++++++++++++++++++++++++-- src/builtin_commandline.cpp | 12 +++++++ src/builtin_complete.cpp | 4 +++ src/builtin_jobs.cpp | 8 +++++ src/builtin_printf.cpp | 6 ++++ src/builtin_set.cpp | 7 ++++ src/builtin_set_color.cpp | 10 ++++-- src/builtin_string.cpp | 65 +++++++++++++++++++++++++++--------- src/builtin_ulimit.cpp | 4 +++ src/common.cpp | 2 ++ src/common.h | 3 ++ src/env.cpp | 23 +++++++++++-- src/env.h | 24 ++------------ src/event.cpp | 4 +++ src/parse_execution.cpp | 8 +++++ src/parse_util.cpp | 4 +++ src/utf8.cpp | 27 ++++++++------- 17 files changed, 220 insertions(+), 57 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 7efd57e3b..e9018a833 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -452,7 +452,6 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) while (1) { int opt_index = 0; int opt = w.wgetopt_long_only(argc, argv, L"aehkKfM:m:", long_options, &opt_index); - if (opt == -1) break; switch (opt) { @@ -501,6 +500,10 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -625,6 +628,10 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -665,6 +672,10 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv block = parser.block_at_index(++block_idx); } } + default: { + DIE("unexpected scope"); + break; + } } if (block) { block->event_blocks.push_front(eb); @@ -713,6 +724,10 @@ static int builtin_builtin(parser_t &parser, io_streams_t &streams, wchar_t **ar builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -759,6 +774,10 @@ static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv) builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -812,6 +831,10 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -870,6 +893,10 @@ static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **ar builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -934,6 +961,7 @@ static wcstring functions_def(const wcstring &name) { append_format(out, L" --on-event %ls", next->str_param1.c_str()); break; } + default: { DIE("unexpected next->type"); } } } @@ -1048,6 +1076,10 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t ** builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -1193,9 +1225,11 @@ static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) { case L'7': { return 7; } + default: { break; } } - if (base == 16) switch (wc) { + if (base == 16) { + switch (wc) { case L'8': { return 8; } @@ -1226,7 +1260,10 @@ static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) { case L'F': { return 15; } + default: { break; } } + } + return UINT_MAX; } @@ -1642,6 +1679,10 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis res = 1; break; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -1760,6 +1801,10 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -1915,6 +1960,10 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -2125,7 +2174,6 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg }; int mode = NORMAL; - int argc = builtin_count_args(argv); int res = STATUS_BUILTIN_OK; @@ -2213,11 +2261,18 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } if (!res) { switch (mode) { + case DONE: { + break; + } case CURRENT_FILENAME: { const wchar_t *fn = parser.current_filename(); @@ -2270,6 +2325,7 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg streams.out.append(parser.stack_trace()); break; } + default: { break; } } } @@ -2426,6 +2482,10 @@ static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **a should_output_index = true; break; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp index 1836b2377..9941a62cc 100644 --- a/src/builtin_commandline.cpp +++ b/src/builtin_commandline.cpp @@ -127,6 +127,10 @@ static void replace_part(const wchar_t *begin, const wchar_t *end, const wchar_t out_pos += wcslen(insert); break; } + default: { + DIE("unexpected append_mode"); + break; + } } out.append(end); reader_set_buffer(out, out_pos); @@ -326,6 +330,10 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv) builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return 1; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -470,6 +478,10 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv) parse_util_token_extent(get_buffer(), get_cursor_pos(), &begin, &end, 0, 0); break; } + default: { + DIE("unexpected buffer_part"); + break; + } } int arg_count = argc - w.woptind; diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp index ec14f8ffe..489ff3c91 100644 --- a/src/builtin_complete.cpp +++ b/src/builtin_complete.cpp @@ -283,6 +283,10 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) { res = true; break; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_jobs.cpp b/src/builtin_jobs.cpp index 72765cb82..7a92e6b9e 100644 --- a/src/builtin_jobs.cpp +++ b/src/builtin_jobs.cpp @@ -101,6 +101,10 @@ static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_ } break; } + default: { + DIE("unexpected mode"); + break; + } } } @@ -159,6 +163,10 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) { builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return 1; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp index 7442673fe..d43927250 100644 --- a/src/builtin_printf.cpp +++ b/src/builtin_printf.cpp @@ -541,6 +541,12 @@ void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wc } break; } + default: { + // TODO: Determine if this should call DIE() + // WTF + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_set.cpp b/src/builtin_set.cpp index 0427427ec..643a08bd0 100644 --- a/src/builtin_set.cpp +++ b/src/builtin_set.cpp @@ -123,6 +123,9 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, } switch (env_set(key, val_str, scope | ENV_USER)) { + case ENV_OK: { + break; + } case ENV_PERM: { streams.err.append_format(_(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); @@ -143,6 +146,10 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, retcode = 1; break; } + default: { + DIE("unexpected env_set() ret val"); + break; + } } return retcode; diff --git a/src/builtin_set_color.cpp b/src/builtin_set_color.cpp index b12c39229..b05bf016d 100644 --- a/src/builtin_set_color.cpp +++ b/src/builtin_set_color.cpp @@ -77,13 +77,13 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) { // Parse options to obtain the requested operation and the modifiers. w.woptind = 0; while (1) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + if (opt == -1) { break; } - switch (c) { + switch (opt) { case 0: { break; } @@ -110,6 +110,10 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) { case '?': { return STATUS_BUILTIN_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp index 0f01096df..eb8e7e2f1 100644 --- a/src/builtin_string.cpp +++ b/src/builtin_string.cpp @@ -100,12 +100,13 @@ static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wcha escape_flags_t flags = ESCAPE_ALL; wgetopter_t w; for (;;) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + if (opt == -1) { break; } - switch (c) { + + switch (opt) { case 0: { break; } @@ -117,6 +118,10 @@ static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wcha string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -145,11 +150,13 @@ static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_ bool quiet = false; wgetopter_t w; for (;;) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); + + if (opt == -1) { break; } - switch (c) { + + switch (opt) { case 0: { break; } @@ -161,6 +168,10 @@ static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_ string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -202,12 +213,12 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha bool quiet = false; wgetopter_t w; for (;;) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + if (opt == -1) { break; } - switch (c) { + switch (opt) { case 0: { break; } @@ -219,6 +230,10 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -499,12 +514,12 @@ static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar bool regex = false; wgetopter_t w; for (;;) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + if (opt == -1) { break; } - switch (c) { + switch (opt) { case 0: { break; } @@ -536,6 +551,10 @@ static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -731,12 +750,12 @@ static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wch bool regex = false; wgetopter_t w; for (;;) { - int c = w.wgetopt_long(argc, argv, short_options, long_options, 0); + int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0); - if (c == -1) { + if (opt == -1) { break; } - switch (c) { + switch (opt) { case 0: { break; } @@ -760,6 +779,10 @@ static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wch string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -876,6 +899,10 @@ static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -989,6 +1016,10 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } @@ -1078,6 +1109,10 @@ static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_ string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return BUILTIN_STRING_ERROR; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/builtin_ulimit.cpp b/src/builtin_ulimit.cpp index 6c67eb9f1..5cc752982 100644 --- a/src/builtin_ulimit.cpp +++ b/src/builtin_ulimit.cpp @@ -262,6 +262,10 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) { builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); return 1; } + default: { + DIE("unexpected opt"); + break; + } } } diff --git a/src/common.cpp b/src/common.cpp index d5bd5ee38..0fa22b310 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1220,6 +1220,7 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } + default: { break; } } } else if (mode == mode_single_quotes) { if (c == L'\\') { @@ -1297,6 +1298,7 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in } break; } + default: { break; } } } diff --git a/src/common.h b/src/common.h index 3afae7a6c..33781f680 100644 --- a/src/common.h +++ b/src/common.h @@ -211,6 +211,9 @@ extern bool has_working_tty_timestamps; } /// Pause for input, then exit the program. If supported, print a backtrace first. +// The `return` will never be run but silences oclint warnings. Especially when this is called +// from within a `switch` block. As of the time I'm writing this oclint doesn't recognize the +// `__attribute__((noreturn))` on the exit_without_destructors() function. #define FATAL_EXIT() \ { \ char exit_read_buff; \ diff --git a/src/env.cpp b/src/env.cpp index 75784624c..2ac7fe2ba 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -476,6 +476,25 @@ static env_node_t *env_get_node(const wcstring &key) { return env; } +/// Set the value of the environment variable whose name matches key to val. +/// +/// Memory policy: All keys and values are copied, the parameters can and should be freed by the +/// caller afterwards +/// +/// \param key The key +/// \param val The value +/// \param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, +/// ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current +/// mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed. +/// +/// Returns: +/// +/// * ENV_OK on success. +/// * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that +/// the user tried to change a read-only variable. +/// * ENV_SCOPE, the variable cannot be set in the given scope. This applies to readonly/electric +/// variables set from the local or universal scopes, or set as exported. +/// * ENV_INVALID, the variable value was invalid. This applies only to special variables. int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) { ASSERT_IS_MAIN_THREAD(); bool has_changed_old = has_changed_exported; @@ -512,7 +531,7 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) umask(mask); // Do not actually create a umask variable, on env_get, it will be calculated // dynamically. - return 0; + return ENV_OK; } } @@ -636,7 +655,7 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) // debug( 1, L"env_set: return from event firing" ); react_to_variable_change(key); - return 0; + return ENV_OK; } /// Attempt to remove/free the specified key/value pair from the specified map. diff --git a/src/env.h b/src/env.h index 6f783312c..56a84ffde 100644 --- a/src/env.h +++ b/src/env.h @@ -36,8 +36,8 @@ enum { }; typedef uint32_t env_mode_flags_t; -/// Error code for trying to alter read-only variable. -enum { ENV_PERM = 1, ENV_SCOPE, ENV_INVALID }; +/// Return values for `env_set()`. +enum { ENV_OK, ENV_PERM, ENV_SCOPE, ENV_INVALID }; /// A struct of configuration directories, determined in main() that fish will optionally pass to /// env_init. @@ -51,26 +51,6 @@ struct config_paths_t { /// Initialize environment variable data. void env_init(const struct config_paths_t *paths = NULL); -/// Set the value of the environment variable whose name matches key to val. -/// -/// Memory policy: All keys and values are copied, the parameters can and should be freed by the -/// caller afterwards -/// -/// \param key The key -/// \param val The value -/// \param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, -/// ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current -/// mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed. -/// -/// \returns 0 on success or an error code on failiure. -/// -/// The current error codes are: -/// -/// * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that -/// the user tried to change a read-only variable. -/// * ENV_SCOPE, the variable cannot be set in the given scope. This applies to readonly/electric -/// variables set from the local or universal scopes, or set as exported. -/// * ENV_INVALID, the variable value was invalid. This applies only to special variables. int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t mode); class env_var_t : public wcstring { diff --git a/src/event.cpp b/src/event.cpp index 143992c7e..c215d81fd 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -88,6 +88,10 @@ static int event_match(const event_t &classv, const event_t &instance) { case EVENT_GENERIC: { return instance.str_param1 == classv.str_param1; } + default: { + DIE("unexpected classv.type"); + break; + } } // This should never be reached. diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 69bd85632..8887c682a 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -534,6 +534,10 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement( case EXPAND_OK: { break; } + default: { + DIE("unexpected expand_string() return value"); + break; + } } if (result == parse_execution_success && switch_values_expanded.size() != 1) { @@ -945,6 +949,10 @@ parse_execution_result_t parse_execution_context_t::determine_arguments( case EXPAND_OK: { break; } + default: { + DIE("unexpected expand_string() return value"); + break; + } } // Now copy over any expanded arguments. Do it using swap() to avoid extra allocations; this diff --git a/src/parse_util.cpp b/src/parse_util.cpp index f0a7f37c5..80c89e160 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -1004,6 +1004,10 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t } break; } + default: { + DIE("unexpected parse_util_locate_cmdsubst() return value"); + break; + } } } diff --git a/src/utf8.cpp b/src/utf8.cpp index 0e87e50ab..53d994852 100644 --- a/src/utf8.cpp +++ b/src/utf8.cpp @@ -20,6 +20,7 @@ #include #include +#include "common.h" #include "utf8.h" #define _NXT 0x80 @@ -137,9 +138,8 @@ static int __utf8_forbitten(unsigned char octet) { case 0xff: { return -1; } + default: { return 0; } } - - return 0; } /// This function translates UTF-8 string into UCS-2 or UCS-4 string (all symbols will be in local @@ -288,18 +288,17 @@ static size_t wchar_to_utf8_internal(const utf8_wchar_t *in, size_t insize, char if ((flags & UTF8_IGNORE_ERROR) == 0) return 0; continue; } - if (w_wide <= 0x0000007f) + if (w_wide <= 0x0000007f) { n = 1; - else if (w_wide <= 0x000007ff) + } else if (w_wide <= 0x000007ff) { n = 2; - else if (w_wide <= 0x0000ffff) + } else if (w_wide <= 0x0000ffff) { n = 3; - else if (w_wide <= 0x001fffff) + } else if (w_wide <= 0x001fffff) { n = 4; - else if (w_wide <= 0x03ffffff) - n = 5; - else - n = 6; /// if (w_wide <= 0x7fffffff) + } else { + DIE("invalid wide char"); + } total += n; @@ -340,10 +339,14 @@ static size_t wchar_to_utf8_internal(const utf8_wchar_t *in, size_t insize, char p[0] = _SEQ4 | ((oc[1] & 0x1f) >> 2); break; } + default: { + DIE("unexpected utff8 len"); + break; + } } - // NOTE: do not check here for forbitten UTF-8 characters. They cannot appear here because - // we do proper convertion. + // NOTE: do not check here for forbidden UTF-8 characters. They cannot appear here because + // we do proper conversion. p += n; } From 6bef7b7be955b006d746a45ad6333dc70db855dc Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 29 Oct 2016 19:01:19 -0700 Subject: [PATCH 037/112] lint: constant if expression --- src/common.cpp | 18 +++++++----------- src/iothread.cpp | 8 +++----- src/parse_productions.cpp | 13 +++++-------- src/utf8.cpp | 4 ++-- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 0fa22b310..bdf327018 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -196,15 +196,14 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) { // Protect against broken mbrtowc() implementations which attempt to encode UTF-8 // sequences longer than four bytes (e.g., OS X Snow Leopard). use_encode_direct = true; - } else if (sizeof(wchar_t) == 2 && (in[in_pos] & 0xF8) == 0xF0) { + } else if (sizeof(wchar_t) == 2 && //!OCLINT(constant if expression) + (in[in_pos] & 0xF8) == 0xF0) { // Assume we are in a UTF-16 environment (e.g., Cygwin) using a UTF-8 encoding. // The bits set check will be true for a four byte UTF-8 sequence that requires // two UTF-16 chars. Something that doesn't work with our simple use of mbrtowc(). use_encode_direct = true; } else { ret = mbrtowc(&wc, &in[in_pos], in_len - in_pos, &state); - // fprintf(stderr, "WTF in_pos %d ret %d\n", in_pos, ret); - // Determine whether to encode this character with our crazy scheme. if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) { use_encode_direct = true; @@ -219,7 +218,8 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) { } else if (ret > in_len - in_pos) { // Other error codes? Terrifying, should never happen. use_encode_direct = true; - } else if (sizeof(wchar_t) == 2 && wc >= 0xD800 && wc <= 0xDFFF) { + } else if (sizeof(wchar_t) == 2 && wc >= 0xD800 && //!OCLINT(constant if expression) + wc <= 0xDFFF) { // If we get a surrogate pair char on a UTF-16 system (e.g., Cygwin) then // it's guaranteed the UTF-8 decoding is wrong so use direct encoding. use_encode_direct = true; @@ -227,24 +227,20 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) { } if (use_encode_direct) { - // fprintf(stderr, "WTF use_encode_direct\n"); wc = ENCODE_DIRECT_BASE + (unsigned char)in[in_pos]; result.push_back(wc); in_pos++; memset(&state, 0, sizeof state); - } else if (ret == 0) { - // fprintf(stderr, "WTF null byte\n"); - // Embedded null byte! + } else if (ret == 0) { // embedded null byte! result.push_back(L'\0'); in_pos++; memset(&state, 0, sizeof state); - } else { - // fprintf(stderr, "WTF null byte\n"); - // Normal case. + } else { // normal case result.push_back(wc); in_pos += ret; } } + return result; } diff --git a/src/iothread.cpp b/src/iothread.cpp index bc7da0cb5..ca9e50a41 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -30,8 +30,6 @@ #define IO_SERVICE_MAIN_THREAD_REQUEST_QUEUE 99 #define IO_SERVICE_RESULT_QUEUE 100 -#define IOTHREAD_LOG if (0) - static void iothread_service_main_thread_requests(void); static void iothread_service_result_queue(); @@ -120,7 +118,7 @@ static void *iothread_worker(void *unused) { scoped_lock locker(s_spawn_queue_lock); struct SpawnRequest_t *req; while ((req = dequeue_spawn_request()) != NULL) { - IOTHREAD_LOG fprintf(stderr, "pthread %p dequeued %p\n", this_thread(), req); + debug(5, "pthread %p dequeued %p\n", this_thread(), req); // Unlock the queue while we execute the request. locker.unlock(); @@ -153,7 +151,7 @@ static void *iothread_worker(void *unused) { assert(s_active_thread_count > 0); s_active_thread_count -= 1; - IOTHREAD_LOG fprintf(stderr, "pthread %p exiting\n", this_thread()); + debug(5, "pthread %p exiting\n", this_thread()); // We're done. return NULL; } @@ -175,7 +173,7 @@ static void iothread_spawn() { // We will never join this thread. VOMIT_ON_FAILURE(pthread_detach(thread)); - IOTHREAD_LOG fprintf(stderr, "pthread %p spawned\n", (void *)(intptr_t)thread); + debug(5, "pthread %p spawned\n", (void *)(intptr_t)thread); // Restore our sigmask. VOMIT_ON_FAILURE(pthread_sigmask(SIG_SETMASK, &saved_set, NULL)); } diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp index 0455b50fa..1b577d6ed 100644 --- a/src/parse_productions.cpp +++ b/src/parse_productions.cpp @@ -432,11 +432,8 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n const parse_token_t &input1, const parse_token_t &input2, parse_node_tag_t *out_tag) { - const bool log_it = false; - if (log_it) { - fprintf(stderr, "Resolving production for %ls with input token <%ls>\n", - token_type_description(node_type), input1.describe().c_str()); - } + debug(5, "Resolving production for %ls with input token <%ls>\n", + token_type_description(node_type), input1.describe().c_str()); // Fetch the function to resolve the list of productions. const production_t *(*resolver)(const parse_token_t &input1, const parse_token_t &input2, @@ -500,9 +497,9 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n PARSE_ASSERT(resolver != NULL); const production_t *result = resolver(input1, input2, out_tag); - if (result == NULL && log_it) { - fprintf(stderr, "Node type '%ls' has no production for input '%ls' (in %s)\n", - token_type_description(node_type), input1.describe().c_str(), __FUNCTION__); + if (result == NULL) { + debug(5, "Node type '%ls' has no production for input '%ls' (in %s)\n", + token_type_description(node_type), input1.describe().c_str(), __FUNCTION__); } return result; diff --git a/src/utf8.cpp b/src/utf8.cpp index 53d994852..55d404fe8 100644 --- a/src/utf8.cpp +++ b/src/utf8.cpp @@ -82,7 +82,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, std::wstring *out, int flags } size_t result; - if (sizeof(wchar_t) == sizeof(utf8_wchar_t)) { + if (sizeof(wchar_t) == sizeof(utf8_wchar_t)) { //!OCLINT(constant if expression) result = utf8_to_wchar_internal(in, insize, reinterpret_cast(out), flags); } else if (out == NULL) { result = utf8_to_wchar_internal(in, insize, NULL, flags); @@ -102,7 +102,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, size_t outsize } size_t result; - if (sizeof(wchar_t) == sizeof(utf8_wchar_t)) { + if (sizeof(wchar_t) == sizeof(utf8_wchar_t)) { //!OCLINT(constant if expression) result = wchar_to_utf8_internal(reinterpret_cast(in), insize, out, outsize, flags); } else { From 9af07973342b0fd72ca1da9ea20565692a9485a2 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 29 Oct 2016 20:51:03 -0700 Subject: [PATCH 038/112] lint: Use early exit/continue --- src/parse_tree.cpp | 364 +++++++++++++++++++++++---------------------- 1 file changed, 185 insertions(+), 179 deletions(-) diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index cbe6436aa..407c1dae2 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -73,70 +73,74 @@ static bool production_is_empty(const production_t *production) { wcstring parse_error_t::describe_with_prefix(const wcstring &src, const wcstring &prefix, bool is_interactive, bool skip_caret) const { wcstring result = text; - if (!skip_caret && source_start < src.size() && source_start + source_length <= src.size()) { - // Locate the beginning of this line of source. - size_t line_start = 0; - // Look for a newline prior to source_start. If we don't find one, start at the beginning of - // the string; otherwise start one past the newline. Note that source_start may itself point - // at a newline; we want to find the newline before it. - if (source_start > 0) { - size_t newline = src.find_last_of(L'\n', source_start - 1); - if (newline != wcstring::npos) { - line_start = newline + 1; - } - } + if (skip_caret || source_start >= src.size() || source_start + source_length > src.size()) { + return result; + } - // Look for the newline after the source range. If the source range itself includes a - // newline, that's the one we want, so start just before the end of the range. - size_t last_char_in_range = - (source_length == 0 ? source_start : source_start + source_length - 1); - size_t line_end = src.find(L'\n', last_char_in_range); - if (line_end == wcstring::npos) { - line_end = src.size(); - } + // Locate the beginning of this line of source. + size_t line_start = 0; - assert(line_end >= line_start); - assert(source_start >= line_start); - - // Don't include the caret and line if we're interactive this is the first line, because - // then it's obvious. - bool skip_caret = (is_interactive && source_start == 0); - - if (!skip_caret) { - // Append the line of text. - if (!result.empty()) { - result.push_back(L'\n'); - } - result.append(prefix); - result.append(src, line_start, line_end - line_start); - - // Append the caret line. The input source may include tabs; for that reason we - // construct a "caret line" that has tabs in corresponding positions. - const wcstring line_to_measure = - prefix + wcstring(src, line_start, source_start - line_start); - wcstring caret_space_line; - caret_space_line.reserve(source_start - line_start); - for (size_t i = 0; i < line_to_measure.size(); i++) { - wchar_t wc = line_to_measure.at(i); - if (wc == L'\t') { - caret_space_line.push_back(L'\t'); - } else if (wc == L'\n') { - // It's possible that the source_start points at a newline itself. In that case, - // pretend it's a space. We only expect this to be at the end of the string. - caret_space_line.push_back(L' '); - } else { - int width = fish_wcwidth(wc); - if (width > 0) { - caret_space_line.append(static_cast(width), L' '); - } - } - } - result.push_back(L'\n'); - result.append(caret_space_line); - result.push_back(L'^'); + // Look for a newline prior to source_start. If we don't find one, start at the beginning of + // the string; otherwise start one past the newline. Note that source_start may itself point + // at a newline; we want to find the newline before it. + if (source_start > 0) { + size_t newline = src.find_last_of(L'\n', source_start - 1); + if (newline != wcstring::npos) { + line_start = newline + 1; } } + + // Look for the newline after the source range. If the source range itself includes a + // newline, that's the one we want, so start just before the end of the range. + size_t last_char_in_range = + (source_length == 0 ? source_start : source_start + source_length - 1); + size_t line_end = src.find(L'\n', last_char_in_range); + if (line_end == wcstring::npos) { + line_end = src.size(); + } + + assert(line_end >= line_start); + assert(source_start >= line_start); + + // Don't include the caret and line if we're interactive this is the first line, because + // then it's obvious. + bool interactive_skip_caret = is_interactive && source_start == 0; + + if (interactive_skip_caret) { + return result; + } + + // Append the line of text. + if (!result.empty()) { + result.push_back(L'\n'); + } + result.append(prefix); + result.append(src, line_start, line_end - line_start); + + // Append the caret line. The input source may include tabs; for that reason we + // construct a "caret line" that has tabs in corresponding positions. + const wcstring line_to_measure = prefix + wcstring(src, line_start, source_start - line_start); + wcstring caret_space_line; + caret_space_line.reserve(source_start - line_start); + for (size_t i = 0; i < line_to_measure.size(); i++) { + wchar_t wc = line_to_measure.at(i); + if (wc == L'\t') { + caret_space_line.push_back(L'\t'); + } else if (wc == L'\n') { + // It's possible that the source_start points at a newline itself. In that case, + // pretend it's a space. We only expect this to be at the end of the string. + caret_space_line.push_back(L' '); + } else { + int width = fish_wcwidth(wc); + if (width > 0) { + caret_space_line.append(static_cast(width), L' '); + } + } + } + result.push_back(L'\n'); + result.append(caret_space_line); + result.push_back(L'^'); return result; } @@ -888,25 +892,27 @@ bool parse_ll_t::report_error_for_unclosed_block() { block_node = this->nodes.get_child(*block_node, 0, symbol_block_header); block_node = this->nodes.get_child(*block_node, 0); // specific statement } - if (block_node != NULL) { - // block_node is now an if_statement, switch_statement, for_header, while_header, - // function_header, or begin_header. - // - // Hackish: descend down the first node until we reach the bottom. This will be a keyword - // node like SWITCH, which will have the source range. Ordinarily the source range would be - // known by the parent node too, but we haven't completed parsing yet, so we haven't yet - // propagated source ranges. - const parse_node_t *cursor = block_node; - while (cursor->child_count > 0) { - cursor = this->nodes.get_child(*cursor, 0); - assert(cursor != NULL); - } - if (cursor->source_start != NODE_OFFSET_INVALID) { - const wcstring node_desc = block_type_user_presentable_description(block_node->type); - this->parse_error_at_location(cursor->source_start, parse_error_generic, - L"Missing end to balance this %ls", node_desc.c_str()); - reported_error = true; - } + if (block_node == NULL) { + return reported_error; + } + + // block_node is now an if_statement, switch_statement, for_header, while_header, + // function_header, or begin_header. + // + // Hackish: descend down the first node until we reach the bottom. This will be a keyword + // node like SWITCH, which will have the source range. Ordinarily the source range would be + // known by the parent node too, but we haven't completed parsing yet, so we haven't yet + // propagated source ranges. + const parse_node_t *cursor = block_node; + while (cursor->child_count > 0) { + cursor = this->nodes.get_child(*cursor, 0); + assert(cursor != NULL); + } + if (cursor->source_start != NODE_OFFSET_INVALID) { + const wcstring node_desc = block_type_user_presentable_description(block_node->type); + this->parse_error_at_location(cursor->source_start, parse_error_generic, + L"Missing end to balance this %ls", node_desc.c_str()); + reported_error = true; } return reported_error; } @@ -914,85 +920,84 @@ bool parse_ll_t::report_error_for_unclosed_block() { bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) { PARSE_ASSERT(!symbol_stack.empty()); //!OCLINT(multiple unary operator) PARSE_ASSERT(token.type >= FIRST_PARSE_TOKEN_TYPE); - bool handled = false; parse_stack_element_t &stack_top = symbol_stack.back(); - if (type_is_terminal_type(stack_top.type)) { - // The top of the stack is terminal. We are going to handle this (because we can't produce - // from a terminal type). - handled = true; - // Now see if we actually matched - bool matched = false; - if (stack_top.type == token.type) { - if (stack_top.type == parse_token_type_string) { - // We matched if the keywords match, or no keyword was required. - matched = - (stack_top.keyword == parse_keyword_none || stack_top.keyword == token.keyword); - } else { - // For other types, we only require that the types match. - matched = true; - } - } - - if (matched) { - // Success. Tell the node that it matched this token, and what its source range is in - // the parse phase, we only set source ranges for terminal types. We propagate ranges to - // parent nodes afterwards. - parse_node_t &node = node_for_top_symbol(); - node.keyword = token.keyword; - node.source_start = token.source_start; - node.source_length = token.source_length; - } else { - // Failure - if (stack_top.type == parse_token_type_string && - token.type == parse_token_type_string) { - // Keyword failure. We should unify this with the 'matched' computation above. - assert(stack_top.keyword != parse_keyword_none && - stack_top.keyword != token.keyword); - - // Check to see which keyword we got which was considered wrong. - switch (token.keyword) { - // Some keywords are only valid in certain contexts. If this cascaded all the - // way down through the outermost job_list, it was not in a valid context. - case parse_keyword_case: - case parse_keyword_end: - case parse_keyword_else: { - this->parse_error_unbalancing_token(token); - break; - } - case parse_keyword_none: { - // This is a random other string (not a keyword). - const wcstring expected = keyword_description(stack_top.keyword); - this->parse_error(token, parse_error_generic, L"Expected keyword '%ls'", - expected.c_str()); - break; - } - default: { - // Got a real keyword we can report. - const wcstring actual = (token.keyword == parse_keyword_none - ? token.describe() - : keyword_description(token.keyword)); - const wcstring expected = keyword_description(stack_top.keyword); - this->parse_error(token, parse_error_generic, - L"Expected keyword '%ls', instead got keyword '%ls'", - expected.c_str(), actual.c_str()); - break; - } - } - } else if (stack_top.keyword == parse_keyword_end && - token.type == parse_token_type_terminate && - this->report_error_for_unclosed_block()) { - // Handled by report_error_for_unclosed_block. - } else { - const wcstring expected = stack_top.user_presentable_description(); - this->parse_error_unexpected_token(expected.c_str(), token); - } - } - - // We handled the token, so pop the symbol stack. - symbol_stack.pop_back(); + if (!type_is_terminal_type(stack_top.type)) { + return false; // was not handled } - return handled; + + // The top of the stack is terminal. We are going to handle this (because we can't produce + // from a terminal type). + + // Now see if we actually matched + bool matched = false; + if (stack_top.type == token.type) { + if (stack_top.type == parse_token_type_string) { + // We matched if the keywords match, or no keyword was required. + matched = + (stack_top.keyword == parse_keyword_none || stack_top.keyword == token.keyword); + } else { + // For other types, we only require that the types match. + matched = true; + } + } + + if (matched) { + // Success. Tell the node that it matched this token, and what its source range is in + // the parse phase, we only set source ranges for terminal types. We propagate ranges to + // parent nodes afterwards. + parse_node_t &node = node_for_top_symbol(); + node.keyword = token.keyword; + node.source_start = token.source_start; + node.source_length = token.source_length; + } else { + // Failure + if (stack_top.type == parse_token_type_string && token.type == parse_token_type_string) { + // Keyword failure. We should unify this with the 'matched' computation above. + assert(stack_top.keyword != parse_keyword_none && stack_top.keyword != token.keyword); + + // Check to see which keyword we got which was considered wrong. + switch (token.keyword) { + // Some keywords are only valid in certain contexts. If this cascaded all the + // way down through the outermost job_list, it was not in a valid context. + case parse_keyword_case: + case parse_keyword_end: + case parse_keyword_else: { + this->parse_error_unbalancing_token(token); + break; + } + case parse_keyword_none: { + // This is a random other string (not a keyword). + const wcstring expected = keyword_description(stack_top.keyword); + this->parse_error(token, parse_error_generic, L"Expected keyword '%ls'", + expected.c_str()); + break; + } + default: { + // Got a real keyword we can report. + const wcstring actual = + (token.keyword == parse_keyword_none ? token.describe() + : keyword_description(token.keyword)); + const wcstring expected = keyword_description(stack_top.keyword); + this->parse_error(token, parse_error_generic, + L"Expected keyword '%ls', instead got keyword '%ls'", + expected.c_str(), actual.c_str()); + break; + } + } + } else if (stack_top.keyword == parse_keyword_end && + token.type == parse_token_type_terminate && + this->report_error_for_unclosed_block()) { + // Handled by report_error_for_unclosed_block. + } else { + const wcstring expected = stack_top.user_presentable_description(); + this->parse_error_unexpected_token(expected.c_str(), token); + } + } + + // We handled the token, so pop the symbol stack. + symbol_stack.pop_back(); + return true; } void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) { @@ -1233,32 +1238,33 @@ bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t parse_flags, parser.report_tokenizer_error(tokenizer_token); } - // Handle errors. - if (parser.has_fatal_error()) { - if (parse_flags & parse_flag_continue_after_error) { - // Hack. Typically the parse error is due to the first token. However, if it's a - // tokenizer error, then has_fatal_error was set due to the check above; in that - // case the second token is what matters. - size_t error_token_idx = 0; - if (queue[1].type == parse_special_type_tokenizer_error) { - error_token_idx = (queue[1].type == parse_special_type_tokenizer_error ? 1 : 0); - token_count = -1; // so that it will be 0 after incrementing, and our tokenizer - // error will be ignored - } - - // Mark a special error token, and then keep going. - const parse_token_t token = {parse_special_type_parse_error, - parse_keyword_none, - false, - false, - queue[error_token_idx].source_start, - queue[error_token_idx].source_length}; - parser.accept_tokens(token, kInvalidToken); - parser.reset_symbols(goal); - } else { - break; // bail out - } + if (!parser.has_fatal_error()) { + continue; } + + // Handle errors. + if (!(parse_flags & parse_flag_continue_after_error)) { + break; // bail out + } + // Hack. Typically the parse error is due to the first token. However, if it's a + // tokenizer error, then has_fatal_error was set due to the check above; in that + // case the second token is what matters. + size_t error_token_idx = 0; + if (queue[1].type == parse_special_type_tokenizer_error) { + error_token_idx = (queue[1].type == parse_special_type_tokenizer_error ? 1 : 0); + token_count = -1; // so that it will be 0 after incrementing, and our tokenizer + // error will be ignored + } + + // Mark a special error token, and then keep going. + const parse_token_t token = {parse_special_type_parse_error, + parse_keyword_none, + false, + false, + queue[error_token_idx].source_start, + queue[error_token_idx].source_length}; + parser.accept_tokens(token, kInvalidToken); + parser.reset_symbols(goal); } // Teach each node where its source range is. From 99b729eb4d228de2e6dace68737475b4b0644d0c Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 29 Oct 2016 21:20:29 -0700 Subject: [PATCH 039/112] lint: Use early exit/continue --- src/pager.cpp | 207 +++++++++++++++++++++++++------------------------- 1 file changed, 104 insertions(+), 103 deletions(-) diff --git a/src/pager.cpp b/src/pager.cpp index 0c9a37606..9bea536e2 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -365,7 +365,7 @@ void pager_t::set_term_size(int w, int h) { } /// Try to print the list of completions l with the prefix prefix using cols as the number of -/// columns. Return true if the completion list was printed, false if the terminal is to narrow for +/// columns. Return true if the completion list was printed, false if the terminal is too narrow for /// the specified number of columns. Always succeeds if cols is 1. bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering, size_t suggested_start_row) const { @@ -446,75 +446,78 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co print = true; } - if (print) { - // Determine the starting and stop row. - size_t start_row = 0, stop_row = 0; - if (row_count <= term_height) { - // Easy, we can show everything. - start_row = 0; - stop_row = row_count; - } else { - // We can only show part of the full list. Determine which part based on the - // suggested_start_row. - assert(row_count > term_height); - size_t last_starting_row = row_count - term_height; - start_row = mini(suggested_start_row, last_starting_row); - stop_row = start_row + term_height; - assert(start_row >= 0 && start_row <= last_starting_row); - } - - assert(stop_row >= start_row); - assert(stop_row <= row_count); - assert(stop_row - start_row <= term_height); - completion_print(cols, width, start_row, stop_row, prefix, lst, rendering); - - // Ellipsis helper string. Either empty or containing the ellipsis char. - const wchar_t ellipsis_string[] = {ellipsis_char == L'\x2026' ? L'\x2026' : L'\0', L'\0'}; - - // Add the progress line. It's a "more to disclose" line if necessary, or a row listing if - // it's scrollable; otherwise ignore it. - wcstring progress_text; - if (rendering->remaining_to_disclose == 1) { - // I don't expect this case to ever happen. - progress_text = format_string(_(L"%lsand 1 more row"), ellipsis_string); - } else if (rendering->remaining_to_disclose > 1) { - progress_text = format_string(_(L"%lsand %lu more rows"), ellipsis_string, - (unsigned long)rendering->remaining_to_disclose); - } else if (start_row > 0 || stop_row < row_count) { - // We have a scrollable interface. The +1 here is because we are zero indexed, but want - // to present things as 1-indexed. We do not add 1 to stop_row or row_count because - // these are the "past the last value". - progress_text = - format_string(_(L"rows %lu to %lu of %lu"), start_row + 1, stop_row, row_count); - } else if (completion_infos.empty() && !unfiltered_completion_infos.empty()) { - // Everything is filtered. - progress_text = _(L"(no matches)"); - } - - if (!progress_text.empty()) { - line_t &line = rendering->screen_data.add_line(); - print_max(progress_text, highlight_spec_pager_progress | - highlight_make_background(highlight_spec_pager_progress), - term_width, true /* has_more */, &line); - } - - if (search_field_shown) { - // Add the search field. - wcstring search_field_text = search_field_line.text; - // Append spaces to make it at least the required width. - if (search_field_text.size() < PAGER_SEARCH_FIELD_WIDTH) { - search_field_text.append(PAGER_SEARCH_FIELD_WIDTH - search_field_text.size(), L' '); - } - line_t *search_field = &rendering->screen_data.insert_line_at_index(0); - - // We limit the width to term_width - 1. - int search_field_written = print_max(SEARCH_FIELD_PROMPT, highlight_spec_normal, - term_width - 1, false, search_field); - print_max(search_field_text, highlight_modifier_force_underline, - term_width - search_field_written - 1, false, search_field); - } + if (!print) { + return false; // no need to continue } - return print; + + // Determine the starting and stop row. + size_t start_row = 0, stop_row = 0; + if (row_count <= term_height) { + // Easy, we can show everything. + start_row = 0; + stop_row = row_count; + } else { + // We can only show part of the full list. Determine which part based on the + // suggested_start_row. + assert(row_count > term_height); + size_t last_starting_row = row_count - term_height; + start_row = mini(suggested_start_row, last_starting_row); + stop_row = start_row + term_height; + assert(start_row >= 0 && start_row <= last_starting_row); + } + + assert(stop_row >= start_row); + assert(stop_row <= row_count); + assert(stop_row - start_row <= term_height); + completion_print(cols, width, start_row, stop_row, prefix, lst, rendering); + + // Ellipsis helper string. Either empty or containing the ellipsis char. + const wchar_t ellipsis_string[] = {ellipsis_char == L'\x2026' ? L'\x2026' : L'\0', L'\0'}; + + // Add the progress line. It's a "more to disclose" line if necessary, or a row listing if + // it's scrollable; otherwise ignore it. + wcstring progress_text; + if (rendering->remaining_to_disclose == 1) { + // I don't expect this case to ever happen. + progress_text = format_string(_(L"%lsand 1 more row"), ellipsis_string); + } else if (rendering->remaining_to_disclose > 1) { + progress_text = format_string(_(L"%lsand %lu more rows"), ellipsis_string, + (unsigned long)rendering->remaining_to_disclose); + } else if (start_row > 0 || stop_row < row_count) { + // We have a scrollable interface. The +1 here is because we are zero indexed, but want + // to present things as 1-indexed. We do not add 1 to stop_row or row_count because + // these are the "past the last value". + progress_text = + format_string(_(L"rows %lu to %lu of %lu"), start_row + 1, stop_row, row_count); + } else if (completion_infos.empty() && !unfiltered_completion_infos.empty()) { + // Everything is filtered. + progress_text = _(L"(no matches)"); + } + + if (!progress_text.empty()) { + line_t &line = rendering->screen_data.add_line(); + print_max(progress_text, highlight_spec_pager_progress | + highlight_make_background(highlight_spec_pager_progress), + term_width, true /* has_more */, &line); + } + + if (search_field_shown) { + // Add the search field. + wcstring search_field_text = search_field_line.text; + // Append spaces to make it at least the required width. + if (search_field_text.size() < PAGER_SEARCH_FIELD_WIDTH) { + search_field_text.append(PAGER_SEARCH_FIELD_WIDTH - search_field_text.size(), L' '); + } + line_t *search_field = &rendering->screen_data.insert_line_at_index(0); + + // We limit the width to term_width - 1. + int search_field_written = print_max(SEARCH_FIELD_PROMPT, highlight_spec_normal, + term_width - 1, false, search_field); + print_max(search_field_text, highlight_modifier_force_underline, + term_width - search_field_written - 1, false, search_field); + } + + return true; } page_rendering_t pager_t::render() const { @@ -717,42 +720,40 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio new_selected_completion_idx = current_col * rendering.rows + current_row; } - if (new_selected_completion_idx != selected_completion_idx) { - selected_completion_idx = new_selected_completion_idx; - - // Update suggested_row_start to ensure the selection is visible. suggested_row_start * - // rendering.cols is the first suggested visible completion; add the visible completion - // count to that to get the last one. - size_t visible_row_count = rendering.row_end - rendering.row_start; - - if (visible_row_count > 0 && selected_completion_idx != PAGER_SELECTION_NONE) // paranoia - { - size_t row_containing_selection = this->get_selected_row(rendering); - - // Ensure our suggested row start is not past the selected row. - if (suggested_row_start > row_containing_selection) { - suggested_row_start = row_containing_selection; - } - - // Ensure our suggested row start is not too early before it. - if (suggested_row_start + visible_row_count <= row_containing_selection) { - // The user moved south past the bottom completion. - if (!fully_disclosed && rendering.remaining_to_disclose > 0) { - fully_disclosed = true; // perform disclosure - } else { - // Scroll - suggested_row_start = row_containing_selection - visible_row_count + 1; - // Ensure fully_disclosed is set. I think we can hit this case if the user - // resizes the window - we don't want to drop back to the disclosed style. - fully_disclosed = true; - } - } - } - - return true; - } else { + if (selected_completion_idx == new_selected_completion_idx) { return false; } + selected_completion_idx = new_selected_completion_idx; + + // Update suggested_row_start to ensure the selection is visible. suggested_row_start * + // rendering.cols is the first suggested visible completion; add the visible completion + // count to that to get the last one. + size_t visible_row_count = rendering.row_end - rendering.row_start; + if (visible_row_count == 0 || selected_completion_idx == PAGER_SELECTION_NONE) { + return true; // this should never happen but be paranoid + } + + // Ensure our suggested row start is not past the selected row. + size_t row_containing_selection = this->get_selected_row(rendering); + if (suggested_row_start > row_containing_selection) { + suggested_row_start = row_containing_selection; + } + + // Ensure our suggested row start is not too early before it. + if (suggested_row_start + visible_row_count <= row_containing_selection) { + // The user moved south past the bottom completion. + if (!fully_disclosed && rendering.remaining_to_disclose > 0) { + fully_disclosed = true; // perform disclosure + } else { + // Scroll + suggested_row_start = row_containing_selection - visible_row_count + 1; + // Ensure fully_disclosed is set. I think we can hit this case if the user + // resizes the window - we don't want to drop back to the disclosed style. + fully_disclosed = true; + } + } + + return true; } size_t pager_t::visual_selected_completion_index(size_t rows, size_t cols) const { From f0ab1331a5d275f9d12428ab50f7697ea7de8006 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 29 Oct 2016 21:46:11 -0700 Subject: [PATCH 040/112] lint: Use early exit/continue --- src/env_universal_common.cpp | 109 ++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 08134855e..ed70a54d5 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -930,22 +930,24 @@ static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN], struct ifaddrs *ifap; bool ok = false; - if (getifaddrs(&ifap) == 0) { - for (const ifaddrs *p = ifap; p; p = p->ifa_next) { - bool is_af_link = p->ifa_addr && p->ifa_addr->sa_family == AF_LINK; - if (is_af_link && p->ifa_name && p->ifa_name[0] && - !strcmp((const char *)p->ifa_name, interface)) { - const sockaddr_dl &sdl = *reinterpret_cast(p->ifa_addr); - - size_t alen = sdl.sdl_alen; - if (alen > MAC_ADDRESS_MAX_LEN) alen = MAC_ADDRESS_MAX_LEN; - memcpy(macaddr, sdl.sdl_data + sdl.sdl_nlen, alen); - ok = true; - break; - } - } - freeifaddrs(ifap); + if (getifaddrs(&ifap) != 0) { + return ok; } + + for (const ifaddrs *p = ifap; p; p = p->ifa_next) { + bool is_af_link = p->ifa_addr && p->ifa_addr->sa_family == AF_LINK; + if (is_af_link && p->ifa_name && p->ifa_name[0] && + !strcmp((const char *)p->ifa_name, interface)) { + const sockaddr_dl &sdl = *reinterpret_cast(p->ifa_addr); + + size_t alen = sdl.sdl_alen; + if (alen > MAC_ADDRESS_MAX_LEN) alen = MAC_ADDRESS_MAX_LEN; + memcpy(macaddr, sdl.sdl_data + sdl.sdl_nlen, alen); + ok = true; + break; + } + } + freeifaddrs(ifap); return ok; } @@ -1356,8 +1358,6 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { } bool poll() { - bool result = false; - // Check if we are past the readback time. if (this->readback_time_usec > 0 && get_time() >= this->readback_time_usec) { // Read back what we wrote. We do nothing with the value. @@ -1372,30 +1372,29 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { } // Check to see if we are doing readability polling. - if (polling_due_to_readable_fd && pipe_fd >= 0) { - // We are polling, so we are definitely going to sync. - result = true; - - // See if this is still readable. - fd_set fds; - FD_ZERO(&fds); - FD_SET(this->pipe_fd, &fds); - struct timeval timeout = {}; - select(this->pipe_fd + 1, &fds, NULL, NULL, &timeout); - if (!FD_ISSET(this->pipe_fd, &fds)) { - // No longer readable, no longer polling. - polling_due_to_readable_fd = false; - drain_if_still_readable_time_usec = 0; - } else { - // Still readable. If it's been readable for a long time, there is probably - // lingering data on the pipe. - if (get_time() >= drain_if_still_readable_time_usec) { - drain_excessive_data(); - } - } + if (!polling_due_to_readable_fd || pipe_fd < 0) { + return false; } - return result; + // We are polling, so we are definitely going to sync. + // See if this is still readable. + fd_set fds; + FD_ZERO(&fds); + FD_SET(this->pipe_fd, &fds); + struct timeval timeout = {}; + select(this->pipe_fd + 1, &fds, NULL, NULL, &timeout); + if (!FD_ISSET(this->pipe_fd, &fds)) { + // No longer readable, no longer polling. + polling_due_to_readable_fd = false; + drain_if_still_readable_time_usec = 0; + } else { + // Still readable. If it's been readable for a long time, there is probably + // lingering data on the pipe. + if (get_time() >= drain_if_still_readable_time_usec) { + drain_excessive_data(); + } + } + return true; } }; @@ -1414,23 +1413,25 @@ static universal_notifier_t::notifier_strategy_t fetch_default_strategy_from_env const size_t opt_count = sizeof options / sizeof *options; const char *var = getenv(UNIVERSAL_NOTIFIER_ENV_NAME); - if (var != NULL && var[0] != '\0') { - size_t i; - for (i = 0; i < opt_count; i++) { - if (!strcmp(var, options[i].name)) { - result = options[i].strat; - break; - } + if (var == NULL || var[0] == '\0') { + return result; + } + + size_t i; + for (i = 0; i < opt_count; i++) { + if (!strcmp(var, options[i].name)) { + result = options[i].strat; + break; } - if (i >= opt_count) { - fprintf(stderr, "Warning: unrecognized value for %s: '%s'\n", - UNIVERSAL_NOTIFIER_ENV_NAME, var); - fprintf(stderr, "Warning: valid values are "); - for (size_t j = 0; j < opt_count; j++) { - fprintf(stderr, "%s%s", j > 0 ? ", " : "", options[j].name); - } - fputc('\n', stderr); + } + if (i >= opt_count) { + fprintf(stderr, "Warning: unrecognized value for %s: '%s'\n", + UNIVERSAL_NOTIFIER_ENV_NAME, var); + fprintf(stderr, "Warning: valid values are "); + for (size_t j = 0; j < opt_count; j++) { + fprintf(stderr, "%s%s", j > 0 ? ", " : "", options[j].name); } + fputc('\n', stderr); } return result; } From 1e234f492c05f73c38a554a036bcf600ea9310fd Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 30 Oct 2016 14:22:51 +0800 Subject: [PATCH 041/112] Makefile: pass correct version macro Fixes display of version in documentation header. A shell-style variable instead of a Makefile-style variable left it displayed as ISH_BUILD_VERSION. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 09cfac2e8..747be9d9e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -386,7 +386,7 @@ toc.txt: $(HDR_FILES:index.hdr=index.hdr.in) | show-SED @echo " SED $(em)$@$(sgr0)" $v rm -f toc.tmp $@ # Ugly hack to set the toc initial title for the main page - $v echo '- fish shell documentation - $FISH_BUILD_VERSION' > toc.tmp + $v echo '- fish shell documentation - $(FISH_BUILD_VERSION)' > toc.tmp # The first sed command captures the page name, followed by the description # The second sed command captures the command name \1 and the description \2, but only up to a dash # This is to reduce the size of the TOC in the command listing on the main page From f4f9ed56eee28d790c765dd23e64da1212d8e6ae Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sun, 30 Oct 2016 12:38:45 -0700 Subject: [PATCH 042/112] Move PCRE2 to pcre2 --- pcre2/.gitignore | 15 + pcre2/132html | 313 + pcre2/AUTHORS | 36 + pcre2/CMakeLists.txt | 780 + pcre2/COPYING | 5 + pcre2/ChangeLog | 758 + pcre2/CheckMan | 67 + pcre2/CleanTxt | 113 + pcre2/Detrail | 35 + pcre2/HACKING | 604 + pcre2/INSTALL | 370 + pcre2/LICENCE | 83 + pcre2/Makefile.am | 796 + pcre2/Makefile.in | 3136 +++ pcre2/NEWS | 88 + pcre2/NON-AUTOTOOLS-BUILD | 392 + pcre2/PrepareRelease | 235 + pcre2/README | 843 + pcre2/RunGrepTest | 633 + pcre2/RunTest | 850 + pcre2/aclocal.m4 | 1531 ++ pcre2/ar-lib | 270 + pcre2/cmake/COPYING-CMAKE-SCRIPTS | 22 + pcre2/cmake/FindEditline.cmake | 17 + .../cmake/FindPackageHandleStandardArgs.cmake | 58 + pcre2/cmake/FindReadline.cmake | 29 + pcre2/compile | 347 + pcre2/config-cmake.h.in | 48 + pcre2/config.guess | 1421 ++ pcre2/config.sub | 1807 ++ pcre2/configure | 18296 ++++++++++++++++ pcre2/configure.ac | 927 + pcre2/depcomp | 791 + pcre2/install-sh | 501 + pcre2/libpcre2-16.pc.in | 13 + pcre2/libpcre2-32.pc.in | 13 + pcre2/libpcre2-8.pc.in | 13 + pcre2/libpcre2-posix.pc.in | 13 + pcre2/ltmain.sh | 11147 ++++++++++ pcre2/m4/ax_pthread.m4 | 309 + pcre2/m4/libtool.m4 | 8369 +++++++ pcre2/m4/ltoptions.m4 | 437 + pcre2/m4/ltsugar.m4 | 124 + pcre2/m4/ltversion.m4 | 23 + pcre2/m4/lt~obsolete.m4 | 99 + pcre2/m4/pcre2_visibility.m4 | 87 + pcre2/missing | 215 + pcre2/pcre2-config.in | 121 + pcre2/perltest.sh | 297 + pcre2/src/config.h.generic | 306 + pcre2/src/config.h.in | 297 + pcre2/src/dftables.c | 214 + pcre2/src/pcre2.h.generic | 722 + pcre2/src/pcre2.h.in | 722 + pcre2/src/pcre2_auto_possess.c | 1287 ++ pcre2/src/pcre2_chartables.c.dist | 198 + pcre2/src/pcre2_compile.c | 9018 ++++++++ pcre2/src/pcre2_config.c | 217 + pcre2/src/pcre2_context.c | 391 + pcre2/src/pcre2_dfa_match.c | 3618 +++ pcre2/src/pcre2_error.c | 321 + pcre2/src/pcre2_find_bracket.c | 218 + pcre2/src/pcre2_internal.h | 1944 ++ pcre2/src/pcre2_intmodedep.h | 852 + pcre2/src/pcre2_jit_compile.c | 11503 ++++++++++ pcre2/src/pcre2_jit_match.c | 189 + pcre2/src/pcre2_jit_misc.c | 227 + pcre2/src/pcre2_jit_test.c | 1735 ++ pcre2/src/pcre2_maketables.c | 157 + pcre2/src/pcre2_match.c | 7243 ++++++ pcre2/src/pcre2_match_data.c | 147 + pcre2/src/pcre2_newline.c | 243 + pcre2/src/pcre2_ord2utf.c | 120 + pcre2/src/pcre2_pattern_info.c | 410 + pcre2/src/pcre2_printint.c | 832 + pcre2/src/pcre2_serialize.c | 258 + pcre2/src/pcre2_string_utils.c | 201 + pcre2/src/pcre2_study.c | 1575 ++ pcre2/src/pcre2_substitute.c | 850 + pcre2/src/pcre2_substring.c | 536 + pcre2/src/pcre2_tables.c | 765 + pcre2/src/pcre2_ucd.c | 3747 ++++ pcre2/src/pcre2_ucp.h | 268 + pcre2/src/pcre2_valid_utf.c | 398 + pcre2/src/pcre2_xclass.c | 271 + pcre2/src/pcre2demo.c | 423 + pcre2/src/pcre2grep.c | 3270 +++ pcre2/src/pcre2posix.c | 335 + pcre2/src/pcre2posix.h | 146 + pcre2/src/pcre2test.c | 7426 +++++++ pcre2/src/sljit/sljitConfig.h | 135 + pcre2/src/sljit/sljitConfigInternal.h | 713 + pcre2/src/sljit/sljitExecAllocator.c | 312 + pcre2/src/sljit/sljitLir.c | 2029 ++ pcre2/src/sljit/sljitLir.h | 1249 ++ pcre2/src/sljit/sljitNativeARM_32.c | 2566 +++ pcre2/src/sljit/sljitNativeARM_64.c | 2050 ++ pcre2/src/sljit/sljitNativeARM_T2_32.c | 2090 ++ pcre2/src/sljit/sljitNativeMIPS_32.c | 366 + pcre2/src/sljit/sljitNativeMIPS_64.c | 469 + pcre2/src/sljit/sljitNativeMIPS_common.c | 2138 ++ pcre2/src/sljit/sljitNativePPC_32.c | 269 + pcre2/src/sljit/sljitNativePPC_64.c | 421 + pcre2/src/sljit/sljitNativePPC_common.c | 2375 ++ pcre2/src/sljit/sljitNativeSPARC_32.c | 164 + pcre2/src/sljit/sljitNativeSPARC_common.c | 1435 ++ pcre2/src/sljit/sljitNativeTILEGX-encoder.c | 10159 +++++++++ pcre2/src/sljit/sljitNativeTILEGX_64.c | 2561 +++ pcre2/src/sljit/sljitNativeX86_32.c | 550 + pcre2/src/sljit/sljitNativeX86_64.c | 747 + pcre2/src/sljit/sljitNativeX86_common.c | 3004 +++ pcre2/src/sljit/sljitUtils.c | 334 + pcre2/test-driver | 148 + 113 files changed, 157381 insertions(+) create mode 100644 pcre2/.gitignore create mode 100755 pcre2/132html create mode 100644 pcre2/AUTHORS create mode 100644 pcre2/CMakeLists.txt create mode 100644 pcre2/COPYING create mode 100644 pcre2/ChangeLog create mode 100755 pcre2/CheckMan create mode 100755 pcre2/CleanTxt create mode 100755 pcre2/Detrail create mode 100644 pcre2/HACKING create mode 100644 pcre2/INSTALL create mode 100644 pcre2/LICENCE create mode 100644 pcre2/Makefile.am create mode 100644 pcre2/Makefile.in create mode 100644 pcre2/NEWS create mode 100644 pcre2/NON-AUTOTOOLS-BUILD create mode 100755 pcre2/PrepareRelease create mode 100644 pcre2/README create mode 100755 pcre2/RunGrepTest create mode 100755 pcre2/RunTest create mode 100644 pcre2/aclocal.m4 create mode 100755 pcre2/ar-lib create mode 100644 pcre2/cmake/COPYING-CMAKE-SCRIPTS create mode 100644 pcre2/cmake/FindEditline.cmake create mode 100644 pcre2/cmake/FindPackageHandleStandardArgs.cmake create mode 100644 pcre2/cmake/FindReadline.cmake create mode 100755 pcre2/compile create mode 100644 pcre2/config-cmake.h.in create mode 100755 pcre2/config.guess create mode 100755 pcre2/config.sub create mode 100755 pcre2/configure create mode 100644 pcre2/configure.ac create mode 100755 pcre2/depcomp create mode 100755 pcre2/install-sh create mode 100644 pcre2/libpcre2-16.pc.in create mode 100644 pcre2/libpcre2-32.pc.in create mode 100644 pcre2/libpcre2-8.pc.in create mode 100644 pcre2/libpcre2-posix.pc.in create mode 100644 pcre2/ltmain.sh create mode 100644 pcre2/m4/ax_pthread.m4 create mode 100644 pcre2/m4/libtool.m4 create mode 100644 pcre2/m4/ltoptions.m4 create mode 100644 pcre2/m4/ltsugar.m4 create mode 100644 pcre2/m4/ltversion.m4 create mode 100644 pcre2/m4/lt~obsolete.m4 create mode 100644 pcre2/m4/pcre2_visibility.m4 create mode 100755 pcre2/missing create mode 100644 pcre2/pcre2-config.in create mode 100755 pcre2/perltest.sh create mode 100644 pcre2/src/config.h.generic create mode 100644 pcre2/src/config.h.in create mode 100644 pcre2/src/dftables.c create mode 100644 pcre2/src/pcre2.h.generic create mode 100644 pcre2/src/pcre2.h.in create mode 100644 pcre2/src/pcre2_auto_possess.c create mode 100644 pcre2/src/pcre2_chartables.c.dist create mode 100644 pcre2/src/pcre2_compile.c create mode 100644 pcre2/src/pcre2_config.c create mode 100644 pcre2/src/pcre2_context.c create mode 100644 pcre2/src/pcre2_dfa_match.c create mode 100644 pcre2/src/pcre2_error.c create mode 100644 pcre2/src/pcre2_find_bracket.c create mode 100644 pcre2/src/pcre2_internal.h create mode 100644 pcre2/src/pcre2_intmodedep.h create mode 100644 pcre2/src/pcre2_jit_compile.c create mode 100644 pcre2/src/pcre2_jit_match.c create mode 100644 pcre2/src/pcre2_jit_misc.c create mode 100644 pcre2/src/pcre2_jit_test.c create mode 100644 pcre2/src/pcre2_maketables.c create mode 100644 pcre2/src/pcre2_match.c create mode 100644 pcre2/src/pcre2_match_data.c create mode 100644 pcre2/src/pcre2_newline.c create mode 100644 pcre2/src/pcre2_ord2utf.c create mode 100644 pcre2/src/pcre2_pattern_info.c create mode 100644 pcre2/src/pcre2_printint.c create mode 100644 pcre2/src/pcre2_serialize.c create mode 100644 pcre2/src/pcre2_string_utils.c create mode 100644 pcre2/src/pcre2_study.c create mode 100644 pcre2/src/pcre2_substitute.c create mode 100644 pcre2/src/pcre2_substring.c create mode 100644 pcre2/src/pcre2_tables.c create mode 100644 pcre2/src/pcre2_ucd.c create mode 100644 pcre2/src/pcre2_ucp.h create mode 100644 pcre2/src/pcre2_valid_utf.c create mode 100644 pcre2/src/pcre2_xclass.c create mode 100644 pcre2/src/pcre2demo.c create mode 100644 pcre2/src/pcre2grep.c create mode 100644 pcre2/src/pcre2posix.c create mode 100644 pcre2/src/pcre2posix.h create mode 100644 pcre2/src/pcre2test.c create mode 100644 pcre2/src/sljit/sljitConfig.h create mode 100644 pcre2/src/sljit/sljitConfigInternal.h create mode 100644 pcre2/src/sljit/sljitExecAllocator.c create mode 100644 pcre2/src/sljit/sljitLir.c create mode 100644 pcre2/src/sljit/sljitLir.h create mode 100644 pcre2/src/sljit/sljitNativeARM_32.c create mode 100644 pcre2/src/sljit/sljitNativeARM_64.c create mode 100644 pcre2/src/sljit/sljitNativeARM_T2_32.c create mode 100644 pcre2/src/sljit/sljitNativeMIPS_32.c create mode 100644 pcre2/src/sljit/sljitNativeMIPS_64.c create mode 100644 pcre2/src/sljit/sljitNativeMIPS_common.c create mode 100644 pcre2/src/sljit/sljitNativePPC_32.c create mode 100644 pcre2/src/sljit/sljitNativePPC_64.c create mode 100644 pcre2/src/sljit/sljitNativePPC_common.c create mode 100644 pcre2/src/sljit/sljitNativeSPARC_32.c create mode 100644 pcre2/src/sljit/sljitNativeSPARC_common.c create mode 100644 pcre2/src/sljit/sljitNativeTILEGX-encoder.c create mode 100644 pcre2/src/sljit/sljitNativeTILEGX_64.c create mode 100644 pcre2/src/sljit/sljitNativeX86_32.c create mode 100644 pcre2/src/sljit/sljitNativeX86_64.c create mode 100644 pcre2/src/sljit/sljitNativeX86_common.c create mode 100644 pcre2/src/sljit/sljitUtils.c create mode 100755 pcre2/test-driver diff --git a/pcre2/.gitignore b/pcre2/.gitignore new file mode 100644 index 000000000..fa91befa7 --- /dev/null +++ b/pcre2/.gitignore @@ -0,0 +1,15 @@ +!config.h.in +!configure +!doc/ +.deps +.dirstamp +.libs/ +*.la +*.lo +*.pc +libtool +pcre2_chartables.c +pcre2-config +pcre2test +pcre2.h +stamp-h1 \ No newline at end of file diff --git a/pcre2/132html b/pcre2/132html new file mode 100755 index 000000000..3a16a59e0 --- /dev/null +++ b/pcre2/132html @@ -0,0 +1,313 @@ +#! /usr/bin/perl -w + +# Script to turn PCRE2 man pages into HTML + + +# Subroutine to handle font changes and other escapes + +sub do_line { +my($s) = $_[0]; + +$s =~ s/ +$s =~ s/>/>/g; +$s =~ s"\\fI(.*?)\\f[RP]"$1"g; +$s =~ s"\\fB(.*?)\\f[RP]"$1"g; +$s =~ s"\\e"\\"g; +$s =~ s/(?<=Copyright )\(c\)/©/g; +$s; +} + +# Subroutine to ensure not in a paragraph + +sub end_para { +if ($inpara) + { + print TEMP "\n" if ($inpre); + print TEMP "

\n"; + } +$inpara = $inpre = 0; +$wrotetext = 0; +} + +# Subroutine to start a new paragraph + +sub new_para { +&end_para(); +print TEMP "

\n"; +$inpara = 1; +} + + +# Main program + +$innf = 0; +$inpara = 0; +$inpre = 0; +$wrotetext = 0; +$toc = 0; +$ref = 1; + +while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) + { + $toc = 1 if $ARGV[0] eq "-toc"; + shift; + } + +# Initial output to STDOUT + +print < + +$ARGV[0] specification + + +

$ARGV[0] man page

+

+Return to the PCRE2 index page. +

+

+This page is part of the PCRE2 HTML documentation. It was generated +automatically from the original man page. If there is any nonsense in it, +please consult the man page, in case the conversion went wrong. +
+End + +print "

    \n" if ($toc); + +open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n"; + +while () + { + # Handle lines beginning with a dot + + if (/^\./) + { + # Some of the PCRE2 man pages used to contain instances of .br. However, + # they should have all been removed because they cause trouble in some + # (other) automated systems that translate man pages to HTML. Complain if + # we find .br or .in (another macro that is deprecated). + + if (/^\.br/ || /^\.in/) + { + print STDERR "\n*** Deprecated macro encountered - rewrite needed\n"; + print STDERR "*** $_\n"; + die "*** Processing abandoned\n"; + } + + # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi. + + elsif (/^\.nf/) + { + $innf = 1; + } + + elsif (/^\.fi/) + { + $innf = 0; + } + + # Handling .sp is subtle. If it is inside a literal section, do nothing if + # the next line is a non literal text line; similarly, if not inside a + # literal section, do nothing if a literal follows, unless we are inside + # a .nf/.ne section. The point being that the
     and 
    that delimit + # literal sections will do the spacing. Always skip if no previous output. + + elsif (/^\.sp/) + { + if ($wrotetext) + { + $_ = ; + if ($inpre) + { + print TEMP "\n" if (/^[\s.]/); + } + else + { + print TEMP "
    \n
    \n" if ($innf || !/^[\s.]/); + } + redo; # Now process the lookahead line we just read + } + } + elsif (/^\.TP/ || /^\.PP/ || /^\.P/) + { + &new_para(); + } + elsif (/^\.SH\s*("?)(.*)\1/) + { + # Ignore the NAME section + if ($2 =~ /^NAME\b/) + { + ; + next; + } + + &end_para(); + my($title) = &do_line($2); + if ($toc) + { + printf("
  • $title\n", + $ref, $ref); + printf TEMP ("
    $title
    \n", + $ref); + $ref++; + } + else + { + print TEMP "
    \n$title\n
    \n"; + } + } + elsif (/^\.SS\s*("?)(.*)\1/) + { + &end_para(); + my($title) = &do_line($2); + print TEMP "
    \n$title\n
    \n"; + } + elsif (/^\.B\s*(.*)/) + { + &new_para() if (!$inpara); + $_ = &do_line($1); + s/"(.*?)"/$1/g; + print TEMP "$_\n"; + $wrotetext = 1; + } + elsif (/^\.I\s*(.*)/) + { + &new_para() if (!$inpara); + $_ = &do_line($1); + s/"(.*?)"/$1/g; + print TEMP "$_\n"; + $wrotetext = 1; + } + + # A comment that starts "HREF" takes the next line as a name that + # is turned into a hyperlink, using the text given, which might be + # in a special font. If it ends in () or (digits) or punctuation, they + # aren't part of the link. + + elsif (/^\.\\"\s*HREF/) + { + $_=; + chomp; + $_ = &do_line($_); + $_ =~ s/\s+$//; + $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/; + print TEMP "$_\n"; + } + + # A comment that starts "HTML" inserts literal HTML + + elsif (/^\.\\"\s*HTML\s*(.*)/) + { + print TEMP $1; + } + + # A comment that starts < inserts that HTML at the end of the + # *next* input line - so as not to get a newline between them. + + elsif (/^\.\\"\s*(<.*>)/) + { + my($markup) = $1; + $_=; + chomp; + $_ = &do_line($_); + $_ =~ s/\s+$//; + print TEMP "$_$markup\n"; + } + + # A comment that starts JOIN joins the next two lines together, with one + # space between them. Then that line is processed. This is used in some + # displays where two lines are needed for the "man" version. JOINSH works + # the same, except that it assumes this is a shell command, so removes + # continuation backslashes. + + elsif (/^\.\\"\s*JOIN(SH)?/) + { + my($one,$two); + $one = ; + $two = ; + $one =~ s/\s*\\e\s*$// if (defined($1)); + chomp($one); + $two =~ s/^\s+//; + $_ = "$one $two"; + redo; # Process the joined lines + } + + # .EX/.EE are used in the pcre2demo page to bracket the entire program, + # which is unmodified except for turning backslash into "\e". + + elsif (/^\.EX\s*$/) + { + print TEMP "
    \n";
    +      while ()
    +        {
    +        last if /^\.EE\s*$/;
    +        s/\\e/\\/g;
    +        s/&/&/g;
    +        s//>/g;
    +        print TEMP;
    +        }
    +      }
    +
    +    # Ignore anything not recognized
    +
    +    next;
    +    }
    +
    +  # Line does not begin with a dot. Replace blank lines with new paragraphs
    +
    +  if (/^\s*$/)
    +    {
    +    &end_para() if ($wrotetext);
    +    next;
    +    }
    +
    +  # Convert fonts changes and output an ordinary line. Ensure that indented
    +  # lines are marked as literal.
    +
    +  $_ = &do_line($_);
    +  &new_para() if (!$inpara);
    +
    +  if (/^\s/)
    +    {
    +    if (!$inpre)
    +      {
    +      print TEMP "
    \n";
    +      $inpre = 1;
    +      }
    +    }
    +  elsif ($inpre)
    +    {
    +    print TEMP "
    \n"; + $inpre = 0; + } + + # Add
    to the end of a non-literal line if we are within .nf/.fi + + $_ .= "
    \n" if (!$inpre && $innf); + + print TEMP; + $wrotetext = 1; + } + +# The TOC, if present, will have been written - terminate it + +print "
\n" if ($toc); + +# Copy the remainder to the standard output + +close(TEMP); +open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n"; + +print while (); + +print < +Return to the PCRE2 index page. +

+End + +close(TEMP); +unlink("/tmp/$$"); + +# End diff --git a/pcre2/AUTHORS b/pcre2/AUTHORS new file mode 100644 index 000000000..d9a0e1569 --- /dev/null +++ b/pcre2/AUTHORS @@ -0,0 +1,36 @@ +THE MAIN PCRE2 LIBRARY CODE +--------------------------- + +Written by: Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk + +University of Cambridge Computing Service, +Cambridge, England. + +Copyright (c) 1997-2016 University of Cambridge +All rights reserved + + +PCRE2 JUST-IN-TIME COMPILATION SUPPORT +-------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2016 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2016 Zoltan Herczeg +All rights reserved. + +#### diff --git a/pcre2/CMakeLists.txt b/pcre2/CMakeLists.txt new file mode 100644 index 000000000..2c84b054d --- /dev/null +++ b/pcre2/CMakeLists.txt @@ -0,0 +1,780 @@ +# CMakeLists.txt +# +# +# This file enables PCRE2 to be built with the CMake configuration and build +# tool. Download CMake in source or binary form from http://www.cmake.org/ +# Converted to support PCRE2 from the original PCRE file, August 2014. +# +# Original listfile by Christian Ehrlicher +# Refined and expanded by Daniel Richard G. +# 2007-09-14 mod by Sheri so 7.4 supported configuration options can be entered +# 2007-09-19 Adjusted by PH to retain previous default settings +# 2007-12-26 (a) On UNIX, use names libpcre instead of just pcre +# (b) Ensure pcretest and pcregrep link with the local library, +# not a previously-installed one. +# (c) Add PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, and +# PCRE_SUPPORT_LIBBZ2. +# 2008-01-20 Brought up to date to include several new features by Christian +# Ehrlicher. +# 2008-01-22 Sheri added options for backward compatibility of library names +# when building with minGW: +# if "ON", NON_STANDARD_LIB_PREFIX causes shared libraries to +# be built without "lib" as prefix. (The libraries will be named +# pcre.dll, pcreposix.dll and pcrecpp.dll). +# if "ON", NON_STANDARD_LIB_SUFFIX causes shared libraries to +# be built with suffix of "-0.dll". (The libraries will be named +# libpcre-0.dll, libpcreposix-0.dll and libpcrecpp-0.dll - same names +# built by default with Configure and Make. +# 2008-01-23 PH removed the automatic build of pcredemo. +# 2008-04-22 PH modified READLINE support so it finds NCURSES when needed. +# 2008-07-03 PH updated for revised UCP property support (change of files) +# 2009-03-23 PH applied Steven Van Ingelgem's patch to change the name +# CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE +# is included within another project. +# 2009-03-23 PH applied a modified version of Steven Van Ingelgem's patches to +# add options to stop the building of pcregrep and the tests, and +# to disable the final configuration report. +# 2009-04-11 PH applied Christian Ehrlicher's patch to show compiler flags that +# are set by specifying a release type. +# 2010-01-02 PH added test for stdint.h +# 2010-03-02 PH added test for inttypes.h +# 2011-08-01 PH added PCREGREP_BUFSIZE +# 2011-08-22 PH added PCRE_SUPPORT_JIT +# 2011-09-06 PH modified WIN32 ADD_TEST line as suggested by Sergey Cherepanov +# 2011-09-06 PH added PCRE_SUPPORT_PCREGREP_JIT +# 2011-10-04 Sheri added support for including coff data in windows shared libraries +# compiled with MINGW if pcre.rc and/or pcreposix.rc are placed in +# the source dir by the user prior to building +# 2011-10-04 Sheri changed various add_test's to use exes' location built instead +# of DEBUG location only (likely only matters in MSVC) +# 2011-10-04 Sheri added scripts to provide needed variables to RunTest and +# RunGrepTest (used for UNIX and Msys) +# 2011-10-04 Sheri added scripts to provide needed variables and to execute +# RunTest.bat in Win32 (for effortless testing with "make test") +# 2011-10-04 Sheri Increased minimum required cmake version +# 2012-01-06 PH removed pcre_info.c and added pcre_string_utils.c +# 2012-01-10 Zoltan Herczeg added libpcre16 support +# 2012-01-13 Stephen Kelly added out of source build support +# 2012-01-17 PH applied Stephen Kelly's patch to parse the version data out +# of the configure.ac file +# 2012-02-26 PH added support for libedit +# 2012-09-06 PH added support for PCRE_EBCDIC_NL25 +# 2012-09-08 ChPe added PCRE32 support +# 2012-10-23 PH added support for VALGRIND and GCOV +# 2012-12-08 PH added patch from Daniel Richard G to quash some MSVC warnings +# 2013-07-01 PH realized that the "support" for GCOV was a total nonsense and +# so it has been removed. +# 2013-10-08 PH got rid of the "source" command, which is a bash-ism (use ".") +# 2013-11-05 PH added support for PARENS_NEST_LIMIT +# 2014-08-29 PH converted the file for PCRE2 (which has no C++). +# 2015-04-24 PH added support for PCRE2_DEBUG +# 2015-07-16 PH updated for new pcre2_find_bracket source module +# 2015-08-24 PH correct C_FLAGS setting (patch from Roy Ivy III) +# 2015-10=16 PH added support for never-backslash-C + +PROJECT(PCRE2 C) + +# Increased minimum to 2.8.0 to support newer add_test features. Set policy +# CMP0026 to avoid warnings for the use of LOCATION in GET_TARGET_PROPERTY. + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) +CMAKE_POLICY(SET CMP0026 OLD) + +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${PROJECT_SOURCE_DIR}/src") + +# external packages +FIND_PACKAGE( BZip2 ) +FIND_PACKAGE( ZLIB ) +FIND_PACKAGE( Readline ) +FIND_PACKAGE( Editline ) + +# Configuration checks + +INCLUDE(CheckIncludeFile) +INCLUDE(CheckFunctionExists) +INCLUDE(CheckTypeSize) + +CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) +CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) +CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) +CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) + +CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) +CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) +CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) + +# User-configurable options +# +# Note: CMakeSetup displays these in alphabetical order, regardless of +# the order we use here. + +SET(BUILD_SHARED_LIBS OFF CACHE BOOL + "Build shared libraries instead of static ones.") + +OPTION(PCRE2_BUILD_PCRE2_8 "Build 8 bit PCRE2 library" ON) + +OPTION(PCRE2_BUILD_PCRE2_16 "Build 16 bit PCRE2 library" OFF) + +OPTION(PCRE2_BUILD_PCRE2_32 "Build 32 bit PCRE2 library" OFF) + +OPTION(PCRE2_DEBUG "Include debugging code" OFF) + +SET(PCRE2_EBCDIC OFF CACHE BOOL + "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems.)") + +SET(PCRE2_EBCDIC_NL25 OFF CACHE BOOL + "Use 0x25 as EBCDIC NL character instead of 0x15; implies EBCDIC.") + +SET(PCRE2_LINK_SIZE "2" CACHE STRING + "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") + +SET(PCRE2_PARENS_NEST_LIMIT "250" CACHE STRING + "Default nested parentheses limit. See PARENS_NEST_LIMIT in config.h.in for details.") + +SET(PCRE2_MATCH_LIMIT "10000000" CACHE STRING + "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") + +SET(PCRE2_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING + "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") + +SET(PCRE2GREP_BUFSIZE "20480" CACHE STRING + "Buffer size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.") + +SET(PCRE2_NEWLINE "LF" CACHE STRING + "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).") + +SET(PCRE2_HEAP_MATCH_RECURSE OFF CACHE BOOL + "If ON, then don't use stack recursion when matching. See HEAP_MATCH_RECURSE in config.h.in for details.") + +SET(PCRE2_SUPPORT_JIT OFF CACHE BOOL + "Enable support for Just-in-time compiling.") + +SET(PCRE2_SUPPORT_PCRE2GREP_JIT ON CACHE BOOL + "Enable use of Just-in-time compiling in pcre2grep.") + +SET(PCRE2_SUPPORT_UNICODE ON CACHE BOOL + "Enable support for Unicode and UTF-8/UTF-16/UTF-32 encoding.") + +SET(PCRE2_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL + "ON=Backslash-R matches only LF CR and CRLF, OFF=Backslash-R matches all Unicode Linebreaks") + +SET(PCRE2_NEVER_BACKSLASH_C OFF CACHE BOOL + "If ON, backslash-C (upper case C) is locked out.") + +SET(PCRE2_SUPPORT_VALGRIND OFF CACHE BOOL + "Enable Valgrind support.") + +OPTION(PCRE2_SHOW_REPORT "Show the final configuration report" ON) +OPTION(PCRE2_BUILD_PCRE2GREP "Build pcre2grep" ON) +OPTION(PCRE2_BUILD_TESTS "Build the tests" ON) + +IF (MINGW) + OPTION(NON_STANDARD_LIB_PREFIX + "ON=Shared libraries built in mingw will be named pcre2.dll, etc., instead of libpcre2.dll, etc." + OFF) + + OPTION(NON_STANDARD_LIB_SUFFIX + "ON=Shared libraries built in mingw will be named libpcre2-0.dll, etc., instead of libpcre2.dll, etc." + OFF) +ENDIF(MINGW) + +IF(MSVC) + OPTION(INSTALL_MSVC_PDB + "ON=Install .pdb files built by MSVC, if generated" + OFF) +ENDIF(MSVC) + +# bzip2 lib +IF(BZIP2_FOUND) + OPTION (PCRE2_SUPPORT_LIBBZ2 "Enable support for linking pcre2grep with libbz2." ON) +ENDIF(BZIP2_FOUND) +IF(PCRE2_SUPPORT_LIBBZ2) + INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) +ENDIF(PCRE2_SUPPORT_LIBBZ2) + +# zlib +IF(ZLIB_FOUND) + OPTION (PCRE2_SUPPORT_LIBZ "Enable support for linking pcre2grep with libz." ON) +ENDIF(ZLIB_FOUND) +IF(PCRE2_SUPPORT_LIBZ) + INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) +ENDIF(PCRE2_SUPPORT_LIBZ) + +# editline lib +IF(EDITLINE_FOUND) + OPTION (PCRE2_SUPPORT_LIBEDIT "Enable support for linking pcre2test with libedit." OFF) +ENDIF(EDITLINE_FOUND) +IF(PCRE2_SUPPORT_LIBEDIT) + INCLUDE_DIRECTORIES(${EDITLINE_INCLUDE_DIR}) +ENDIF(PCRE2_SUPPORT_LIBEDIT) + +# readline lib +IF(READLINE_FOUND) + OPTION (PCRE2_SUPPORT_LIBREADLINE "Enable support for linking pcre2test with libreadline." ON) +ENDIF(READLINE_FOUND) +IF(PCRE2_SUPPORT_LIBREADLINE) + INCLUDE_DIRECTORIES(${READLINE_INCLUDE_DIR}) +ENDIF(PCRE2_SUPPORT_LIBREADLINE) + +# Prepare build configuration + +IF(NOT BUILD_SHARED_LIBS) + SET(PCRE2_STATIC 1) +ENDIF(NOT BUILD_SHARED_LIBS) + +IF(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32) + MESSAGE(FATAL_ERROR "At least one of PCRE2_BUILD_PCRE2_8, PCRE2_BUILD_PCRE2_16 or PCRE2_BUILD_PCRE2_32 must be enabled") +ENDIF(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32) + +IF(PCRE2_BUILD_PCRE2_8) + SET(SUPPORT_PCRE2_8 1) +ENDIF(PCRE2_BUILD_PCRE2_8) + +IF(PCRE2_BUILD_PCRE2_16) + SET(SUPPORT_PCRE2_16 1) +ENDIF(PCRE2_BUILD_PCRE2_16) + +IF(PCRE2_BUILD_PCRE2_32) + SET(SUPPORT_PCRE2_32 1) +ENDIF(PCRE2_BUILD_PCRE2_32) + +IF(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8) + MESSAGE(STATUS "** PCRE2_BUILD_PCRE2_8 must be enabled for the pcre2grep program") + SET(PCRE2_BUILD_PCRE2GREP OFF) +ENDIF(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8) + +IF(PCRE2_SUPPORT_LIBREADLINE AND PCRE2_SUPPORT_LIBEDIT) + MESSAGE(FATAL_ERROR "Only one of libreadline or libeditline can be specified") +ENDIF(PCRE2_SUPPORT_LIBREADLINE AND PCRE2_SUPPORT_LIBEDIT) + +IF(PCRE2_SUPPORT_BSR_ANYCRLF) + SET(BSR_ANYCRLF 1) +ENDIF(PCRE2_SUPPORT_BSR_ANYCRLF) + +IF(PCRE2_NEVER_BACKSLASH_C) + SET(NEVER_BACKSLASH_C 1) +ENDIF(PCRE2_NEVER_BACKSLASH_C) + +IF(PCRE2_SUPPORT_UNICODE) + SET(SUPPORT_UNICODE 1) +ENDIF(PCRE2_SUPPORT_UNICODE) + +IF(PCRE2_SUPPORT_JIT) + SET(SUPPORT_JIT 1) +ENDIF(PCRE2_SUPPORT_JIT) + +IF(PCRE2_SUPPORT_PCRE2GREP_JIT) + SET(SUPPORT_PCRE2GREP_JIT 1) +ENDIF(PCRE2_SUPPORT_PCRE2GREP_JIT) + +IF(PCRE2_SUPPORT_VALGRIND) + SET(SUPPORT_VALGRIND 1) +ENDIF(PCRE2_SUPPORT_VALGRIND) + +# This next one used to reference ${READLINE_LIBRARY}) +# but I was advised to add the NCURSES test as well, along with +# some modifications to cmake/FindReadline.cmake which should +# make it possible to override the default if necessary. PH + +IF(PCRE2_SUPPORT_LIBREADLINE) + SET(SUPPORT_LIBREADLINE 1) + SET(PCRE2TEST_LIBS ${READLINE_LIBRARY} ${NCURSES_LIBRARY}) +ENDIF(PCRE2_SUPPORT_LIBREADLINE) + +# libedit is a plug-compatible alternative to libreadline + +IF(PCRE2_SUPPORT_LIBEDIT) + SET(SUPPORT_LIBEDIT 1) + SET(PCRE2TEST_LIBS ${EDITLINE_LIBRARY} ${NCURSES_LIBRARY}) +ENDIF(PCRE2_SUPPORT_LIBEDIT) + +IF(PCRE2_SUPPORT_LIBZ) + SET(SUPPORT_LIBZ 1) + SET(PCRE2GREP_LIBS ${PCRE2GREP_LIBS} ${ZLIB_LIBRARIES}) +ENDIF(PCRE2_SUPPORT_LIBZ) + +IF(PCRE2_SUPPORT_LIBBZ2) + SET(SUPPORT_LIBBZ2 1) + SET(PCRE2GREP_LIBS ${PCRE2GREP_LIBS} ${BZIP2_LIBRARIES}) +ENDIF(PCRE2_SUPPORT_LIBBZ2) + +SET(NEWLINE_DEFAULT "") + +IF(PCRE2_NEWLINE STREQUAL "CR") + SET(NEWLINE_DEFAULT "1") +ENDIF(PCRE2_NEWLINE STREQUAL "CR") +IF(PCRE2_NEWLINE STREQUAL "LF") + SET(NEWLINE_DEFAULT "2") +ENDIF(PCRE2_NEWLINE STREQUAL "LF") +IF(PCRE2_NEWLINE STREQUAL "CRLF") + SET(NEWLINE_DEFAULT "3") +ENDIF(PCRE2_NEWLINE STREQUAL "CRLF") +IF(PCRE2_NEWLINE STREQUAL "ANY") + SET(NEWLINE_DEFAULT "4") +ENDIF(PCRE2_NEWLINE STREQUAL "ANY") +IF(PCRE2_NEWLINE STREQUAL "ANYCRLF") + SET(NEWLINE_DEFAULT "5") +ENDIF(PCRE2_NEWLINE STREQUAL "ANYCRLF") + +IF(NEWLINE_DEFAULT STREQUAL "") + MESSAGE(FATAL_ERROR "The PCRE2_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") +ENDIF(NEWLINE_DEFAULT STREQUAL "") + +IF(PCRE2_EBCDIC) + SET(EBCDIC 1) +ENDIF(PCRE2_EBCDIC) + +IF(PCRE2_EBCDIC_NL25) + SET(EBCDIC 1) + SET(EBCDIC_NL25 1) +ENDIF(PCRE2_EBCDIC_NL25) + +IF(PCRE2_HEAP_MATCH_RECURSE) + SET(HEAP_MATCH_RECURSE 1) +ENDIF(PCRE2_HEAP_MATCH_RECURSE) + +# Output files + +CONFIGURE_FILE(config-cmake.h.in + ${PROJECT_BINARY_DIR}/config.h + @ONLY) + +# Parse version numbers and date out of configure.ac + +file(STRINGS ${PROJECT_SOURCE_DIR}/configure.ac + configure_lines + LIMIT_COUNT 50 # Read only the first 50 lines of the file +) + +set(SEARCHED_VARIABLES "pcre2_major" "pcre2_minor" "pcre2_prerelease" "pcre2_date") +foreach(configure_line ${configure_lines}) + foreach(_substitution_variable ${SEARCHED_VARIABLES}) + string(TOUPPER ${_substitution_variable} _substitution_variable_upper) + if (NOT ${_substitution_variable_upper}) + string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MACTHED_STRING ${configure_line}) + if (CMAKE_MATCH_1) + set(${_substitution_variable_upper} ${CMAKE_MATCH_1}) + endif() + endif() + endforeach() +endforeach() + +CONFIGURE_FILE(src/pcre2.h.in + ${PROJECT_BINARY_DIR}/pcre2.h + @ONLY) + +# What about pcre2-config and libpcre2.pc? + +# Character table generation + +OPTION(PCRE2_REBUILD_CHARTABLES "Rebuild char tables" OFF) +IF(PCRE2_REBUILD_CHARTABLES) + ADD_EXECUTABLE(dftables src/dftables.c) + ADD_CUSTOM_COMMAND( + COMMENT "Generating character tables (pcre2_chartables.c) for current locale" + DEPENDS dftables + COMMAND dftables + ARGS ${PROJECT_BINARY_DIR}/pcre2_chartables.c + OUTPUT ${PROJECT_BINARY_DIR}/pcre2_chartables.c + ) +ELSE(PCRE2_REBUILD_CHARTABLES) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/src/pcre2_chartables.c.dist + ${PROJECT_BINARY_DIR}/pcre2_chartables.c + COPYONLY) +ENDIF(PCRE2_REBUILD_CHARTABLES) + +# Source code + +SET(PCRE2_HEADERS ${PROJECT_BINARY_DIR}/pcre2.h) + +SET(PCRE2_SOURCES + src/pcre2_auto_possess.c + ${PROJECT_BINARY_DIR}/pcre2_chartables.c + src/pcre2_compile.c + src/pcre2_config.c + src/pcre2_context.c + src/pcre2_dfa_match.c + src/pcre2_error.c + src/pcre2_find_bracket.c + src/pcre2_jit_compile.c + src/pcre2_maketables.c + src/pcre2_match.c + src/pcre2_match_data.c + src/pcre2_newline.c + src/pcre2_ord2utf.c + src/pcre2_pattern_info.c + src/pcre2_serialize.c + src/pcre2_string_utils.c + src/pcre2_study.c + src/pcre2_substitute.c + src/pcre2_substring.c + src/pcre2_tables.c + src/pcre2_ucd.c + src/pcre2_valid_utf.c + src/pcre2_xclass.c +) + +SET(PCRE2POSIX_HEADERS src/pcre2posix.h) +SET(PCRE2POSIX_SOURCES src/pcre2posix.c) + +IF(MINGW AND NOT PCRE2_STATIC) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre2.o +PRE-LINK +COMMAND windres ARGS pcre2.rc pcre2.o +WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +COMMENT Using pcre2 coff info in mingw build) +SET(PCRE2_SOURCES + ${PCRE2_SOURCES} ${PROJECT_SOURCE_DIR}/pcre2.o +) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre2posix.o +PRE-LINK +COMMAND windres ARGS pcre2posix.rc pcre2posix.o +WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +COMMENT Using pcre2posix coff info in mingw build) +SET(PCRE2POSIX_SOURCES + ${PCRE2POSIX_SOURCES} ${PROJECT_SOURCE_DIR}/pcre2posix.o +) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) +ENDIF(MINGW AND NOT PCRE2_STATIC) + +IF(MSVC AND NOT PCRE2_STATIC) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) +SET(PCRE2_SOURCES + ${PCRE2_SOURCES} pcre2.rc) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) +SET(PCRE2POSIX_SOURCES + ${PCRE2POSIX_SOURCES} pcre2posix.rc) +ENDIF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) +ENDIF(MSVC AND NOT PCRE2_STATIC) + +# Build setup + +ADD_DEFINITIONS(-DHAVE_CONFIG_H) + +IF(MSVC) + ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) +ENDIF(MSVC) + +SET(CMAKE_INCLUDE_CURRENT_DIR 1) +# needed to make sure to not link debug libs +# against release libs and vice versa +IF(WIN32) + SET(CMAKE_DEBUG_POSTFIX "d") +ENDIF(WIN32) + +SET(targets) + +# 8-bit library + +IF(PCRE2_BUILD_PCRE2_8) +ADD_LIBRARY(pcre2-8 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) +SET_PROPERTY(TARGET pcre2-8 + PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) +SET(targets ${targets} pcre2-8) +ADD_LIBRARY(pcre2posix ${PCRE2POSIX_HEADERS} ${PCRE2POSIX_SOURCES}) +SET_PROPERTY(TARGET pcre2posix + PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) +SET(targets ${targets} pcre2posix) +TARGET_LINK_LIBRARIES(pcre2posix pcre2-8) + +IF(MINGW AND NOT PCRE2_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES PREFIX "") + ENDIF(NON_STANDARD_LIB_PREFIX) + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES SUFFIX "-0.dll") + ENDIF(NON_STANDARD_LIB_SUFFIX) +ENDIF(MINGW AND NOT PCRE2_STATIC) +ENDIF(PCRE2_BUILD_PCRE2_8) + +# 16-bit library + +IF(PCRE2_BUILD_PCRE2_16) +ADD_LIBRARY(pcre2-16 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) +SET_PROPERTY(TARGET pcre2-16 + PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=16) +SET(targets ${targets} pcre2-16) + +IF(MINGW AND NOT PCRE2_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcre2-16 PROPERTIES PREFIX "") + ENDIF(NON_STANDARD_LIB_PREFIX) + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre2-16 PROPERTIES SUFFIX "-0.dll") + ENDIF(NON_STANDARD_LIB_SUFFIX) +ENDIF(MINGW AND NOT PCRE2_STATIC) +ENDIF(PCRE2_BUILD_PCRE2_16) + +# 32-bit library + +IF(PCRE2_BUILD_PCRE2_32) +ADD_LIBRARY(pcre2-32 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) +SET_PROPERTY(TARGET pcre2-32 + PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=32) +SET(targets ${targets} pcre2-32) + +IF(MINGW AND NOT PCRE2_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcre2-32 PROPERTIES PREFIX "") + ENDIF(NON_STANDARD_LIB_PREFIX) + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre2-32 PROPERTIES SUFFIX "-0.dll") + ENDIF(NON_STANDARD_LIB_SUFFIX) +ENDIF(MINGW AND NOT PCRE2_STATIC) +ENDIF(PCRE2_BUILD_PCRE2_32) + +# Executables + +IF(PCRE2_BUILD_PCRE2GREP) + ADD_EXECUTABLE(pcre2grep src/pcre2grep.c) + SET_PROPERTY(TARGET pcre2grep + PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) + SET(targets ${targets} pcre2grep) + TARGET_LINK_LIBRARIES(pcre2grep pcre2posix ${PCRE2GREP_LIBS}) +ENDIF(PCRE2_BUILD_PCRE2GREP) + +# Testing + +IF(PCRE2_BUILD_TESTS) + ENABLE_TESTING() + + SET(PCRE2TEST_SOURCES src/pcre2test.c) + + ADD_EXECUTABLE(pcre2test ${PCRE2TEST_SOURCES}) + SET(targets ${targets} pcre2test) + IF(PCRE2_BUILD_PCRE2_8) + LIST(APPEND PCRE2TEST_LIBS pcre2posix pcre2-8) + ENDIF(PCRE2_BUILD_PCRE2_8) + IF(PCRE2_BUILD_PCRE2_16) + LIST(APPEND PCRE2TEST_LIBS pcre2-16) + ENDIF(PCRE2_BUILD_PCRE2_16) + IF(PCRE2_BUILD_PCRE2_32) + LIST(APPEND PCRE2TEST_LIBS pcre2-32) + ENDIF(PCRE2_BUILD_PCRE2_32) + TARGET_LINK_LIBRARIES(pcre2test ${PCRE2TEST_LIBS}) + + IF(PCRE2_SUPPORT_JIT) + ADD_EXECUTABLE(pcre2_jit_test src/pcre2_jit_test.c) + SET(targets ${targets} pcre2_jit_test) + SET(PCRE2_JIT_TEST_LIBS ) + IF(PCRE2_BUILD_PCRE2_8) + LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-8) + ENDIF(PCRE2_BUILD_PCRE2_8) + IF(PCRE2_BUILD_PCRE2_16) + LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-16) + ENDIF(PCRE2_BUILD_PCRE2_16) + IF(PCRE2_BUILD_PCRE2_32) + LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-32) + ENDIF(PCRE2_BUILD_PCRE2_32) + TARGET_LINK_LIBRARIES(pcre2_jit_test ${PCRE2_JIT_TEST_LIBS}) + ENDIF(PCRE2_SUPPORT_JIT) + + # exes in Debug location tested by the RunTest shell script + # via "make test" + + IF(PCRE2_BUILD_PCRE2GREP) + GET_TARGET_PROPERTY(PCRE2GREP_EXE pcre2grep DEBUG_LOCATION) + ENDIF(PCRE2_BUILD_PCRE2GREP) + + GET_TARGET_PROPERTY(PCRE2TEST_EXE pcre2test DEBUG_LOCATION) + +# ================================================= + # Write out a CTest configuration file + # + FILE(WRITE ${PROJECT_BINARY_DIR}/CTestCustom.ctest + "# This is a generated file. +MESSAGE(\"When testing is complete, review test output in the +\\\"${PROJECT_BINARY_DIR}/Testing/Temporary\\\" folder.\") +MESSAGE(\" \") +") + + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_test.sh + "#! /bin/sh +# This is a generated file. +. ${PROJECT_SOURCE_DIR}/RunTest +if test \"$?\" != \"0\"; then exit 1; fi +# End +") + + IF(UNIX) + ADD_TEST(pcre2_test sh ${PROJECT_BINARY_DIR}/pcre2_test.sh) + ENDIF(UNIX) + + IF(PCRE2_BUILD_PCRE2GREP) + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh + "#! /bin/sh +# This is a generated file. +. ${PROJECT_SOURCE_DIR}/RunGrepTest +if test \"$?\" != \"0\"; then exit 1; fi +# End +") + + IF(UNIX) + ADD_TEST(pcre2_grep_test sh ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh) + ENDIF(UNIX) + ENDIF(PCRE2_BUILD_PCRE2GREP) + + IF(WIN32) + # Provide environment for executing the bat file version of RunTest + FILE(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} winsrc) + FILE(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} winbin) + FILE(TO_NATIVE_PATH ${PCRE2TEST_EXE} winexe) + + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_test.bat + "\@REM This is a generated file. +\@echo off +setlocal +SET srcdir=\"${winsrc}\" +SET pcre2test=\"${winexe}\" +if not [%CMAKE_CONFIG_TYPE%]==[] SET pcre2test=\"${winbin}\\%CMAKE_CONFIG_TYPE%\\pcre2test.exe\" +call %srcdir%\\RunTest.Bat +if errorlevel 1 exit /b 1 +echo RunTest.bat tests successfully completed +") + + ADD_TEST(NAME pcre2_test_bat + COMMAND pcre2_test.bat) + SET_TESTS_PROPERTIES(pcre2_test_bat PROPERTIES + PASS_REGULAR_EXPRESSION "RunTest\\.bat tests successfully completed") + + IF("$ENV{OSTYPE}" STREQUAL "msys") + # Both the sh and bat file versions of RunTest are run if make test is used + # in msys + ADD_TEST(pcre2_test_sh sh.exe ${PROJECT_BINARY_DIR}/pcre2_test.sh) + IF(PCRE2_BUILD_PCRE2GREP) + ADD_TEST(pcre2_grep_test sh.exe ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh) + ENDIF(PCRE2_BUILD_PCRE2GREP) + ENDIF("$ENV{OSTYPE}" STREQUAL "msys") + ENDIF(WIN32) + + # Changed to accommodate testing whichever location was just built + + IF(PCRE2_SUPPORT_JIT) + ADD_TEST(pcre2_jit_test pcre2_jit_test) + ENDIF(PCRE2_SUPPORT_JIT) + +ENDIF(PCRE2_BUILD_TESTS) + +# Installation + +SET(CMAKE_INSTALL_ALWAYS 1) + +INSTALL(TARGETS ${targets} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + +INSTALL(FILES ${PCRE2_HEADERS} ${PCRE2POSIX_HEADERS} DESTINATION include) + +FILE(GLOB html ${PROJECT_SOURCE_DIR}/doc/html/*.html) +FILE(GLOB man1 ${PROJECT_SOURCE_DIR}/doc/*.1) +FILE(GLOB man3 ${PROJECT_SOURCE_DIR}/doc/*.3) + +FOREACH(man ${man3}) + GET_FILENAME_COMPONENT(man_tmp ${man} NAME) + SET(man3_new ${man3} ${man}) +ENDFOREACH(man ${man3}) +SET(man3 ${man3_new}) + +INSTALL(FILES ${man1} DESTINATION man/man1) +INSTALL(FILES ${man3} DESTINATION man/man3) +INSTALL(FILES ${html} DESTINATION share/doc/pcre2/html) + +IF(MSVC AND INSTALL_MSVC_PDB) + INSTALL(FILES ${PROJECT_BINARY_DIR}/pcre2.pdb + ${PROJECT_BINARY_DIR}/pcre2posix.pdb + DESTINATION bin + CONFIGURATIONS RelWithDebInfo) + INSTALL(FILES ${PROJECT_BINARY_DIR}/pcre2d.pdb + ${PROJECT_BINARY_DIR}/pcre2posixd.pdb + DESTINATION bin + CONFIGURATIONS Debug) +ENDIF(MSVC AND INSTALL_MSVC_PDB) + +# Help, only for nice output +IF(BUILD_SHARED_LIBS) + SET(BUILD_STATIC_LIBS OFF) +ELSE(BUILD_SHARED_LIBS) + SET(BUILD_STATIC_LIBS ON) +ENDIF(BUILD_SHARED_LIBS) + +IF(PCRE2_SHOW_REPORT) + STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) + IF (CMAKE_C_FLAGS) + SET(cfsp " ") + ENDIF(CMAKE_C_FLAGS) + MESSAGE(STATUS "") + MESSAGE(STATUS "") + MESSAGE(STATUS "PCRE2 configuration summary:") + MESSAGE(STATUS "") + MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}") + MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}") + MESSAGE(STATUS " C compiler flags ................ : ${CMAKE_C_FLAGS}${cfsp}${CMAKE_C_FLAGS_${buildtype}}") + MESSAGE(STATUS "") + MESSAGE(STATUS " Build 8 bit PCRE2 library ....... : ${PCRE2_BUILD_PCRE2_8}") + MESSAGE(STATUS " Build 16 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_16}") + MESSAGE(STATUS " Build 32 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_32}") + MESSAGE(STATUS " Enable JIT compiling support .... : ${PCRE2_SUPPORT_JIT}") + MESSAGE(STATUS " Enable Unicode support .......... : ${PCRE2_SUPPORT_UNICODE}") + MESSAGE(STATUS " Newline char/sequence ........... : ${PCRE2_NEWLINE}") + MESSAGE(STATUS " \\R matches only ANYCRLF ......... : ${PCRE2_SUPPORT_BSR_ANYCRLF}") + MESSAGE(STATUS " \\C is disabled .................. : ${PCRE2_NEVER_BACKSLASH_C}") + MESSAGE(STATUS " EBCDIC coding ................... : ${PCRE2_EBCDIC}") + MESSAGE(STATUS " EBCDIC coding with NL=0x25 ...... : ${PCRE2_EBCDIC_NL25}") + MESSAGE(STATUS " Rebuild char tables ............. : ${PCRE2_REBUILD_CHARTABLES}") + MESSAGE(STATUS " Use heap recursion .............. : ${PCRE2_HEAP_MATCH_RECURSE}") + MESSAGE(STATUS " Internal link size .............. : ${PCRE2_LINK_SIZE}") + MESSAGE(STATUS " Parentheses nest limit .......... : ${PCRE2_PARENS_NEST_LIMIT}") + MESSAGE(STATUS " Match limit ..................... : ${PCRE2_MATCH_LIMIT}") + MESSAGE(STATUS " Match limit recursion ........... : ${PCRE2_MATCH_LIMIT_RECURSION}") + MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") + MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") + MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}") + MESSAGE(STATUS " Enable JIT in pcre2grep ......... : ${PCRE2_SUPPORT_PCRE2GREP_JIT}") + MESSAGE(STATUS " Buffer size for pcre2grep ....... : ${PCRE2GREP_BUFSIZE}") + MESSAGE(STATUS " Build tests (implies pcre2test . : ${PCRE2_BUILD_TESTS}") + MESSAGE(STATUS " and pcre2grep)") + IF(ZLIB_FOUND) + MESSAGE(STATUS " Link pcre2grep with libz ........ : ${PCRE2_SUPPORT_LIBZ}") + ELSE(ZLIB_FOUND) + MESSAGE(STATUS " Link pcre2grep with libz ........ : Library not found" ) + ENDIF(ZLIB_FOUND) + IF(BZIP2_FOUND) + MESSAGE(STATUS " Link pcre2grep with libbz2 ...... : ${PCRE2_SUPPORT_LIBBZ2}") + ELSE(BZIP2_FOUND) + MESSAGE(STATUS " Link pcre2grep with libbz2 ...... : Library not found" ) + ENDIF(BZIP2_FOUND) + IF(EDITLINE_FOUND) + MESSAGE(STATUS " Link pcre2test with libeditline . : ${PCRE2_SUPPORT_LIBEDIT}") + ELSE(EDITLINE_FOUND) + MESSAGE(STATUS " Link pcre2test with libeditline . : Library not found" ) + ENDIF(EDITLINE_FOUND) + IF(READLINE_FOUND) + MESSAGE(STATUS " Link pcre2test with libreadline . : ${PCRE2_SUPPORT_LIBREADLINE}") + ELSE(READLINE_FOUND) + MESSAGE(STATUS " Link pcre2test with libreadline . : Library not found" ) + ENDIF(READLINE_FOUND) + MESSAGE(STATUS " Support Valgrind .................: ${PCRE2_SUPPORT_VALGRIND}") + + IF(MINGW AND NOT PCRE2_STATIC) + MESSAGE(STATUS " Non-standard dll names (prefix) . : ${NON_STANDARD_LIB_PREFIX}") + MESSAGE(STATUS " Non-standard dll names (suffix) . : ${NON_STANDARD_LIB_SUFFIX}") + ENDIF(MINGW AND NOT PCRE2_STATIC) + + IF(MSVC) + MESSAGE(STATUS " Install MSVC .pdb files ..........: ${INSTALL_MSVC_PDB}") + ENDIF(MSVC) + + MESSAGE(STATUS "") +ENDIF(PCRE2_SHOW_REPORT) + +# end CMakeLists.txt diff --git a/pcre2/COPYING b/pcre2/COPYING new file mode 100644 index 000000000..c233950f6 --- /dev/null +++ b/pcre2/COPYING @@ -0,0 +1,5 @@ +PCRE2 LICENCE + +Please see the file LICENCE in the PCRE2 distribution for licensing details. + +End diff --git a/pcre2/ChangeLog b/pcre2/ChangeLog new file mode 100644 index 000000000..2035490c6 --- /dev/null +++ b/pcre2/ChangeLog @@ -0,0 +1,758 @@ +Change Log for PCRE2 +-------------------- + +Version 10.21 12-January-2016 +----------------------------- + +1. Improve matching speed of patterns starting with + or * in JIT. + +2. Use memchr() to find the first character in an unanchored match in 8-bit +mode in the interpreter. This gives a significant speed improvement. + +3. Removed a redundant copy of the opcode_possessify table in the +pcre2_auto_possessify.c source. + +4. Fix typos in dftables.c for z/OS. + +5. Change 36 for 10.20 broke the handling of [[:>:]] and [[:<:]] in that +processing them could involve a buffer overflow if the following character was +an opening parenthesis. + +6. Change 36 for 10.20 also introduced a bug in processing this pattern: +/((?x)(*:0))#(?'/. Specifically: if a setting of (?x) was followed by a (*MARK) +setting (which (*:0) is), then (?x) did not get unset at the end of its group +during the scan for named groups, and hence the external # was incorrectly +treated as a comment and the invalid (?' at the end of the pattern was not +diagnosed. This caused a buffer overflow during the real compile. This bug was +discovered by Karl Skomski with the LLVM fuzzer. + +7. Moved the pcre2_find_bracket() function from src/pcre2_compile.c into its +own source module to avoid a circular dependency between src/pcre2_compile.c +and src/pcre2_study.c + +8. A callout with a string argument containing an opening square bracket, for +example /(?C$[$)(?<]/, was incorrectly processed and could provoke a buffer +overflow. This bug was discovered by Karl Skomski with the LLVM fuzzer. + +9. The handling of callouts during the pre-pass for named group identification +has been tightened up. + +10. The quantifier {1} can be ignored, whether greedy, non-greedy, or +possessive. This is a very minor optimization. + +11. A possessively repeated conditional group that could match an empty string, +for example, /(?(R))*+/, was incorrectly compiled. + +12. The Unicode tables have been updated to Unicode 8.0.0 (thanks to Christian +Persch). + +13. An empty comment (?#) in a pattern was incorrectly processed and could +provoke a buffer overflow. This bug was discovered by Karl Skomski with the +LLVM fuzzer. + +14. Fix infinite recursion in the JIT compiler when certain patterns such as +/(?:|a|){100}x/ are analysed. + +15. Some patterns with character classes involving [: and \\ were incorrectly +compiled and could cause reading from uninitialized memory or an incorrect +error diagnosis. Examples are: /[[:\\](?<[::]/ and /[[:\\](?'abc')[a:]. The +first of these bugs was discovered by Karl Skomski with the LLVM fuzzer. + +16. Pathological patterns containing many nested occurrences of [: caused +pcre2_compile() to run for a very long time. This bug was found by the LLVM +fuzzer. + +17. A missing closing parenthesis for a callout with a string argument was not +being diagnosed, possibly leading to a buffer overflow. This bug was found by +the LLVM fuzzer. + +18. A conditional group with only one branch has an implicit empty alternative +branch and must therefore be treated as potentially matching an empty string. + +19. If (?R was followed by - or + incorrect behaviour happened instead of a +diagnostic. This bug was discovered by Karl Skomski with the LLVM fuzzer. + +20. Another bug that was introduced by change 36 for 10.20: conditional groups +whose condition was an assertion preceded by an explicit callout with a string +argument might be incorrectly processed, especially if the string contained \Q. +This bug was discovered by Karl Skomski with the LLVM fuzzer. + +21. Compiling PCRE2 with the sanitize options of clang showed up a number of +very pedantic coding infelicities and a buffer overflow while checking a UTF-8 +string if the final multi-byte UTF-8 character was truncated. + +22. For Perl compatibility in EBCDIC environments, ranges such as a-z in a +class, where both values are literal letters in the same case, omit the +non-letter EBCDIC code points within the range. + +23. Finding the minimum matching length of complex patterns with back +references and/or recursions can take a long time. There is now a cut-off that +gives up trying to find a minimum length when things get too complex. + +24. An optimization has been added that speeds up finding the minimum matching +length for patterns containing repeated capturing groups or recursions. + +25. If a pattern contained a back reference to a group whose number was +duplicated as a result of appearing in a (?|...) group, the computation of the +minimum matching length gave a wrong result, which could cause incorrect "no +match" errors. For such patterns, a minimum matching length cannot at present +be computed. + +26. Added a check for integer overflow in conditions (?() and +(?(R). This omission was discovered by Karl Skomski with the LLVM +fuzzer. + +27. Fixed an issue when \p{Any} inside an xclass did not read the current +character. + +28. If pcre2grep was given the -q option with -c or -l, or when handling a +binary file, it incorrectly wrote output to stdout. + +29. The JIT compiler did not restore the control verb head in case of *THEN +control verbs. This issue was found by Karl Skomski with a custom LLVM fuzzer. + +30. The way recursive references such as (?3) are compiled has been re-written +because the old way was the cause of many issues. Now, conversion of the group +number into a pattern offset does not happen until the pattern has been +completely compiled. This does mean that detection of all infinitely looping +recursions is postponed till match time. In the past, some easy ones were +detected at compile time. This re-writing was done in response to yet another +bug found by the LLVM fuzzer. + +31. A test for a back reference to a non-existent group was missing for items +such as \987. This caused incorrect code to be compiled. This issue was found +by Karl Skomski with a custom LLVM fuzzer. + +32. Error messages for syntax errors following \g and \k were giving inaccurate +offsets in the pattern. + +33. Improve the performance of starting single character repetitions in JIT. + +34. (*LIMIT_MATCH=) now gives an error instead of setting the value to 0. + +35. Error messages for syntax errors in *LIMIT_MATCH and *LIMIT_RECURSION now +give the right offset instead of zero. + +36. The JIT compiler should not check repeats after a {0,1} repeat byte code. +This issue was found by Karl Skomski with a custom LLVM fuzzer. + +37. The JIT compiler should restore the control chain for empty possessive +repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer. + +38. A bug which was introduced by the single character repetition optimization +was fixed. + +39. Match limit check added to recursion. This issue was found by Karl Skomski +with a custom LLVM fuzzer. + +40. Arrange for the UTF check in pcre2_match() and pcre2_dfa_match() to look +only at the part of the subject that is relevant when the starting offset is +non-zero. + +41. Improve first character match in JIT with SSE2 on x86. + +42. Fix two assertion fails in JIT. These issues were found by Karl Skomski +with a custom LLVM fuzzer. + +43. Correct the setting of CMAKE_C_FLAGS in CMakeLists.txt (patch from Roy Ivy +III). + +44. Fix bug in RunTest.bat for new test 14, and adjust the script for the added +test (there are now 20 in total). + +45. Fixed a corner case of range optimization in JIT. + +46. Add the ${*MARK} facility to pcre2_substitute(). + +47. Modifier lists in pcre2test were splitting at spaces without the required +commas. + +48. Implemented PCRE2_ALT_VERBNAMES. + +49. Fixed two issues in JIT. These were found by Karl Skomski with a custom +LLVM fuzzer. + +50. The pcre2test program has been extended by adding the #newline_default +command. This has made it possible to run the standard tests when PCRE2 is +compiled with either CR or CRLF as the default newline convention. As part of +this work, the new command was added to several test files and the testing +scripts were modified. The pcre2grep tests can now also be run when there is no +LF in the default newline convention. + +51. The RunTest script has been modified so that, when JIT is used and valgrind +is specified, a valgrind suppressions file is set up to ignore "Invalid read of +size 16" errors because these are false positives when the hardware supports +the SSE2 instruction set. + +52. It is now possible to have comment lines amid the subject strings in +pcre2test (and perltest.sh) input. + +53. Implemented PCRE2_USE_OFFSET_LIMIT and pcre2_set_offset_limit(). + +54. Add the null_context modifier to pcre2test so that calling pcre2_compile() +and the matching functions with NULL contexts can be tested. + +55. Implemented PCRE2_SUBSTITUTE_EXTENDED. + +56. In a character class such as [\W\p{Any}] where both a negative-type escape +("not a word character") and a property escape were present, the property +escape was being ignored. + +57. Fixed integer overflow for patterns whose minimum matching length is very, +very large. + +58. Implemented --never-backslash-C. + +59. Change 55 above introduced a bug by which certain patterns provoked the +erroneous error "\ at end of pattern". + +60. The special sequences [[:<:]] and [[:>:]] gave rise to incorrect compiling +errors or other strange effects if compiled in UCP mode. Found with libFuzzer +and AddressSanitizer. + +61. Whitespace at the end of a pcre2test pattern line caused a spurious error +message if there were only single-character modifiers. It should be ignored. + +62. The use of PCRE2_NO_AUTO_CAPTURE could cause incorrect compilation results +or segmentation errors for some patterns. Found with libFuzzer and +AddressSanitizer. + +63. Very long names in (*MARK) or (*THEN) etc. items could provoke a buffer +overflow. + +64. Improve error message for overly-complicated patterns. + +65. Implemented an optional replication feature for patterns in pcre2test, to +make it easier to test long repetitive patterns. The tests for 63 above are +converted to use the new feature. + +66. In the POSIX wrapper, if regerror() was given too small a buffer, it could +misbehave. + +67. In pcre2_substitute() in UTF mode, the UTF validity check on the +replacement string was happening before the length setting when the replacement +string was zero-terminated. + +68. In pcre2_substitute() in UTF mode, PCRE2_NO_UTF_CHECK can be set for the +second and subsequent calls to pcre2_match(). + +69. There was no check for integer overflow for a replacement group number in +pcre2_substitute(). An added check for a number greater than the largest group +number in the pattern means this is not now needed. + +70. The PCRE2-specific VERSION condition didn't work correctly if only one +digit was given after the decimal point, or if more than two digits were given. +It now works with one or two digits, and gives a compile time error if more are +given. + +71. In pcre2_substitute() there was the possibility of reading one code unit +beyond the end of the replacement string. + +72. The code for checking a subject's UTF-32 validity for a pattern with a +lookbehind involved an out-of-bounds pointer, which could potentially cause +trouble in some environments. + +73. The maximum lookbehind length was incorrectly calculated for patterns such +as /(?<=(a)(?-1))x/ which have a recursion within a backreference. + +74. Give an error if a lookbehind assertion is longer than 65535 code units. + +75. Give an error in pcre2_substitute() if a match ends before it starts (as a +result of the use of \K). + +76. Check the length of subpattern names and the names in (*MARK:xx) etc. +dynamically to avoid the possibility of integer overflow. + +77. Implement pcre2_set_max_pattern_length() so that programs can restrict the +size of patterns that they are prepared to handle. + +78. (*NO_AUTO_POSSESS) was not working. + +79. Adding group information caching improves the speed of compiling when +checking whether a group has a fixed length and/or could match an empty string, +especially when recursion or subroutine calls are involved. However, this +cannot be used when (?| is present in the pattern because the same number may +be used for groups of different sizes. To catch runaway patterns in this +situation, counts have been introduced to the functions that scan for empty +branches or compute fixed lengths. + +80. Allow for the possibility of the size of the nest_save structure not being +a factor of the size of the compiling workspace (it currently is). + +81. Check for integer overflow in minimum length calculation and cap it at +65535. + +82. Small optimizations in code for finding the minimum matching length. + +83. Lock out configuring for EBCDIC with non-8-bit libraries. + +84. Test for error code <= 0 in regerror(). + +85. Check for too many replacements (more than INT_MAX) in pcre2_substitute(). + +86. Avoid the possibility of computing with an out-of-bounds pointer (though +not dereferencing it) while handling lookbehind assertions. + +87. Failure to get memory for the match data in regcomp() is now given as a +regcomp() error instead of waiting for regexec() to pick it up. + +88. In pcre2_substitute(), ensure that CRLF is not split when it is a valid +newline sequence. + +89. Paranoid check in regcomp() for bad error code from pcre2_compile(). + +90. Run test 8 (internal offsets and code sizes) for link sizes 3 and 4 as well +as for link size 2. + +91. Document that JIT has a limit on pattern size, and give more information +about JIT compile failures in pcre2test. + +92. Implement PCRE2_INFO_HASBACKSLASHC. + +93. Re-arrange valgrind support code in pcre2test to avoid spurious reports +with JIT (possibly caused by SSE2?). + +94. Support offset_limit in JIT. + +95. A sequence such as [[:punct:]b] that is, a POSIX character class followed +by a single ASCII character in a class item, was incorrectly compiled in UCP +mode. The POSIX class got lost, but only if the single character followed it. + +96. [:punct:] in UCP mode was matching some characters in the range 128-255 +that should not have been matched. + +97. If [:^ascii:] or [:^xdigit:] are present in a non-negated class, all +characters with code points greater than 255 are in the class. When a Unicode +property was also in the class (if PCRE2_UCP is set, escapes such as \w are +turned into Unicode properties), wide characters were not correctly handled, +and could fail to match. + +98. In pcre2test, make the "startoffset" modifier a synonym of "offset", +because it sets the "startoffset" parameter for pcre2_match(). + +99. If PCRE2_AUTO_CALLOUT was set on a pattern that had a (?# comment between +an item and its qualifier (for example, A(?#comment)?B) pcre2_compile() +misbehaved. This bug was found by the LLVM fuzzer. + +100. The error for an invalid UTF pattern string always gave the code unit +offset as zero instead of where the invalidity was found. + +101. Further to 97 above, negated classes such as [^[:^ascii:]\d] were also not +working correctly in UCP mode. + +102. Similar to 99 above, if an isolated \E was present between an item and its +qualifier when PCRE2_AUTO_CALLOUT was set, pcre2_compile() misbehaved. This bug +was found by the LLVM fuzzer. + +103. The POSIX wrapper function regexec() crashed if the option REG_STARTEND +was set when the pmatch argument was NULL. It now returns REG_INVARG. + +104. Allow for up to 32-bit numbers in the ordin() function in pcre2grep. + +105. An empty \Q\E sequence between an item and its qualifier caused +pcre2_compile() to misbehave when auto callouts were enabled. This bug +was found by the LLVM fuzzer. + +106. If both PCRE2_ALT_VERBNAMES and PCRE2_EXTENDED were set, and a (*MARK) or +other verb "name" ended with whitespace immediately before the closing +parenthesis, pcre2_compile() misbehaved. Example: /(*:abc )/, but only when +both those options were set. + +107. In a number of places pcre2_compile() was not handling NULL characters +correctly, and pcre2test with the "bincode" modifier was not always correctly +displaying fields containing NULLS: + + (a) Within /x extended #-comments + (b) Within the "name" part of (*MARK) and other *verbs + (c) Within the text argument of a callout + +108. If a pattern that was compiled with PCRE2_EXTENDED started with white +space or a #-type comment that was followed by (?-x), which turns off +PCRE2_EXTENDED, and there was no subsequent (?x) to turn it on again, +pcre2_compile() assumed that (?-x) applied to the whole pattern and +consequently mis-compiled it. This bug was found by the LLVM fuzzer. The fix +for this bug means that a setting of any of the (?imsxU) options at the start +of a pattern is no longer transferred to the options that are returned by +PCRE2_INFO_ALLOPTIONS. In fact, this was an anachronism that should have +changed when the effects of those options were all moved to compile time. + +109. An escaped closing parenthesis in the "name" part of a (*verb) when +PCRE2_ALT_VERBNAMES was set caused pcre2_compile() to malfunction. This bug +was found by the LLVM fuzzer. + +110. Implemented PCRE2_SUBSTITUTE_UNSET_EMPTY, and updated pcre2test to make it +possible to test it. + +111. "Harden" pcre2test against ridiculously large values in modifiers and +command line arguments. + +112. Implemented PCRE2_SUBSTITUTE_UNKNOWN_UNSET and PCRE2_SUBSTITUTE_OVERFLOW_ +LENGTH. + +113. Fix printing of *MARK names that contain binary zeroes in pcre2test. + + +Version 10.20 30-June-2015 +-------------------------- + +1. Callouts with string arguments have been added. + +2. Assertion code generator in JIT has been optimized. + +3. The invalid pattern (?(?C) has a missing assertion condition at the end. The +pcre2_compile() function read past the end of the input before diagnosing an +error. This bug was discovered by the LLVM fuzzer. + +4. Implemented pcre2_callout_enumerate(). + +5. Fix JIT compilation of conditional blocks whose assertion is converted to +(*FAIL). E.g: /(?(?!))/. + +6. The pattern /(?(?!)^)/ caused references to random memory. This bug was +discovered by the LLVM fuzzer. + +7. The assertion (?!) is optimized to (*FAIL). This was not handled correctly +when this assertion was used as a condition, for example (?(?!)a|b). In +pcre2_match() it worked by luck; in pcre2_dfa_match() it gave an incorrect +error about an unsupported item. + +8. For some types of pattern, for example /Z*(|d*){216}/, the auto- +possessification code could take exponential time to complete. A recursion +depth limit of 1000 has been imposed to limit the resources used by this +optimization. This infelicity was discovered by the LLVM fuzzer. + +9. A pattern such as /(*UTF)[\S\V\H]/, which contains a negated special class +such as \S in non-UCP mode, explicit wide characters (> 255) can be ignored +because \S ensures they are all in the class. The code for doing this was +interacting badly with the code for computing the amount of space needed to +compile the pattern, leading to a buffer overflow. This bug was discovered by +the LLVM fuzzer. + +10. A pattern such as /((?2)+)((?1))/ which has mutual recursion nested inside +other kinds of group caused stack overflow at compile time. This bug was +discovered by the LLVM fuzzer. + +11. A pattern such as /(?1)(?#?'){8}(a)/ which had a parenthesized comment +between a subroutine call and its quantifier was incorrectly compiled, leading +to buffer overflow or other errors. This bug was discovered by the LLVM fuzzer. + +12. The illegal pattern /(?(?.*!.*)?)/ was not being diagnosed as missing an +assertion after (?(. The code was failing to check the character after (?(?< +for the ! or = that would indicate a lookbehind assertion. This bug was +discovered by the LLVM fuzzer. + +13. A pattern such as /X((?2)()*+){2}+/ which has a possessive quantifier with +a fixed maximum following a group that contains a subroutine reference was +incorrectly compiled and could trigger buffer overflow. This bug was discovered +by the LLVM fuzzer. + +14. Negative relative recursive references such as (?-7) to non-existent +subpatterns were not being diagnosed and could lead to unpredictable behaviour. +This bug was discovered by the LLVM fuzzer. + +15. The bug fixed in 14 was due to an integer variable that was unsigned when +it should have been signed. Some other "int" variables, having been checked, +have either been changed to uint32_t or commented as "must be signed". + +16. A mutual recursion within a lookbehind assertion such as (?<=((?2))((?1))) +caused a stack overflow instead of the diagnosis of a non-fixed length +lookbehind assertion. This bug was discovered by the LLVM fuzzer. + +17. The use of \K in a positive lookbehind assertion in a non-anchored pattern +(e.g. /(?<=\Ka)/) could make pcre2grep loop. + +18. There was a similar problem to 17 in pcre2test for global matches, though +the code there did catch the loop. + +19. If a greedy quantified \X was preceded by \C in UTF mode (e.g. \C\X*), +and a subsequent item in the pattern caused a non-match, backtracking over the +repeated \X did not stop, but carried on past the start of the subject, causing +reference to random memory and/or a segfault. There were also some other cases +where backtracking after \C could crash. This set of bugs was discovered by the +LLVM fuzzer. + +20. The function for finding the minimum length of a matching string could take +a very long time if mutual recursion was present many times in a pattern, for +example, /((?2){73}(?2))((?1))/. A better mutual recursion detection method has +been implemented. This infelicity was discovered by the LLVM fuzzer. + +21. Implemented PCRE2_NEVER_BACKSLASH_C. + +22. The feature for string replication in pcre2test could read from freed +memory if the replication required a buffer to be extended, and it was not +working properly in 16-bit and 32-bit modes. This issue was discovered by a +fuzzer: see http://lcamtuf.coredump.cx/afl/. + +23. Added the PCRE2_ALT_CIRCUMFLEX option. + +24. Adjust the treatment of \8 and \9 to be the same as the current Perl +behaviour. + +25. Static linking against the PCRE2 library using the pkg-config module was +failing on missing pthread symbols. + +26. If a group that contained a recursive back reference also contained a +forward reference subroutine call followed by a non-forward-reference +subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to +compile correct code, leading to undefined behaviour or an internally detected +error. This bug was discovered by the LLVM fuzzer. + +27. Quantification of certain items (e.g. atomic back references) could cause +incorrect code to be compiled when recursive forward references were involved. +For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/. This bug was +discovered by the LLVM fuzzer. + +28. A repeated conditional group whose condition was a reference by name caused +a buffer overflow if there was more than one group with the given name. This +bug was discovered by the LLVM fuzzer. + +29. A recursive back reference by name within a group that had the same name as +another group caused a buffer overflow. For example: /(?J)(?'d'(?'d'\g{d}))/. +This bug was discovered by the LLVM fuzzer. + +30. A forward reference by name to a group whose number is the same as the +current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused a +buffer overflow at compile time. This bug was discovered by the LLVM fuzzer. + +31. Fix -fsanitize=undefined warnings for left shifts of 1 by 31 (it treats 1 +as an int; fixed by writing it as 1u). + +32. Fix pcre2grep compile when -std=c99 is used with gcc, though it still gives +a warning for "fileno" unless -std=gnu99 us used. + +33. A lookbehind assertion within a set of mutually recursive subpatterns could +provoke a buffer overflow. This bug was discovered by the LLVM fuzzer. + +34. Give an error for an empty subpattern name such as (?''). + +35. Make pcre2test give an error if a pattern that follows #forbud_utf contains +\P, \p, or \X. + +36. The way named subpatterns are handled has been refactored. There is now a +pre-pass over the regex which does nothing other than identify named +subpatterns and count the total captures. This means that information about +named patterns is known before the rest of the compile. In particular, it means +that forward references can be checked as they are encountered. Previously, the +code for handling forward references was contorted and led to several errors in +computing the memory requirements for some patterns, leading to buffer +overflows. + +37. There was no check for integer overflow in subroutine calls such as (?123). + +38. The table entry for \l in EBCDIC environments was incorrect, leading to its +being treated as a literal 'l' instead of causing an error. + +39. If a non-capturing group containing a conditional group that could match +an empty string was repeated, it was not identified as matching an empty string +itself. For example: /^(?:(?(1)x|)+)+$()/. + +40. In an EBCDIC environment, pcretest was mishandling the escape sequences +\a and \e in test subject lines. + +41. In an EBCDIC environment, \a in a pattern was converted to the ASCII +instead of the EBCDIC value. + +42. The handling of \c in an EBCDIC environment has been revised so that it is +now compatible with the specification in Perl's perlebcdic page. + +43. Single character repetition in JIT has been improved. 20-30% speedup +was achieved on certain patterns. + +44. The EBCDIC character 0x41 is a non-breaking space, equivalent to 0xa0 in +ASCII/Unicode. This has now been added to the list of characters that are +recognized as white space in EBCDIC. + +45. When PCRE2 was compiled without Unicode support, the use of \p and \P gave +an error (correctly) when used outside a class, but did not give an error +within a class. + +46. \h within a class was incorrectly compiled in EBCDIC environments. + +47. JIT should return with error when the compiled pattern requires +more stack space than the maximum. + +48. Fixed a memory leak in pcre2grep when a locale is set. + + +Version 10.10 06-March-2015 +--------------------------- + +1. When a pattern is compiled, it remembers the highest back reference so that +when matching, if the ovector is too small, extra memory can be obtained to +use instead. A conditional subpattern whose condition is a check on a capture +having happened, such as, for example in the pattern /^(?:(a)|b)(?(1)A|B)/, is +another kind of back reference, but it was not setting the highest +backreference number. This mattered only if pcre2_match() was called with an +ovector that was too small to hold the capture, and there was no other kind of +back reference (a situation which is probably quite rare). The effect of the +bug was that the condition was always treated as FALSE when the capture could +not be consulted, leading to a incorrect behaviour by pcre2_match(). This bug +has been fixed. + +2. Functions for serialization and deserialization of sets of compiled patterns +have been added. + +3. The value that is returned by PCRE2_INFO_SIZE has been corrected to remove +excess code units at the end of the data block that may occasionally occur if +the code for calculating the size over-estimates. This change stops the +serialization code copying uninitialized data, to which valgrind objects. The +documentation of PCRE2_INFO_SIZE was incorrect in stating that the size did not +include the general overhead. This has been corrected. + +4. All code units in every slot in the table of group names are now set, again +in order to avoid accessing uninitialized data when serializing. + +5. The (*NO_JIT) feature is implemented. + +6. If a bug that caused pcre2_compile() to use more memory than allocated was +triggered when using valgrind, the code in (3) above passed a stupidly large +value to valgrind. This caused a crash instead of an "internal error" return. + +7. A reference to a duplicated named group (either a back reference or a test +for being set in a conditional) that occurred in a part of the pattern where +PCRE2_DUPNAMES was not set caused the amount of memory needed for the pattern +to be incorrectly calculated, leading to overwriting. + +8. A mutually recursive set of back references such as (\2)(\1) caused a +segfault at compile time (while trying to find the minimum matching length). +The infinite loop is now broken (with the minimum length unset, that is, zero). + +9. If an assertion that was used as a condition was quantified with a minimum +of zero, matching went wrong. In particular, if the whole group had unlimited +repetition and could match an empty string, a segfault was likely. The pattern +(?(?=0)?)+ is an example that caused this. Perl allows assertions to be +quantified, but not if they are being used as conditions, so the above pattern +is faulted by Perl. PCRE2 has now been changed so that it also rejects such +patterns. + +10. The error message for an invalid quantifier has been changed from "nothing +to repeat" to "quantifier does not follow a repeatable item". + +11. If a bad UTF string is compiled with NO_UTF_CHECK, it may succeed, but +scanning the compiled pattern in subsequent auto-possessification can get out +of step and lead to an unknown opcode. Previously this could have caused an +infinite loop. Now it generates an "internal error" error. This is a tidyup, +not a bug fix; passing bad UTF with NO_UTF_CHECK is documented as having an +undefined outcome. + +12. A UTF pattern containing a "not" match of a non-ASCII character and a +subroutine reference could loop at compile time. Example: /[^\xff]((?1))/. + +13. The locale test (RunTest 3) has been upgraded. It now checks that a locale +that is found in the output of "locale -a" can actually be set by pcre2test +before it is accepted. Previously, in an environment where a locale was listed +but would not set (an example does exist), the test would "pass" without +actually doing anything. Also the fr_CA locale has been added to the list of +locales that can be used. + +14. Fixed a bug in pcre2_substitute(). If a replacement string ended in a +capturing group number without parentheses, the last character was incorrectly +literally included at the end of the replacement string. + +15. A possessive capturing group such as (a)*+ with a minimum repeat of zero +failed to allow the zero-repeat case if pcre2_match() was called with an +ovector too small to capture the group. + +16. Improved error message in pcre2test when setting the stack size (-S) fails. + +17. Fixed two bugs in CMakeLists.txt: (1) Some lines had got lost in the +transfer from PCRE1, meaning that CMake configuration failed if "build tests" +was selected. (2) The file src/pcre2_serialize.c had not been added to the list +of PCRE2 sources, which caused a failure to build pcre2test. + +18. Fixed typo in pcre2_serialize.c (DECL instead of DEFN) that causes problems +only on Windows. + +19. Use binary input when reading back saved serialized patterns in pcre2test. + +20. Added RunTest.bat for running the tests under Windows. + +21. "make distclean" was not removing config.h, a file that may be created for +use with CMake. + +22. A pattern such as "((?2){0,1999}())?", which has a group containing a +forward reference repeated a large (but limited) number of times within a +repeated outer group that has a zero minimum quantifier, caused incorrect code +to be compiled, leading to the error "internal error: previously-checked +referenced subpattern not found" when an incorrect memory address was read. +This bug was reported as "heap overflow", discovered by Kai Lu of Fortinet's +FortiGuard Labs. (Added 24-March-2015: CVE-2015-2325 was given to this.) + +23. A pattern such as "((?+1)(\1))/" containing a forward reference subroutine +call within a group that also contained a recursive back reference caused +incorrect code to be compiled. This bug was reported as "heap overflow", +discovered by Kai Lu of Fortinet's FortiGuard Labs. (Added 24-March-2015: +CVE-2015-2326 was given to this.) + +24. Computing the size of the JIT read-only data in advance has been a source +of various issues, and new ones are still appear unfortunately. To fix +existing and future issues, size computation is eliminated from the code, +and replaced by on-demand memory allocation. + +25. A pattern such as /(?i)[A-`]/, where characters in the other case are +adjacent to the end of the range, and the range contained characters with more +than one other case, caused incorrect behaviour when compiled in UTF mode. In +that example, the range a-j was left out of the class. + + +Version 10.00 05-January-2015 +----------------------------- + +Version 10.00 is the first release of PCRE2, a revised API for the PCRE +library. Changes prior to 10.00 are logged in the ChangeLog file for the old +API, up to item 20 for release 8.36. + +The code of the library was heavily revised as part of the new API +implementation. Details of each and every modification were not individually +logged. In addition to the API changes, the following changes were made. They +are either new functionality, or bug fixes and other noticeable changes of +behaviour that were implemented after the code had been forked. + +1. Including Unicode support at build time is now enabled by default, but it +can optionally be disabled. It is not enabled by default at run time (no +change). + +2. The test program, now called pcre2test, was re-specified and almost +completely re-written. Its input is not compatible with input for pcretest. + +3. Patterns may start with (*NOTEMPTY) or (*NOTEMPTY_ATSTART) to set the +PCRE2_NOTEMPTY or PCRE2_NOTEMPTY_ATSTART options for every subject line that is +matched by that pattern. + +4. For the benefit of those who use PCRE2 via some other application, that is, +not writing the function calls themselves, it is possible to check the PCRE2 +version by matching a pattern such as /(?(VERSION>=10)yes|no)/ against a +string such as "yesno". + +5. There are case-equivalent Unicode characters whose encodings use different +numbers of code units in UTF-8. U+023A and U+2C65 are one example. (It is +theoretically possible for this to happen in UTF-16 too.) If a backreference to +a group containing one of these characters was greedily repeated, and during +the match a backtrack occurred, the subject might be backtracked by the wrong +number of code units. For example, if /^(\x{23a})\1*(.)/ is matched caselessly +(and in UTF-8 mode) against "\x{23a}\x{2c65}\x{2c65}\x{2c65}", group 2 should +capture the final character, which is the three bytes E2, B1, and A5 in UTF-8. +Incorrect backtracking meant that group 2 captured only the last two bytes. +This bug has been fixed; the new code is slower, but it is used only when the +strings matched by the repetition are not all the same length. + +6. A pattern such as /()a/ was not setting the "first character must be 'a'" +information. This applied to any pattern with a group that matched no +characters, for example: /(?:(?=.)|(? 0) + { + $line = 0; + $file = shift @ARGV; + + open (IN, $file) || die "Failed to open $file\n"; + + while () + { + $line++; + if (/^\s*$/) + { + printf "Empty line $line of $file\n"; + $yield = 1; + } + elsif (/^\./) + { + if (!/^\.\s*$| + ^\.B\s+\S| + ^\.TH\s\S| + ^\.SH\s\S| + ^\.SS\s\S| + ^\.TP(?:\s?\d+)?\s*$| + ^\.SM\s*$| + ^\.br\s*$| + ^\.rs\s*$| + ^\.sp\s*$| + ^\.nf\s*$| + ^\.fi\s*$| + ^\.P\s*$| + ^\.PP\s*$| + ^\.\\"(?:\ HREF)?\s*$| + ^\.\\"\sHTML\s\s*$| + ^\.\\"\sHTML\s<\/a>\s*$| + ^\.\\"\s<\/a>\s*$| + ^\.\\"\sJOINSH\s*$| + ^\.\\"\sJOIN\s*$/x + ) + { + printf "Bad control line $line of $file\n"; + $yield = 1; + } + } + else + { + if (/\\[^ef]|\\f[^IBP]/) + { + printf "Bad backslash in line $line of $file\n"; + $yield = 1; + } + } + } + + close(IN); + } + +exit $yield; +# End diff --git a/pcre2/CleanTxt b/pcre2/CleanTxt new file mode 100755 index 000000000..1f42519c8 --- /dev/null +++ b/pcre2/CleanTxt @@ -0,0 +1,113 @@ +#! /usr/bin/perl -w + +# Script to take the output of nroff -man and remove all the backspacing and +# the page footers and the screen commands etc so that it is more usefully +# readable online. In fact, in the latest nroff, intermediate footers don't +# seem to be generated any more. + +$blankcount = 0; +$lastwascut = 0; +$firstheader = 1; + +# Input on STDIN; output to STDOUT. + +while () + { + s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" + s/.\x8//g; # Remove "char, backspace" + + # Handle header lines. Retain only the first one we encounter, but remove + # the blank line that follows. Any others (e.g. at end of document) and the + # following blank line are dropped. + + if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/) + { + if ($firstheader) + { + $firstheader = 0; + print; + $lastprinted = $_; + $lastwascut = 0; + } + $_=; # Remove a blank that follows + next; + } + + # Count runs of empty lines + + if (/^\s*$/) + { + $blankcount++; + $lastwascut = 0; + next; + } + + # If a chunk of lines has been cut out (page footer) and the next line + # has a different indentation, put back one blank line. + + if ($lastwascut && $blankcount < 1 && defined($lastprinted)) + { + ($a) = $lastprinted =~ /^(\s*)/; + ($b) = $_ =~ /^(\s*)/; + $blankcount++ if ($a ne $b); + } + + # We get here only when we have a non-blank line in hand. If it was preceded + # by 3 or more blank lines, read the next 3 lines and see if they are blank. + # If so, remove all 7 lines, and remember that we have just done a cut. + + if ($blankcount >= 3) + { + for ($i = 0; $i < 3; $i++) + { + $next[$i] = ; + $next[$i] = "" if !defined $next[$i]; + $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" + $next[$i] =~ s/.\x8//g; # Remove "char, backspace" + } + + # Cut out chunks of the form <3 blanks><3 blanks> + + if ($next[0] =~ /^\s*$/ && + $next[1] =~ /^\s*$/ && + $next[2] =~ /^\s*$/) + { + $blankcount -= 3; + $lastwascut = 1; + } + + # Otherwise output the saved blanks, the current, and the next three + # lines. Remember the last printed line. + + else + { + for ($i = 0; $i < $blankcount; $i++) { print "\n"; } + print; + for ($i = 0; $i < 3; $i++) + { + $next[$i] =~ s/.\x8//g; + print $next[$i]; + $lastprinted = $_; + } + $lastwascut = 0; + $blankcount = 0; + } + } + + # This non-blank line is not preceded by 3 or more blank lines. Output + # any blanks there are, and the line. Remember it. Force two blank lines + # before headings. + + else + { + $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ && + defined($lastprinted); + for ($i = 0; $i < $blankcount; $i++) { print "\n"; } + print; + $lastprinted = $_; + $lastwascut = 0; + $blankcount = 0; + } + } + +# End diff --git a/pcre2/Detrail b/pcre2/Detrail new file mode 100755 index 000000000..1c5c7e9ca --- /dev/null +++ b/pcre2/Detrail @@ -0,0 +1,35 @@ +#!/usr/bin/perl + +# This is a script for removing trailing whitespace from lines in files that +# are listed on the command line. + +# This subroutine does the work for one file. + +sub detrail { +my($file) = $_[0]; +my($changed) = 0; +open(IN, "$file") || die "Can't open $file for input"; +@lines = ; +close(IN); +foreach (@lines) + { + if (/\s+\n$/) + { + s/\s+\n$/\n/; + $changed = 1; + } + } +if ($changed) + { + open(OUT, ">$file") || die "Can't open $file for output"; + print OUT @lines; + close(OUT); + } +} + +# This is the main program + +$, = ""; # Output field separator +for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); } + +# End diff --git a/pcre2/HACKING b/pcre2/HACKING new file mode 100644 index 000000000..051520c28 --- /dev/null +++ b/pcre2/HACKING @@ -0,0 +1,604 @@ +Technical Notes about PCRE2 +--------------------------- + +These are very rough technical notes that record potentially useful information +about PCRE2 internals. PCRE2 is a library based on the original PCRE library, +but with a revised (and incompatible) API. To avoid confusion, the original +library is referred to as PCRE1 below. For information about testing PCRE2, see +the pcre2test documentation and the comment at the head of the RunTest file. + +PCRE1 releases were up to 8.3x when PCRE2 was developed. The 8.xx series will +continue for bugfixes if necessary. PCRE2 releases started at 10.00 to avoid +confusion with PCRE1. + + +Historical note 1 +----------------- + +Many years ago I implemented some regular expression functions to an algorithm +suggested by Martin Richards. These were not Unix-like in form, and were quite +restricted in what they could do by comparison with Perl. The interesting part +about the algorithm was that the amount of space required to hold the compiled +form of an expression was known in advance. The code to apply an expression did +not operate by backtracking, as the original Henry Spencer code and current +PCRE2 and Perl code does, but instead checked all possibilities simultaneously +by keeping a list of current states and checking all of them as it advanced +through the subject string. In the terminology of Jeffrey Friedl's book, it was +a "DFA algorithm", though it was not a traditional Finite State Machine (FSM). +When the pattern was all used up, all remaining states were possible matches, +and the one matching the longest subset of the subject string was chosen. This +did not necessarily maximize the individual wild portions of the pattern, as is +expected in Unix and Perl-style regular expressions. + + +Historical note 2 +----------------- + +By contrast, the code originally written by Henry Spencer (which was +subsequently heavily modified for Perl) compiles the expression twice: once in +a dummy mode in order to find out how much store will be needed, and then for +real. (The Perl version probably doesn't do this any more; I'm talking about +the original library.) The execution function operates by backtracking and +maximizing (or, optionally, minimizing, in Perl) the amount of the subject that +matches individual wild portions of the pattern. This is an "NFA algorithm" in +Friedl's terminology. + + +OK, here's the real stuff +------------------------- + +For the set of functions that formed the original PCRE1 library (which are +unrelated to those mentioned above), I tried at first to invent an algorithm +that used an amount of store bounded by a multiple of the number of characters +in the pattern, to save on compiling time. However, because of the greater +complexity in Perl regular expressions, I couldn't do this. In any case, a +first pass through the pattern is helpful for other reasons. + + +Support for 16-bit and 32-bit data strings +------------------------------------------- + +The library can be compiled in any combination of 8-bit, 16-bit or 32-bit +modes, creating up to three different libraries. In the description that +follows, the word "short" is used for a 16-bit data quantity, and the phrase +"code unit" is used for a quantity that is a byte in 8-bit mode, a short in +16-bit mode and a 32-bit word in 32-bit mode. The names of PCRE2 functions are +given in generic form, without the _8, _16, or _32 suffix. + + +Computing the memory requirement: how it was +-------------------------------------------- + +Up to and including release 6.7, PCRE1 worked by running a very degenerate +first pass to calculate a maximum memory requirement, and then a second pass to +do the real compile - which might use a bit less than the predicted amount of +memory. The idea was that this would turn out faster than the Henry Spencer +code because the first pass is degenerate and the second pass can just store +stuff straight into memory, which it knows is big enough. + + +Computing the memory requirement: how it is +------------------------------------------- + +By the time I was working on a potential 6.8 release, the degenerate first pass +had become very complicated and hard to maintain. Indeed one of the early +things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then +I had a flash of inspiration as to how I could run the real compile function in +a "fake" mode that enables it to compute how much memory it would need, while +actually only ever using a few hundred bytes of working memory, and without too +many tests of the mode that might slow it down. So I refactored the compiling +functions to work this way. This got rid of about 600 lines of source. It +should make future maintenance and development easier. As this was such a major +change, I never released 6.8, instead upping the number to 7.0 (other quite +major changes were also present in the 7.0 release). + +A side effect of this work was that the previous limit of 200 on the nesting +depth of parentheses was removed. However, there was a downside: compiling ran +more slowly than before (30% or more, depending on the pattern) because it now +did a full analysis of the pattern. My hope was that this would not be a big +issue, and in the event, nobody has commented on it. + +At release 8.34, a limit on the nesting depth of parentheses was re-introduced +(default 250, settable at build time) so as to put a limit on the amount of +system stack used by the compile function, which uses recursive function calls +for nested parenthesized groups. This is a safety feature for environments with +small stacks where the patterns are provided by users. + +History repeated itself for release 10.20. A number of bugs relating to named +subpatterns had been discovered by fuzzers. Most of these were related to the +handling of forward references when it was not known if the named pattern was +unique. (References to non-unique names use a different opcode and more +memory.) The use of duplicate group numbers (the (?| facility) also caused +issues. + +To get around these problems I adopted a new approach by adding a third pass, +really a "pre-pass", over the pattern, which does nothing other than identify +all the named subpatterns and their corresponding group numbers. This means +that the actual compile (both pre-pass and real compile) have full knowledge of +group names and numbers throughout. Several dozen lines of messy code were +eliminated, though the new pre-pass is not short (skipping over [] classes is +complicated). + + +Traditional matching function +----------------------------- + +The "traditional", and original, matching function is called pcre2_match(), and +it implements an NFA algorithm, similar to the original Henry Spencer algorithm +and the way that Perl works. This is not surprising, since it is intended to be +as compatible with Perl as possible. This is the function most users of PCRE2 +will use most of the time. If PCRE2 is compiled with just-in-time (JIT) +support, and studying a compiled pattern with JIT is successful, the JIT code +is run instead of the normal pcre2_match() code, but the result is the same. + + +Supplementary matching function +------------------------------- + +There is also a supplementary matching function called pcre2_dfa_match(). This +implements a DFA matching algorithm that searches simultaneously for all +possible matches that start at one point in the subject string. (Going back to +my roots: see Historical Note 1 above.) This function intreprets the same +compiled pattern data as pcre2_match(); however, not all the facilities are +available, and those that are do not always work in quite the same way. See the +user documentation for details. + +The algorithm that is used for pcre2_dfa_match() is not a traditional FSM, +because it may have a number of states active at one time. More work would be +needed at compile time to produce a traditional FSM where only one state is +ever active at once. I believe some other regex matchers work this way. JIT +support is not available for this kind of matching. + + +Changeable options +------------------ + +The /i, /m, or /s options (PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and +some others) may change in the middle of patterns. Their processing is handled +entirely at compile time by generating different opcodes for the different +settings. The runtime functions do not need to keep track of an options state. + + +Format of compiled patterns +--------------------------- + +The compiled form of a pattern is a vector of unsigned code units (bytes in +8-bit mode, shorts in 16-bit mode, 32-bit words in 32-bit mode), containing +items of variable length. The first code unit in an item contains an opcode, +and the length of the item is either implicit in the opcode or contained in the +data that follows it. + +In many cases listed below, LINK_SIZE data values are specified for offsets +within the compiled pattern. LINK_SIZE always specifies a number of bytes. The +default value for LINK_SIZE is 2, except for the 32-bit library, where it can +only be 4. The 8-bit library can be compiled to used 3-byte or 4-byte values, +and the 16-bit library can be compiled to use 4-byte values, though this +impairs performance. Specifing a LINK_SIZE larger than 2 for these libraries is +necessary only when patterns whose compiled length is greater than 64K code +units are going to be processed. When a LINK_SIZE value uses more than one code +unit, the most significant unit is first. + +In this description, we assume the "normal" compilation options. Data values +that are counts (e.g. quantifiers) are always two bytes long in 8-bit mode +(most significant byte first), or one code unit in 16-bit and 32-bit modes. + + +Opcodes with no following data +------------------------------ + +These items are all just one unit long + + OP_END end of pattern + OP_ANY match any one character other than newline + OP_ALLANY match any one character, including newline + OP_ANYBYTE match any single code unit, even in UTF-8/16 mode + OP_SOD match start of data: \A + OP_SOM, start of match (subject + offset): \G + OP_SET_SOM, set start of match (\K) + OP_CIRC ^ (start of data) + OP_CIRCM ^ multiline mode (start of data or after newline) + OP_NOT_WORD_BOUNDARY \W + OP_WORD_BOUNDARY \w + OP_NOT_DIGIT \D + OP_DIGIT \d + OP_NOT_HSPACE \H + OP_HSPACE \h + OP_NOT_WHITESPACE \S + OP_WHITESPACE \s + OP_NOT_VSPACE \V + OP_VSPACE \v + OP_NOT_WORDCHAR \W + OP_WORDCHAR \w + OP_EODN match end of data or newline at end: \Z + OP_EOD match end of data: \z + OP_DOLL $ (end of data, or before final newline) + OP_DOLLM $ multiline mode (end of data or before newline) + OP_EXTUNI match an extended Unicode grapheme cluster + OP_ANYNL match any Unicode newline sequence + + OP_ASSERT_ACCEPT ) + OP_ACCEPT ) These are Perl 5.10's "backtracking control + OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing + OP_FAIL ) parentheses, it may be preceded by one or more + OP_PRUNE ) OP_CLOSE, each followed by a count that + OP_SKIP ) indicates which parentheses must be closed. + OP_THEN ) + +OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion. +This ends the assertion, not the entire pattern match. The assertion (?!) is +always optimized to OP_FAIL. + + +Backtracking control verbs with optional data +--------------------------------------------- + +(*THEN) without an argument generates the opcode OP_THEN and no following data. +OP_MARK is followed by the mark name, preceded by a length in one code unit, +and followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with +arguments, the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, +with the name following in the same format as OP_MARK. + + +Matching literal characters +--------------------------- + +The OP_CHAR opcode is followed by a single character that is to be matched +casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, +the character may be more than one code unit long. In UTF-32 mode, characters +are always exactly one code unit long. + +If there is only one character in a character class, OP_CHAR or OP_CHARI is +used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is, +for something like [^a]). + + +Repeating single characters +--------------------------- + +The common repeats (*, +, ?), when applied to a single character, use the +following opcodes, which come in caseful and caseless versions: + + Caseful Caseless + OP_STAR OP_STARI + OP_MINSTAR OP_MINSTARI + OP_POSSTAR OP_POSSTARI + OP_PLUS OP_PLUSI + OP_MINPLUS OP_MINPLUSI + OP_POSPLUS OP_POSPLUSI + OP_QUERY OP_QUERYI + OP_MINQUERY OP_MINQUERYI + OP_POSQUERY OP_POSQUERYI + +Each opcode is followed by the character that is to be repeated. In ASCII or +UTF-32 modes, these are two-code-unit items; in UTF-8 or UTF-16 modes, the +length is variable. Those with "MIN" in their names are the minimizing +versions. Those with "POS" in their names are possessive versions. Other kinds +of repeat make use of these opcodes: + + Caseful Caseless + OP_UPTO OP_UPTOI + OP_MINUPTO OP_MINUPTOI + OP_POSUPTO OP_POSUPTOI + OP_EXACT OP_EXACTI + +Each of these is followed by a count and then the repeated character. The count +is two bytes long in 8-bit mode (most significant byte first), or one code unit +in 16-bit and 32-bit modes. + +OP_UPTO matches from 0 to the given number. A repeat with a non-zero minimum +and a fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or +OP_MINUPTO or OPT_POSUPTO). + +Another set of matching repeating opcodes (called OP_NOTSTAR, OP_NOTSTARI, +etc.) are used for repeated, negated, single-character classes such as [^a]*. +The normal single-character opcodes (OP_STAR, etc.) are used for repeated +positive single-character classes. + + +Repeating character types +------------------------- + +Repeats of things like \d are done exactly as for single characters, except +that instead of a character, the opcode for the type (e.g. OP_DIGIT) is stored +in the next code unit. The opcodes are: + + OP_TYPESTAR + OP_TYPEMINSTAR + OP_TYPEPOSSTAR + OP_TYPEPLUS + OP_TYPEMINPLUS + OP_TYPEPOSPLUS + OP_TYPEQUERY + OP_TYPEMINQUERY + OP_TYPEPOSQUERY + OP_TYPEUPTO + OP_TYPEMINUPTO + OP_TYPEPOSUPTO + OP_TYPEEXACT + + +Match by Unicode property +------------------------- + +OP_PROP and OP_NOTPROP are used for positive and negative matches of a +character by testing its Unicode property (the \p and \P escape sequences). +Each is followed by two code units that encode the desired property as a type +and a value. The types are a set of #defines of the form PT_xxx, and the values +are enumerations of the form ucp_xx, defined in the pcre2_ucp.h source file. +The value is relevant only for PT_GC (General Category), PT_PC (Particular +Category), and PT_SC (Script). + +Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by +three code units: OP_PROP or OP_NOTPROP, and then the desired property type and +value. + + +Character classes +----------------- + +If there is only one character in a class, OP_CHAR or OP_CHARI is used for a +positive class, and OP_NOT or OP_NOTI for a negative one (that is, for +something like [^a]). + +A set of repeating opcodes (called OP_NOTSTAR etc.) are used for repeated, +negated, single-character classes. The normal single-character opcodes +(OP_STAR, etc.) are used for repeated positive single-character classes. + +When there is more than one character in a class, and all the code points are +less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a +negative one. In either case, the opcode is followed by a 32-byte (16-short, +8-word) bit map containing a 1 bit for every character that is acceptable. The +bits are counted from the least significant end of each unit. In caseless mode, +bits for both cases are set. + +The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 and +16-bit and 32-bit modes, subject characters with values greater than 255 can be +handled correctly. For OP_CLASS they do not match, whereas for OP_NCLASS they +do. + +For classes containing characters with values greater than 255 or that contain +\p or \P, OP_XCLASS is used. It optionally uses a bit map if any acceptable +code points are less than 256, followed by a list of pairs (for a range) and/or +single characters and/or properties. In caseless mode, both cases are +explicitly listed. + +OP_XCLASS is followed by a LINK_SIZE value containing the total length of the +opcode and its data. This is followed by a code unit containing flag bits: +XCL_NOT indicates that this is a negative class, and XCL_MAP indicates that a +bit map is present. There follows the bit map, if XCL_MAP is set, and then a +sequence of items coded as follows: + + XCL_END marks the end of the list + XCL_SINGLE one character follows + XCL_RANGE two characters follow + XCL_PROP a Unicode property (type, value) follows + XCL_NOTPROP a Unicode property (type, value) follows + +If a range starts with a code point less than 256 and ends with one greater +than 255, it is split into two ranges, with characters less than 256 being +indicated in the bit map, and the rest with XCL_RANGE. + +When XCL_NOT is set, the bit map, if present, contains bits for characters that +are allowed (exactly as for OP_NCLASS), but the list of items that follow it +specifies characters and properties that are not allowed. + + +Back references +--------------- + +OP_REF (caseful) or OP_REFI (caseless) is followed by a count containing the +reference number when the reference is to a unique capturing group (either by +number or by name). When named groups are used, there may be more than one +group with the same name. In this case, a reference to such a group by name +generates OP_DNREF or OP_DNREFI. These are followed by two counts: the index +(not the byte offset) in the group name table of the first entry for the +required name, followed by the number of groups with the same name. The +matching code can then search for the first one that is set. + + +Repeating character classes and back references +----------------------------------------------- + +Single-character classes are handled specially (see above). This section +applies to other classes and also to back references. In both cases, the repeat +information follows the base item. The matching code looks at the following +opcode to see if it is one of these: + + OP_CRSTAR + OP_CRMINSTAR + OP_CRPOSSTAR + OP_CRPLUS + OP_CRMINPLUS + OP_CRPOSPLUS + OP_CRQUERY + OP_CRMINQUERY + OP_CRPOSQUERY + OP_CRRANGE + OP_CRMINRANGE + OP_CRPOSRANGE + +All but the last three are single-code-unit items, with no data. The others are +followed by the minimum and maximum repeat counts. + + +Brackets and alternation +------------------------ + +A pair of non-capturing round brackets is wrapped round each expression at +compile time, so alternation always happens in the context of brackets. + +[Note for North Americans: "bracket" to some English speakers, including +myself, can be round, square, curly, or pointy. Hence this usage rather than +"parentheses".] + +Non-capturing brackets use the opcode OP_BRA, capturing brackets use OP_CBRA. A +bracket opcode is followed by a LINK_SIZE value which gives the offset to the +next alternative OP_ALT or, if there aren't any branches, to the matching +OP_KET opcode. Each OP_ALT is followed by a LINK_SIZE value giving the offset +to the next one, or to the OP_KET opcode. For capturing brackets, the bracket +number is a count that immediately follows the offset. + +OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN +and OP_KETRMAX are used for indefinite repetitions, minimally or maximally +respectively (see below for possessive repetitions). All three are followed by +a LINK_SIZE value giving (as a positive number) the offset back to the matching +bracket opcode. + +If a subpattern is quantified such that it is permitted to match zero times, it +is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are +single-unit opcodes that tell the matcher that skipping the following +subpattern entirely is a valid match. In the case of the first two, not +skipping the pattern is also valid (greedy and non-greedy). The third is used +when a pattern has the quantifier {0,0}. It cannot be entirely discarded, +because it may be called as a subroutine from elsewhere in the pattern. + +A subpattern with an indefinite maximum repetition is replicated in the +compiled data its minimum number of times (or once with OP_BRAZERO if the +minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX +as appropriate. + +A subpattern with a bounded maximum repetition is replicated in a nested +fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO +before each replication after the minimum, so that, for example, (abc){2,5} is +compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group +has the same number. + +When a repeated subpattern has an unbounded upper limit, it is checked to see +whether it could match an empty string. If this is the case, the opcode in the +final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher +that it needs to check for matching an empty string when it hits OP_KETRMIN or +OP_KETRMAX, and if so, to break the loop. + + +Possessive brackets +------------------- + +When a repeated group (capturing or non-capturing) is marked as possessive by +the "+" notation, e.g. (abc)++, different opcodes are used. Their names all +have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCBRAPOS instead +of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum +repetition is zero, the group is preceded by OP_BRAPOSZERO. + + +Once-only (atomic) groups +------------------------- + +These are just like other subpatterns, but they start with the opcode +OP_ONCE or OP_ONCE_NC. The former is used when there are no capturing brackets +within the atomic group; the latter when there are. The distinction is needed +for when there is a backtrack to before the group - any captures within the +group must be reset, so it is necessary to retain backtracking points inside +the group, even after it is complete, in order to do this. When there are no +captures in an atomic group, all the backtracking can be discarded when it is +complete. This is more efficient, and also uses less stack. + +The check for matching an empty string in an unbounded repeat is handled +entirely at runtime, so there are just these two opcodes for atomic groups. + + +Assertions +---------- + +Forward assertions are also just like other subpatterns, but starting with one +of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes +OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion +is OP_REVERSE, followed by a count of the number of characters to move back the +pointer in the subject string. In ASCII or UTF-32 mode, the count is also the +number of code units, but in UTF-8/16 mode each character may occupy more than +one code unit. A separate count is present in each alternative of a lookbehind +assertion, allowing them to have different (but fixed) lengths. + + +Conditional subpatterns +----------------------- + +These are like other subpatterns, but they start with the opcode OP_COND, or +OP_SCOND for one that might match an empty string in an unbounded repeat. + +If the condition is a back reference, this is stored at the start of the +subpattern using the opcode OP_CREF followed by a count containing the +reference number, provided that the reference is to a unique capturing group. +If the reference was by name and there is more than one group with that name, +OP_DNCREF is used instead. It is followed by two counts: the index in the group +names table, and the number of groups with the same name. The allows the +matcher to check if any group with the given name is set. + +If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of +group x" (coded as "(?(Rx)"), the group number is stored at the start of the +subpattern using the opcode OP_RREF (with a value of RREF_ANY (0xffff) for "the +whole pattern") or OP_DNRREF (with data as for OP_DNCREF). + +For a DEFINE condition, OP_FALSE is used (with no associated data). During +compilation, however, a DEFINE condition is coded as OP_DEFINE so that, when +the conditional group is complete, there can be a check to ensure that it +contains only one top-level branch. Once this has happened, the opcode is +changed to OP_FALSE, so the matcher never sees OP_DEFINE. + +There is a special PCRE2-specific condition of the form (VERSION[>]=x.y), which +tests the PCRE2 version number. This compiles into one of the opcodes OP_TRUE +or OP_FALSE. + +If a condition is not a back reference, recursion test, DEFINE, or VERSION, it +must start with an assertion, whose opcode normally immediately follows OP_COND +or OP_SCOND. However, if automatic callouts are enabled, a callout is inserted +immediately before the assertion. It is also possible to insert a manual +callout at this point. Only assertion conditions may have callouts preceding +the condition. + +A condition that is the negative assertion (?!) is optimized to OP_FAIL in all +parts of the pattern, so this is another opcode that may appear as a condition. +It is treated the same as OP_FALSE. + + +Recursion +--------- + +Recursion either matches the current pattern, or some subexpression. The opcode +OP_RECURSE is followed by a LINK_SIZE value that is the offset to the starting +bracket from the start of the whole pattern. OP_RECURSE is also used for +"subroutine" calls, even though they are not strictly a recursion. Repeated +recursions are automatically wrapped inside OP_ONCE brackets, because otherwise +some patterns broke them. A non-repeated recursion is not wrapped in OP_ONCE +brackets, but it is nevertheless still treated as an atomic group. + + +Callout +------- + +A callout can nowadays have either a numerical argument or a string argument. +These use OP_CALLOUT or OP_CALLOUT_STR, respectively. In each case these are +followed by two LINK_SIZE values giving the offset in the pattern string to the +start of the following item, and another count giving the length of this item. +These values make it possible for pcre2test to output useful tracing +information using callouts. + +In the case of a numeric callout, after these two values there is a single code +unit containing the callout number, in the range 0-255, with 255 being used for +callouts that are automatically inserted as a result of the PCRE2_AUTO_CALLOUT +option. Thus, this opcode item is of fixed length: + + [OP_CALLOUT] [PATTERN_OFFSET] [PATTERN_LENGTH] [NUMBER] + +For callouts with string arguments, OP_CALLOUT_STR has three more data items: +a LINK_SIZE value giving the complete length of the entire opcode item, a +LINK_SIZE item containing the offset within the pattern string to the start of +the string argument, and the string itself, preceded by its starting delimiter +and followed by a binary zero. When a callout function is called, a pointer to +the actual string is passed, but the delimiter can be accessed as string[-1] if +the application needs it. In the 8-bit library, the callout in /X(?C'abc')Y/ is +compiled as the following bytes (decimal numbers represent binary values): + + [OP_CALLOUT] [0] [10] [0] [1] [0] [14] [0] [5] ['] [a] [b] [c] [0] + -------- ------- -------- ------- + | | | | + ------- LINK_SIZE items ------ + +Opcode table checking +--------------------- + +The last opcode that is defined in pcre2_internal.h is OP_TABLE_LENGTH. This is +not a real opcode, but is used to check that tables indexed by opcode are the +correct length, in order to catch updating errors. + +Philip Hazel +June 2015 diff --git a/pcre2/INSTALL b/pcre2/INSTALL new file mode 100644 index 000000000..209984075 --- /dev/null +++ b/pcre2/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell command `./configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/pcre2/LICENCE b/pcre2/LICENCE new file mode 100644 index 000000000..6600a6590 --- /dev/null +++ b/pcre2/LICENCE @@ -0,0 +1,83 @@ +PCRE2 LICENCE +------------- + +PCRE2 is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + +Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as +specified below. The documentation for PCRE2, supplied in the "doc" +directory, is distributed under the same terms as the software itself. The data +in the testdata directory is not copyrighted and is in the public domain. + +The basic library functions are written in C and are freestanding. Also +included in the distribution is a just-in-time compiler that can be used to +optimize pattern matching. This is an optional feature that can be omitted when +the library is built. + + +THE BASIC LIBRARY FUNCTIONS +--------------------------- + +Written by: Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk + +University of Cambridge Computing Service, +Cambridge, England. + +Copyright (c) 1997-2016 University of Cambridge +All rights reserved. + + +PCRE2 JUST-IN-TIME COMPILATION SUPPORT +-------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2016 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2016 Zoltan Herczeg +All rights reserved. + + +THE "BSD" LICENCE +----------------- + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of any + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +End diff --git a/pcre2/Makefile.am b/pcre2/Makefile.am new file mode 100644 index 000000000..5977ba06b --- /dev/null +++ b/pcre2/Makefile.am @@ -0,0 +1,796 @@ +## Process this file with automake to produce Makefile.in. + +AUTOMAKE_OPTIONS = subdir-objects +ACLOCAL_AMFLAGS = -I m4 +AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src + +## Specify the documentation files that are distributed. + +dist_doc_DATA = \ + AUTHORS \ + COPYING \ + ChangeLog \ + LICENCE \ + NEWS \ + README \ + doc/pcre2.txt \ + doc/pcre2-config.txt \ + doc/pcre2grep.txt \ + doc/pcre2test.txt + +dist_html_DATA = \ + doc/html/NON-AUTOTOOLS-BUILD.txt \ + doc/html/README.txt \ + doc/html/index.html \ + doc/html/pcre2-config.html \ + doc/html/pcre2.html \ + doc/html/pcre2_callout_enumerate.html \ + doc/html/pcre2_code_free.html \ + doc/html/pcre2_compile.html \ + doc/html/pcre2_compile_context_copy.html \ + doc/html/pcre2_compile_context_create.html \ + doc/html/pcre2_compile_context_free.html \ + doc/html/pcre2_config.html \ + doc/html/pcre2_dfa_match.html \ + doc/html/pcre2_general_context_copy.html \ + doc/html/pcre2_general_context_create.html \ + doc/html/pcre2_general_context_free.html \ + doc/html/pcre2_get_error_message.html \ + doc/html/pcre2_get_mark.html \ + doc/html/pcre2_get_ovector_count.html \ + doc/html/pcre2_get_ovector_pointer.html \ + doc/html/pcre2_get_startchar.html \ + doc/html/pcre2_jit_compile.html \ + doc/html/pcre2_jit_free_unused_memory.html \ + doc/html/pcre2_jit_match.html \ + doc/html/pcre2_jit_stack_assign.html \ + doc/html/pcre2_jit_stack_create.html \ + doc/html/pcre2_jit_stack_free.html \ + doc/html/pcre2_maketables.html \ + doc/html/pcre2_match.html \ + doc/html/pcre2_match_context_copy.html \ + doc/html/pcre2_match_context_create.html \ + doc/html/pcre2_match_context_free.html \ + doc/html/pcre2_match_data_create.html \ + doc/html/pcre2_match_data_create_from_pattern.html \ + doc/html/pcre2_match_data_free.html \ + doc/html/pcre2_pattern_info.html \ + doc/html/pcre2_serialize_decode.html \ + doc/html/pcre2_serialize_encode.html \ + doc/html/pcre2_serialize_free.html \ + doc/html/pcre2_serialize_get_number_of_codes.html \ + doc/html/pcre2_set_bsr.html \ + doc/html/pcre2_set_callout.html \ + doc/html/pcre2_set_character_tables.html \ + doc/html/pcre2_set_compile_recursion_guard.html \ + doc/html/pcre2_set_match_limit.html \ + doc/html/pcre2_set_offset_limit.html \ + doc/html/pcre2_set_newline.html \ + doc/html/pcre2_set_parens_nest_limit.html \ + doc/html/pcre2_set_recursion_limit.html \ + doc/html/pcre2_set_recursion_memory_management.html \ + doc/html/pcre2_substitute.html \ + doc/html/pcre2_substring_copy_byname.html \ + doc/html/pcre2_substring_copy_bynumber.html \ + doc/html/pcre2_substring_free.html \ + doc/html/pcre2_substring_get_byname.html \ + doc/html/pcre2_substring_get_bynumber.html \ + doc/html/pcre2_substring_length_byname.html \ + doc/html/pcre2_substring_length_bynumber.html \ + doc/html/pcre2_substring_list_free.html \ + doc/html/pcre2_substring_list_get.html \ + doc/html/pcre2_substring_nametable_scan.html \ + doc/html/pcre2_substring_number_from_name.html \ + doc/html/pcre2api.html \ + doc/html/pcre2build.html \ + doc/html/pcre2callout.html \ + doc/html/pcre2compat.html \ + doc/html/pcre2demo.html \ + doc/html/pcre2grep.html \ + doc/html/pcre2jit.html \ + doc/html/pcre2limits.html \ + doc/html/pcre2matching.html \ + doc/html/pcre2partial.html \ + doc/html/pcre2pattern.html \ + doc/html/pcre2perform.html \ + doc/html/pcre2posix.html \ + doc/html/pcre2sample.html \ + doc/html/pcre2serialize.html \ + doc/html/pcre2stack.html \ + doc/html/pcre2syntax.html \ + doc/html/pcre2test.html \ + doc/html/pcre2unicode.html + +dist_man_MANS = \ + doc/pcre2-config.1 \ + doc/pcre2.3 \ + doc/pcre2_callout_enumerate.3 \ + doc/pcre2_code_free.3 \ + doc/pcre2_compile.3 \ + doc/pcre2_compile_context_copy.3 \ + doc/pcre2_compile_context_create.3 \ + doc/pcre2_compile_context_free.3 \ + doc/pcre2_config.3 \ + doc/pcre2_dfa_match.3 \ + doc/pcre2_general_context_copy.3 \ + doc/pcre2_general_context_create.3 \ + doc/pcre2_general_context_free.3 \ + doc/pcre2_get_error_message.3 \ + doc/pcre2_get_mark.3 \ + doc/pcre2_get_ovector_count.3 \ + doc/pcre2_get_ovector_pointer.3 \ + doc/pcre2_get_startchar.3 \ + doc/pcre2_jit_compile.3 \ + doc/pcre2_jit_free_unused_memory.3 \ + doc/pcre2_jit_match.3 \ + doc/pcre2_jit_stack_assign.3 \ + doc/pcre2_jit_stack_create.3 \ + doc/pcre2_jit_stack_free.3 \ + doc/pcre2_maketables.3 \ + doc/pcre2_match.3 \ + doc/pcre2_match_context_copy.3 \ + doc/pcre2_match_context_create.3 \ + doc/pcre2_match_context_free.3 \ + doc/pcre2_match_data_create.3 \ + doc/pcre2_match_data_create_from_pattern.3 \ + doc/pcre2_match_data_free.3 \ + doc/pcre2_pattern_info.3 \ + doc/pcre2_serialize_decode.3 \ + doc/pcre2_serialize_encode.3 \ + doc/pcre2_serialize_free.3 \ + doc/pcre2_serialize_get_number_of_codes.3 \ + doc/pcre2_set_bsr.3 \ + doc/pcre2_set_callout.3 \ + doc/pcre2_set_character_tables.3 \ + doc/pcre2_set_compile_recursion_guard.3 \ + doc/pcre2_set_match_limit.3 \ + doc/pcre2_set_offset_limit.3 \ + doc/pcre2_set_newline.3 \ + doc/pcre2_set_parens_nest_limit.3 \ + doc/pcre2_set_recursion_limit.3 \ + doc/pcre2_set_recursion_memory_management.3 \ + doc/pcre2_substitute.3 \ + doc/pcre2_substring_copy_byname.3 \ + doc/pcre2_substring_copy_bynumber.3 \ + doc/pcre2_substring_free.3 \ + doc/pcre2_substring_get_byname.3 \ + doc/pcre2_substring_get_bynumber.3 \ + doc/pcre2_substring_length_byname.3 \ + doc/pcre2_substring_length_bynumber.3 \ + doc/pcre2_substring_list_free.3 \ + doc/pcre2_substring_list_get.3 \ + doc/pcre2_substring_nametable_scan.3 \ + doc/pcre2_substring_number_from_name.3 \ + doc/pcre2api.3 \ + doc/pcre2build.3 \ + doc/pcre2callout.3 \ + doc/pcre2compat.3 \ + doc/pcre2demo.3 \ + doc/pcre2grep.1 \ + doc/pcre2jit.3 \ + doc/pcre2limits.3 \ + doc/pcre2matching.3 \ + doc/pcre2partial.3 \ + doc/pcre2pattern.3 \ + doc/pcre2perform.3 \ + doc/pcre2posix.3 \ + doc/pcre2sample.3 \ + doc/pcre2serialize.3 \ + doc/pcre2stack.3 \ + doc/pcre2syntax.3 \ + doc/pcre2test.1 \ + doc/pcre2unicode.3 + +# The Libtool libraries to install. We'll add to this later. + +lib_LTLIBRARIES = + +# Unit tests you want to run when people type 'make check'. +# TESTS is for binary unit tests, check_SCRIPTS for script-based tests + +TESTS = +check_SCRIPTS = +dist_noinst_SCRIPTS = + +# Some of the binaries we make are to be installed, and others are +# (non-user-visible) helper programs needed to build the libraries. + +bin_PROGRAMS = +noinst_PROGRAMS = + +# Additional files to delete on 'make clean', 'make distclean', +# and 'make maintainer-clean'. + +CLEANFILES = +DISTCLEANFILES = src/config.h.in~ config.h +MAINTAINERCLEANFILES = + +# Additional files to bundle with the distribution, over and above what +# the Autotools include by default. + +EXTRA_DIST = + +# These files contain additional m4 macros that are used by autoconf. + +EXTRA_DIST += \ + m4/ax_pthread.m4 m4/pcre2_visibility.m4 + +# These files contain maintenance information + +EXTRA_DIST += \ + NON-AUTOTOOLS-BUILD \ + HACKING + +# These files are used in the preparation of a release + +EXTRA_DIST += \ + PrepareRelease \ + CheckMan \ + CleanTxt \ + Detrail \ + 132html \ + doc/index.html.src + +# These files are usable versions of pcre2.h and config.h that are distributed +# for the benefit of people who are building PCRE2 manually, without the +# Autotools support. + +EXTRA_DIST += \ + src/pcre2.h.generic \ + src/config.h.generic + +# The only difference between pcre2.h.in and pcre2.h is the setting of the PCRE +# version number. Therefore, we can create the generic version just by copying. + +src/pcre2.h.generic: src/pcre2.h.in configure.ac + rm -f $@ + cp -p src/pcre2.h $@ + +# It is more complicated for config.h.generic. We need the version that results +# from a default configuration so as to get all the default values for PCRE +# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by +# doing a configure in a temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you just try +# running configure in a new directory, it complains. For this reason, we move +# config.status out of the way while doing the default configuration. The +# resulting config.h is munged by perl to put #ifdefs round any #defines for +# macros with values, and to #undef all boolean macros such as HAVE_xxx and +# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make +# sure that PCRE2_EXP_DEFN is unset (in case it has visibility settings). + +src/config.h.generic: configure.ac + rm -rf $@ _generic + mkdir _generic + cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside + cd _generic && $(abs_top_srcdir)/configure || : + cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs + test -f _generic/src/config.h + perl -n \ + -e 'BEGIN{$$blank=0;}' \ + -e 'if(/PCRE2_EXP_DEFN/){print"/* #undef PCRE2_EXP_DEFN */\n";$$blank=0;next;}' \ + -e 'if(/to make a symbol visible/){next;}' \ + -e 'if(/__attribute__ \(\(visibility/){next;}' \ + -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ + -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ + -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ + -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ + _generic/src/config.h >$@ + rm -rf _generic + +MAINTAINERCLEANFILES += src/pcre2.h.generic src/config.h.generic + +# These are the header files we'll install. We do not distribute pcre2.h +# because it is generated from pcre2.h.in. + +nodist_include_HEADERS = src/pcre2.h +include_HEADERS = src/pcre2posix.h + +# This is the "config" script. + +bin_SCRIPTS = pcre2-config + +## --------------------------------------------------------------- +## The dftables program is used to rebuild character tables before compiling +## PCRE2, if --enable-rebuild-chartables is specified. It is not a user-visible +## program. The default (when --enable-rebuild-chartables is not specified) is +## to copy a distributed set of tables that are defined for ASCII code. In this +## case, dftables is not needed. + +if WITH_REBUILD_CHARTABLES +noinst_PROGRAMS += dftables +dftables_SOURCES = src/dftables.c +src/pcre2_chartables.c: dftables$(EXEEXT) + rm -f $@ + ./dftables$(EXEEXT) $@ +else +src/pcre2_chartables.c: $(srcdir)/src/pcre2_chartables.c.dist + rm -f $@ + $(LN_S) $(abs_srcdir)/src/pcre2_chartables.c.dist $(abs_builddir)/src/pcre2_chartables.c +endif # WITH_REBUILD_CHARTABLES + +BUILT_SOURCES = src/pcre2_chartables.c +NODIST_SOURCES = src/pcre2_chartables.c + +## Define the list of common sources, then arrange to build whichever of the +## 8-, 16-, or 32-bit libraries are configured. + +COMMON_SOURCES = \ + src/pcre2_auto_possess.c \ + src/pcre2_compile.c \ + src/pcre2_config.c \ + src/pcre2_context.c \ + src/pcre2_dfa_match.c \ + src/pcre2_error.c \ + src/pcre2_find_bracket.c \ + src/pcre2_internal.h \ + src/pcre2_intmodedep.h \ + src/pcre2_jit_compile.c \ + src/pcre2_maketables.c \ + src/pcre2_match.c \ + src/pcre2_match_data.c \ + src/pcre2_newline.c \ + src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c \ + src/pcre2_serialize.c \ + src/pcre2_string_utils.c \ + src/pcre2_study.c \ + src/pcre2_substitute.c \ + src/pcre2_substring.c \ + src/pcre2_tables.c \ + src/pcre2_ucd.c \ + src/pcre2_ucp.h \ + src/pcre2_valid_utf.c \ + src/pcre2_xclass.c + +if WITH_PCRE2_8 +lib_LTLIBRARIES += libpcre2-8.la +libpcre2_8_la_SOURCES = \ + $(COMMON_SOURCES) +nodist_libpcre2_8_la_SOURCES = \ + $(NODIST_SOURCES) +libpcre2_8_la_CFLAGS = \ + -DPCRE2_CODE_UNIT_WIDTH=8 \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) +libpcre2_8_la_LIBADD = +endif # WITH_PCRE2_8 + +if WITH_PCRE2_16 +lib_LTLIBRARIES += libpcre2-16.la +libpcre2_16_la_SOURCES = \ + $(COMMON_SOURCES) +nodist_libpcre2_16_la_SOURCES = \ + $(NODIST_SOURCES) +libpcre2_16_la_CFLAGS = \ + -DPCRE2_CODE_UNIT_WIDTH=16 \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) +libpcre2_16_la_LIBADD = +endif # WITH_PCRE2_16 + +if WITH_PCRE2_32 +lib_LTLIBRARIES += libpcre2-32.la +libpcre2_32_la_SOURCES = \ + $(COMMON_SOURCES) +nodist_libpcre2_32_la_SOURCES = \ + $(NODIST_SOURCES) +libpcre2_32_la_CFLAGS = \ + -DPCRE2_CODE_UNIT_WIDTH=32 \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) +libpcre2_32_la_LIBADD = +endif # WITH_PCRE2_32 + +# The pcre2_chartables.c.dist file is the default version of +# pcre2_chartables.c, used unless --enable-rebuild-chartables is specified. + +EXTRA_DIST += src/pcre2_chartables.c.dist +CLEANFILES += src/pcre2_chartables.c + +# The JIT compiler lives in a separate directory, but its files are #included +# when pcre2_jit_compile.c is processed, so they must be distributed. + +EXTRA_DIST += \ + src/sljit/sljitConfig.h \ + src/sljit/sljitConfigInternal.h \ + src/sljit/sljitExecAllocator.c \ + src/sljit/sljitLir.c \ + src/sljit/sljitLir.h \ + src/sljit/sljitNativeARM_32.c \ + src/sljit/sljitNativeARM_64.c \ + src/sljit/sljitNativeARM_T2_32.c \ + src/sljit/sljitNativeMIPS_32.c \ + src/sljit/sljitNativeMIPS_64.c \ + src/sljit/sljitNativeMIPS_common.c \ + src/sljit/sljitNativePPC_32.c \ + src/sljit/sljitNativePPC_64.c \ + src/sljit/sljitNativePPC_common.c \ + src/sljit/sljitNativeSPARC_32.c \ + src/sljit/sljitNativeSPARC_common.c \ + src/sljit/sljitNativeTILEGX-encoder.c \ + src/sljit/sljitNativeTILEGX_64.c \ + src/sljit/sljitNativeX86_32.c \ + src/sljit/sljitNativeX86_64.c \ + src/sljit/sljitNativeX86_common.c \ + src/sljit/sljitUtils.c + +# Some of the JIT sources are also in separate files that are #included. + +EXTRA_DIST += \ + src/pcre2_jit_match.c \ + src/pcre2_jit_misc.c + +if WITH_PCRE2_8 +libpcre2_8_la_LDFLAGS = $(EXTRA_LIBPCRE2_8_LDFLAGS) +endif # WITH_PCRE2_8 +if WITH_PCRE2_16 +libpcre2_16_la_LDFLAGS = $(EXTRA_LIBPCRE2_16_LDFLAGS) +endif # WITH_PCRE2_16 +if WITH_PCRE2_32 +libpcre2_32_la_LDFLAGS = $(EXTRA_LIBPCRE2_32_LDFLAGS) +endif # WITH_PCRE2_32 + +if WITH_VALGRIND +if WITH_PCRE2_8 +libpcre2_8_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE2_8 +if WITH_PCRE2_16 +libpcre2_16_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE2_16 +if WITH_PCRE2_32 +libpcre2_32_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE2_32 +endif # WITH_VALGRIND + +if WITH_GCOV +if WITH_PCRE2_8 +libpcre2_8_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE2_8 +if WITH_PCRE2_16 +libpcre2_16_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE2_16 +if WITH_PCRE2_32 +libpcre2_32_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE2_32 +endif # WITH_GCOV + +## A version of the 8-bit library that has a POSIX API. + +if WITH_PCRE2_8 +lib_LTLIBRARIES += libpcre2-posix.la +libpcre2_posix_la_SOURCES = src/pcre2posix.c +libpcre2_posix_la_CFLAGS = \ + -DPCRE2_CODE_UNIT_WIDTH=8 \ + $(VISIBILITY_CFLAGS) $(AM_CFLAGS) +libpcre2_posix_la_LDFLAGS = $(EXTRA_LIBPCRE2_POSIX_LDFLAGS) +libpcre2_posix_la_LIBADD = libpcre2-8.la +if WITH_GCOV +libpcre2_posix_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_GCOV +endif # WITH_PCRE2_8 + +## Build pcre2grep if the 8-bit library is enabled + +if WITH_PCRE2_8 +bin_PROGRAMS += pcre2grep +pcre2grep_SOURCES = src/pcre2grep.c +pcre2grep_CFLAGS = $(AM_CFLAGS) +pcre2grep_LDADD = $(LIBZ) $(LIBBZ2) +pcre2grep_LDADD += libpcre2-8.la +if WITH_GCOV +pcre2grep_CFLAGS += $(GCOV_CFLAGS) +pcre2grep_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV +endif # WITH_PCRE2_8 + +## -------- Testing ---------- + +## If JIT support is enabled, arrange for the JIT test program to run. + +if WITH_JIT +TESTS += pcre2_jit_test +noinst_PROGRAMS += pcre2_jit_test +pcre2_jit_test_SOURCES = src/pcre2_jit_test.c +pcre2_jit_test_CFLAGS = $(AM_CFLAGS) +pcre2_jit_test_LDADD = +if WITH_PCRE2_8 +pcre2_jit_test_LDADD += libpcre2-8.la +endif # WITH_PCRE2_8 +if WITH_PCRE2_16 +pcre2_jit_test_LDADD += libpcre2-16.la +endif # WITH_PCRE2_16 +if WITH_PCRE2_32 +pcre2_jit_test_LDADD += libpcre2-32.la +endif # WITH_PCRE2_32 +if WITH_GCOV +pcre2_jit_test_CFLAGS += $(GCOV_CFLAGS) +pcre2_jit_test_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV +endif # WITH_JIT + +# Build the general pcre2test program. The file src/pcre2_printint.c is +# #included by pcre2test as many times as needed, at different code unit +# widths. + +bin_PROGRAMS += pcre2test +EXTRA_DIST += src/pcre2_printint.c +pcre2test_SOURCES = src/pcre2test.c +pcre2test_CFLAGS = $(AM_CFLAGS) +pcre2test_LDADD = $(LIBREADLINE) + +if WITH_PCRE2_8 +pcre2test_LDADD += libpcre2-8.la libpcre2-posix.la +endif # WITH_PCRE2_8 + +if WITH_PCRE2_16 +pcre2test_LDADD += libpcre2-16.la +endif # WITH_PCRE2_16 + +if WITH_PCRE2_32 +pcre2test_LDADD += libpcre2-32.la +endif # WITH_PCRE2_32 + +if WITH_VALGRIND +pcre2test_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_VALGRIND + +if WITH_GCOV +pcre2test_CFLAGS += $(GCOV_CFLAGS) +pcre2test_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV + +## The main library tests. Each test is a binary plus a script that runs that +## binary in various ways. We install these test binaries in case folks find it +## helpful. + +TESTS += RunTest +dist_noinst_SCRIPTS += RunTest + +EXTRA_DIST += RunTest.bat + +## When the 8-bit library is configured, pcre2grep will have been built. + +if WITH_PCRE2_8 +TESTS += RunGrepTest +dist_noinst_SCRIPTS += RunGrepTest +endif # WITH_PCRE2_8 + +## Distribute all the test data files + +EXTRA_DIST += \ + testdata/grepbinary \ + testdata/grepfilelist \ + testdata/grepinput \ + testdata/grepinput3 \ + testdata/grepinput8 \ + testdata/grepinputv \ + testdata/grepinputx \ + testdata/greplist \ + testdata/grepoutput \ + testdata/grepoutput8 \ + testdata/grepoutputN \ + testdata/greppatN4 \ + testdata/testinput1 \ + testdata/testinput2 \ + testdata/testinput3 \ + testdata/testinput4 \ + testdata/testinput5 \ + testdata/testinput6 \ + testdata/testinput7 \ + testdata/testinput8 \ + testdata/testinput9 \ + testdata/testinput10 \ + testdata/testinput11 \ + testdata/testinput12 \ + testdata/testinput13 \ + testdata/testinput14 \ + testdata/testinput15 \ + testdata/testinput16 \ + testdata/testinput17 \ + testdata/testinput18 \ + testdata/testinput19 \ + testdata/testinput20 \ + testdata/testinput21 \ + testdata/testinput22 \ + testdata/testinput23 \ + testdata/testinputEBC \ + testdata/testoutput1 \ + testdata/testoutput2 \ + testdata/testoutput3 \ + testdata/testoutput3A \ + testdata/testoutput3B \ + testdata/testoutput4 \ + testdata/testoutput5 \ + testdata/testoutput6 \ + testdata/testoutput7 \ + testdata/testoutput8-16-2 \ + testdata/testoutput8-16-3 \ + testdata/testoutput8-16-3 \ + testdata/testoutput8-32-2 \ + testdata/testoutput8-32-3 \ + testdata/testoutput8-32-4 \ + testdata/testoutput8-8-2 \ + testdata/testoutput8-8-3 \ + testdata/testoutput8-8-4 \ + testdata/testoutput9 \ + testdata/testoutput10 \ + testdata/testoutput11-16 \ + testdata/testoutput11-32 \ + testdata/testoutput12-16 \ + testdata/testoutput12-32 \ + testdata/testoutput13 \ + testdata/testoutput14-16 \ + testdata/testoutput14-32 \ + testdata/testoutput14-8 \ + testdata/testoutput15 \ + testdata/testoutput16 \ + testdata/testoutput17 \ + testdata/testoutput18 \ + testdata/testoutput19 \ + testdata/testoutput20 \ + testdata/testoutput21 \ + testdata/testoutput22-16 \ + testdata/testoutput22-32 \ + testdata/testoutput22-8 \ + testdata/testoutput23 \ + testdata/testoutputEBC \ + testdata/valgrind-jit.supp \ + testdata/wintestinput3 \ + testdata/wintestoutput3 \ + perltest.sh + +# RunTest and RunGrepTest should clean up after themselves, but just in case +# they don't, add their working files to CLEANFILES. + +CLEANFILES += \ + testSinput \ + test3input \ + test3output \ + test3outputA \ + test3outputB \ + testtry \ + teststdout \ + teststderr \ + teststderrgrep \ + testtemp1grep \ + testtemp2grep \ + testtrygrep \ + testNinputgrep + +## ------------ End of testing ------------- + + +# PCRE2 demonstration program. Not built automatcally. The point is that the +# users should build it themselves. So just distribute the source. + +EXTRA_DIST += src/pcre2demo.c + + +# We have .pc files for pkg-config users. + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = + +if WITH_PCRE2_8 +pkgconfig_DATA += libpcre2-8.pc libpcre2-posix.pc +endif + +if WITH_PCRE2_16 +pkgconfig_DATA += libpcre2-16.pc +endif + +if WITH_PCRE2_32 +pkgconfig_DATA += libpcre2-32.pc +endif + + +# gcov/lcov code coverage reporting +# +# Coverage reporting targets: +# +# coverage: Create a coverage report from 'make check' +# coverage-baseline: Capture baseline coverage information +# coverage-reset: This zeros the coverage counters only +# coverage-report: This creates the coverage report only +# coverage-clean-report: This removes the generated coverage report +# without cleaning the coverage data itself +# coverage-clean-data: This removes the captured coverage data without +# removing the coverage files created at compile time (*.gcno) +# coverage-clean: This cleans all coverage data including the generated +# coverage report. + +if WITH_GCOV +COVERAGE_TEST_NAME = $(PACKAGE) +COVERAGE_NAME = $(PACKAGE)-$(VERSION) +COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info +COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage +COVERAGE_LCOV_EXTRA_FLAGS = +COVERAGE_GENHTML_EXTRA_FLAGS = + +coverage_quiet = $(coverage_quiet_$(V)) +coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +coverage_quiet_0 = --quiet + +coverage-check: all + -$(MAKE) $(AM_MAKEFLAGS) -k check + +coverage-baseline: + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --output-file "$(COVERAGE_OUTPUT_FILE)" \ + --capture \ + --initial + +coverage-report: + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --capture \ + --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ + --test-name "$(COVERAGE_TEST_NAME)" \ + --no-checksum \ + --compat-libtool \ + $(COVERAGE_LCOV_EXTRA_FLAGS) + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --output-file "$(COVERAGE_OUTPUT_FILE)" \ + --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ + "/tmp/*" \ + "/usr/include/*" \ + "$(includedir)/*" + -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" + LANG=C $(GENHTML) $(coverage_quiet) \ + --prefix $(top_builddir) \ + --output-directory "$(COVERAGE_OUTPUT_DIR)" \ + --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ + --show-details "$(COVERAGE_OUTPUT_FILE)" \ + --legend \ + $(COVERAGE_GENHTML_EXTRA_FLAGS) + @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" + +coverage-reset: + -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) + +coverage-clean-report: + -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" + -rm -rf "$(COVERAGE_OUTPUT_DIR)" + +coverage-clean-data: + -find $(top_builddir) -name "*.gcda" -delete + +coverage-clean: coverage-reset coverage-clean-report coverage-clean-data + -find $(top_builddir) -name "*.gcno" -delete + +coverage-distclean: coverage-clean + +coverage: coverage-reset coverage-baseline coverage-check coverage-report +clean-local: coverage-clean +distclean-local: coverage-distclean + +.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean + +# Without coverage support, still arrange for 'make distclean' to get rid of +# any coverage files that may have been left from a different configuration. + +else + +coverage: + @echo "Configuring with --enable-coverage is required to generate code coverage report." + +DISTCLEANFILES += src/*.gcda src/*.gcno + +distclean-local: + rm -rf $(PACKAGE)-$(VERSION)-coverage* + +endif # WITH_GCOV + +## CMake support + +EXTRA_DIST += \ + cmake/COPYING-CMAKE-SCRIPTS \ + cmake/FindPackageHandleStandardArgs.cmake \ + cmake/FindReadline.cmake \ + cmake/FindEditline.cmake \ + CMakeLists.txt \ + config-cmake.h.in + +## end Makefile.am diff --git a/pcre2/Makefile.in b/pcre2/Makefile.in new file mode 100644 index 000000000..fd07c58cb --- /dev/null +++ b/pcre2/Makefile.in @@ -0,0 +1,3136 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = $(am__EXEEXT_3) RunTest $(am__append_29) +bin_PROGRAMS = $(am__EXEEXT_1) pcre2test$(EXEEXT) +noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) +@WITH_REBUILD_CHARTABLES_TRUE@am__append_1 = dftables +@WITH_PCRE2_8_TRUE@am__append_2 = libpcre2-8.la +@WITH_PCRE2_16_TRUE@am__append_3 = libpcre2-16.la +@WITH_PCRE2_32_TRUE@am__append_4 = libpcre2-32.la +@WITH_PCRE2_8_TRUE@@WITH_VALGRIND_TRUE@am__append_5 = $(VALGRIND_CFLAGS) +@WITH_PCRE2_16_TRUE@@WITH_VALGRIND_TRUE@am__append_6 = $(VALGRIND_CFLAGS) +@WITH_PCRE2_32_TRUE@@WITH_VALGRIND_TRUE@am__append_7 = $(VALGRIND_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_8 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE2_16_TRUE@am__append_9 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE2_32_TRUE@am__append_10 = $(GCOV_CFLAGS) +@WITH_PCRE2_8_TRUE@am__append_11 = libpcre2-posix.la +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_12 = $(GCOV_CFLAGS) +@WITH_PCRE2_8_TRUE@am__append_13 = pcre2grep +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_14 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_15 = $(GCOV_LIBS) +@WITH_JIT_TRUE@am__append_16 = pcre2_jit_test +@WITH_JIT_TRUE@am__append_17 = pcre2_jit_test +@WITH_JIT_TRUE@@WITH_PCRE2_8_TRUE@am__append_18 = libpcre2-8.la +@WITH_JIT_TRUE@@WITH_PCRE2_16_TRUE@am__append_19 = libpcre2-16.la +@WITH_JIT_TRUE@@WITH_PCRE2_32_TRUE@am__append_20 = libpcre2-32.la +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_21 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_22 = $(GCOV_LIBS) +@WITH_PCRE2_8_TRUE@am__append_23 = libpcre2-8.la libpcre2-posix.la +@WITH_PCRE2_16_TRUE@am__append_24 = libpcre2-16.la +@WITH_PCRE2_32_TRUE@am__append_25 = libpcre2-32.la +@WITH_VALGRIND_TRUE@am__append_26 = $(VALGRIND_CFLAGS) +@WITH_GCOV_TRUE@am__append_27 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@am__append_28 = $(GCOV_LIBS) +@WITH_PCRE2_8_TRUE@am__append_29 = RunGrepTest +@WITH_PCRE2_8_TRUE@am__append_30 = RunGrepTest +@WITH_PCRE2_8_TRUE@am__append_31 = libpcre2-8.pc libpcre2-posix.pc +@WITH_PCRE2_16_TRUE@am__append_32 = libpcre2-16.pc +@WITH_PCRE2_32_TRUE@am__append_33 = libpcre2-32.pc +@WITH_GCOV_FALSE@am__append_34 = src/*.gcda src/*.gcno +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pcre2_visibility.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__dist_noinst_SCRIPTS_DIST) \ + $(dist_doc_DATA) $(dist_html_DATA) $(include_HEADERS) \ + $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc \ + libpcre2-posix.pc pcre2-config src/pcre2.h +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libpcre2_16_la_DEPENDENCIES = +am__libpcre2_16_la_SOURCES_DIST = src/pcre2_auto_possess.c \ + src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ + src/pcre2_dfa_match.c src/pcre2_error.c \ + src/pcre2_find_bracket.c src/pcre2_internal.h \ + src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ + src/pcre2_maketables.c src/pcre2_match.c \ + src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c src/pcre2_serialize.c \ + src/pcre2_string_utils.c src/pcre2_study.c \ + src/pcre2_substitute.c src/pcre2_substring.c \ + src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ + src/pcre2_valid_utf.c src/pcre2_xclass.c +am__dirstamp = $(am__leading_dot)dirstamp +am__objects_1 = src/libpcre2_16_la-pcre2_auto_possess.lo \ + src/libpcre2_16_la-pcre2_compile.lo \ + src/libpcre2_16_la-pcre2_config.lo \ + src/libpcre2_16_la-pcre2_context.lo \ + src/libpcre2_16_la-pcre2_dfa_match.lo \ + src/libpcre2_16_la-pcre2_error.lo \ + src/libpcre2_16_la-pcre2_find_bracket.lo \ + src/libpcre2_16_la-pcre2_jit_compile.lo \ + src/libpcre2_16_la-pcre2_maketables.lo \ + src/libpcre2_16_la-pcre2_match.lo \ + src/libpcre2_16_la-pcre2_match_data.lo \ + src/libpcre2_16_la-pcre2_newline.lo \ + src/libpcre2_16_la-pcre2_ord2utf.lo \ + src/libpcre2_16_la-pcre2_pattern_info.lo \ + src/libpcre2_16_la-pcre2_serialize.lo \ + src/libpcre2_16_la-pcre2_string_utils.lo \ + src/libpcre2_16_la-pcre2_study.lo \ + src/libpcre2_16_la-pcre2_substitute.lo \ + src/libpcre2_16_la-pcre2_substring.lo \ + src/libpcre2_16_la-pcre2_tables.lo \ + src/libpcre2_16_la-pcre2_ucd.lo \ + src/libpcre2_16_la-pcre2_valid_utf.lo \ + src/libpcre2_16_la-pcre2_xclass.lo +@WITH_PCRE2_16_TRUE@am_libpcre2_16_la_OBJECTS = $(am__objects_1) +am__objects_2 = src/libpcre2_16_la-pcre2_chartables.lo +@WITH_PCRE2_16_TRUE@nodist_libpcre2_16_la_OBJECTS = $(am__objects_2) +libpcre2_16_la_OBJECTS = $(am_libpcre2_16_la_OBJECTS) \ + $(nodist_libpcre2_16_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpcre2_16_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpcre2_16_la_CFLAGS) $(CFLAGS) $(libpcre2_16_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@WITH_PCRE2_16_TRUE@am_libpcre2_16_la_rpath = -rpath $(libdir) +libpcre2_32_la_DEPENDENCIES = +am__libpcre2_32_la_SOURCES_DIST = src/pcre2_auto_possess.c \ + src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ + src/pcre2_dfa_match.c src/pcre2_error.c \ + src/pcre2_find_bracket.c src/pcre2_internal.h \ + src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ + src/pcre2_maketables.c src/pcre2_match.c \ + src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c src/pcre2_serialize.c \ + src/pcre2_string_utils.c src/pcre2_study.c \ + src/pcre2_substitute.c src/pcre2_substring.c \ + src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ + src/pcre2_valid_utf.c src/pcre2_xclass.c +am__objects_3 = src/libpcre2_32_la-pcre2_auto_possess.lo \ + src/libpcre2_32_la-pcre2_compile.lo \ + src/libpcre2_32_la-pcre2_config.lo \ + src/libpcre2_32_la-pcre2_context.lo \ + src/libpcre2_32_la-pcre2_dfa_match.lo \ + src/libpcre2_32_la-pcre2_error.lo \ + src/libpcre2_32_la-pcre2_find_bracket.lo \ + src/libpcre2_32_la-pcre2_jit_compile.lo \ + src/libpcre2_32_la-pcre2_maketables.lo \ + src/libpcre2_32_la-pcre2_match.lo \ + src/libpcre2_32_la-pcre2_match_data.lo \ + src/libpcre2_32_la-pcre2_newline.lo \ + src/libpcre2_32_la-pcre2_ord2utf.lo \ + src/libpcre2_32_la-pcre2_pattern_info.lo \ + src/libpcre2_32_la-pcre2_serialize.lo \ + src/libpcre2_32_la-pcre2_string_utils.lo \ + src/libpcre2_32_la-pcre2_study.lo \ + src/libpcre2_32_la-pcre2_substitute.lo \ + src/libpcre2_32_la-pcre2_substring.lo \ + src/libpcre2_32_la-pcre2_tables.lo \ + src/libpcre2_32_la-pcre2_ucd.lo \ + src/libpcre2_32_la-pcre2_valid_utf.lo \ + src/libpcre2_32_la-pcre2_xclass.lo +@WITH_PCRE2_32_TRUE@am_libpcre2_32_la_OBJECTS = $(am__objects_3) +am__objects_4 = src/libpcre2_32_la-pcre2_chartables.lo +@WITH_PCRE2_32_TRUE@nodist_libpcre2_32_la_OBJECTS = $(am__objects_4) +libpcre2_32_la_OBJECTS = $(am_libpcre2_32_la_OBJECTS) \ + $(nodist_libpcre2_32_la_OBJECTS) +libpcre2_32_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpcre2_32_la_CFLAGS) $(CFLAGS) $(libpcre2_32_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@WITH_PCRE2_32_TRUE@am_libpcre2_32_la_rpath = -rpath $(libdir) +libpcre2_8_la_DEPENDENCIES = +am__libpcre2_8_la_SOURCES_DIST = src/pcre2_auto_possess.c \ + src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ + src/pcre2_dfa_match.c src/pcre2_error.c \ + src/pcre2_find_bracket.c src/pcre2_internal.h \ + src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ + src/pcre2_maketables.c src/pcre2_match.c \ + src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c src/pcre2_serialize.c \ + src/pcre2_string_utils.c src/pcre2_study.c \ + src/pcre2_substitute.c src/pcre2_substring.c \ + src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ + src/pcre2_valid_utf.c src/pcre2_xclass.c +am__objects_5 = src/libpcre2_8_la-pcre2_auto_possess.lo \ + src/libpcre2_8_la-pcre2_compile.lo \ + src/libpcre2_8_la-pcre2_config.lo \ + src/libpcre2_8_la-pcre2_context.lo \ + src/libpcre2_8_la-pcre2_dfa_match.lo \ + src/libpcre2_8_la-pcre2_error.lo \ + src/libpcre2_8_la-pcre2_find_bracket.lo \ + src/libpcre2_8_la-pcre2_jit_compile.lo \ + src/libpcre2_8_la-pcre2_maketables.lo \ + src/libpcre2_8_la-pcre2_match.lo \ + src/libpcre2_8_la-pcre2_match_data.lo \ + src/libpcre2_8_la-pcre2_newline.lo \ + src/libpcre2_8_la-pcre2_ord2utf.lo \ + src/libpcre2_8_la-pcre2_pattern_info.lo \ + src/libpcre2_8_la-pcre2_serialize.lo \ + src/libpcre2_8_la-pcre2_string_utils.lo \ + src/libpcre2_8_la-pcre2_study.lo \ + src/libpcre2_8_la-pcre2_substitute.lo \ + src/libpcre2_8_la-pcre2_substring.lo \ + src/libpcre2_8_la-pcre2_tables.lo \ + src/libpcre2_8_la-pcre2_ucd.lo \ + src/libpcre2_8_la-pcre2_valid_utf.lo \ + src/libpcre2_8_la-pcre2_xclass.lo +@WITH_PCRE2_8_TRUE@am_libpcre2_8_la_OBJECTS = $(am__objects_5) +am__objects_6 = src/libpcre2_8_la-pcre2_chartables.lo +@WITH_PCRE2_8_TRUE@nodist_libpcre2_8_la_OBJECTS = $(am__objects_6) +libpcre2_8_la_OBJECTS = $(am_libpcre2_8_la_OBJECTS) \ + $(nodist_libpcre2_8_la_OBJECTS) +libpcre2_8_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre2_8_la_CFLAGS) \ + $(CFLAGS) $(libpcre2_8_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE2_8_TRUE@am_libpcre2_8_la_rpath = -rpath $(libdir) +@WITH_PCRE2_8_TRUE@libpcre2_posix_la_DEPENDENCIES = libpcre2-8.la +am__libpcre2_posix_la_SOURCES_DIST = src/pcre2posix.c +@WITH_PCRE2_8_TRUE@am_libpcre2_posix_la_OBJECTS = \ +@WITH_PCRE2_8_TRUE@ src/libpcre2_posix_la-pcre2posix.lo +libpcre2_posix_la_OBJECTS = $(am_libpcre2_posix_la_OBJECTS) +libpcre2_posix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpcre2_posix_la_CFLAGS) $(CFLAGS) \ + $(libpcre2_posix_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE2_8_TRUE@am_libpcre2_posix_la_rpath = -rpath $(libdir) +@WITH_PCRE2_8_TRUE@am__EXEEXT_1 = pcre2grep$(EXEEXT) +@WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_2 = dftables$(EXEEXT) +@WITH_JIT_TRUE@am__EXEEXT_3 = pcre2_jit_test$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am__dftables_SOURCES_DIST = src/dftables.c +@WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS = \ +@WITH_REBUILD_CHARTABLES_TRUE@ src/dftables.$(OBJEXT) +dftables_OBJECTS = $(am_dftables_OBJECTS) +dftables_LDADD = $(LDADD) +am__pcre2_jit_test_SOURCES_DIST = src/pcre2_jit_test.c +@WITH_JIT_TRUE@am_pcre2_jit_test_OBJECTS = \ +@WITH_JIT_TRUE@ src/pcre2_jit_test-pcre2_jit_test.$(OBJEXT) +pcre2_jit_test_OBJECTS = $(am_pcre2_jit_test_OBJECTS) +am__DEPENDENCIES_1 = +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__DEPENDENCIES_2 = \ +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@ $(am__DEPENDENCIES_1) +@WITH_JIT_TRUE@pcre2_jit_test_DEPENDENCIES = $(am__append_18) \ +@WITH_JIT_TRUE@ $(am__append_19) $(am__append_20) \ +@WITH_JIT_TRUE@ $(am__DEPENDENCIES_2) +pcre2_jit_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(pcre2_jit_test_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ + $@ +am__pcre2grep_SOURCES_DIST = src/pcre2grep.c +@WITH_PCRE2_8_TRUE@am_pcre2grep_OBJECTS = \ +@WITH_PCRE2_8_TRUE@ src/pcre2grep-pcre2grep.$(OBJEXT) +pcre2grep_OBJECTS = $(am_pcre2grep_OBJECTS) +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__DEPENDENCIES_3 = \ +@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_1) +@WITH_PCRE2_8_TRUE@pcre2grep_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_1) libpcre2-8.la \ +@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_3) +pcre2grep_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre2grep_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_pcre2test_OBJECTS = src/pcre2test-pcre2test.$(OBJEXT) +pcre2test_OBJECTS = $(am_pcre2test_OBJECTS) +@WITH_GCOV_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) +pcre2test_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_23) \ + $(am__append_24) $(am__append_25) $(am__DEPENDENCIES_4) +pcre2test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre2test_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest +SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpcre2_16_la_SOURCES) $(nodist_libpcre2_16_la_SOURCES) \ + $(libpcre2_32_la_SOURCES) $(nodist_libpcre2_32_la_SOURCES) \ + $(libpcre2_8_la_SOURCES) $(nodist_libpcre2_8_la_SOURCES) \ + $(libpcre2_posix_la_SOURCES) $(dftables_SOURCES) \ + $(pcre2_jit_test_SOURCES) $(pcre2grep_SOURCES) \ + $(pcre2test_SOURCES) +DIST_SOURCES = $(am__libpcre2_16_la_SOURCES_DIST) \ + $(am__libpcre2_32_la_SOURCES_DIST) \ + $(am__libpcre2_8_la_SOURCES_DIST) \ + $(am__libpcre2_posix_la_SOURCES_DIST) \ + $(am__dftables_SOURCES_DIST) \ + $(am__pcre2_jit_test_SOURCES_DIST) \ + $(am__pcre2grep_SOURCES_DIST) $(pcre2test_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(dist_man_MANS) +DATA = $(dist_doc_DATA) $(dist_html_DATA) $(pkgconfig_DATA) +HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope check recheck +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ + $(srcdir)/libpcre2-16.pc.in $(srcdir)/libpcre2-32.pc.in \ + $(srcdir)/libpcre2-8.pc.in $(srcdir)/libpcre2-posix.pc.in \ + $(srcdir)/pcre2-config.in $(top_srcdir)/src/config.h.in \ + $(top_srcdir)/src/pcre2.h.in AUTHORS COPYING ChangeLog INSTALL \ + NEWS README ar-lib compile config.guess config.sub depcomp \ + install-sh ltmain.sh missing test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip +GZIP_ENV = --best +DIST_TARGETS = dist-bzip2 dist-gzip dist-zip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBPCRE2_16_LDFLAGS = @EXTRA_LIBPCRE2_16_LDFLAGS@ +EXTRA_LIBPCRE2_32_LDFLAGS = @EXTRA_LIBPCRE2_32_LDFLAGS@ +EXTRA_LIBPCRE2_8_LDFLAGS = @EXTRA_LIBPCRE2_8_LDFLAGS@ +EXTRA_LIBPCRE2_POSIX_LDFLAGS = @EXTRA_LIBPCRE2_POSIX_LDFLAGS@ +FGREP = @FGREP@ +GCOV_CFLAGS = @GCOV_CFLAGS@ +GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ +GCOV_LIBS = @GCOV_LIBS@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBZ2 = @LIBBZ2@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBZ = @LIBZ@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE2_DATE = @PCRE2_DATE@ +PCRE2_MAJOR = @PCRE2_MAJOR@ +PCRE2_MINOR = @PCRE2_MINOR@ +PCRE2_PRERELEASE = @PCRE2_PRERELEASE@ +PCRE2_STATIC_CFLAG = @PCRE2_STATIC_CFLAG@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHTOOL = @SHTOOL@ +STRIP = @STRIP@ +VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ +VALGRIND_LIBS = @VALGRIND_LIBS@ +VERSION = @VERSION@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_pcre2_16 = @enable_pcre2_16@ +enable_pcre2_32 = @enable_pcre2_32@ +enable_pcre2_8 = @enable_pcre2_8@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = subdir-objects +ACLOCAL_AMFLAGS = -I m4 +AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src +dist_doc_DATA = \ + AUTHORS \ + COPYING \ + ChangeLog \ + LICENCE \ + NEWS \ + README \ + doc/pcre2.txt \ + doc/pcre2-config.txt \ + doc/pcre2grep.txt \ + doc/pcre2test.txt + +dist_html_DATA = \ + doc/html/NON-AUTOTOOLS-BUILD.txt \ + doc/html/README.txt \ + doc/html/index.html \ + doc/html/pcre2-config.html \ + doc/html/pcre2.html \ + doc/html/pcre2_callout_enumerate.html \ + doc/html/pcre2_code_free.html \ + doc/html/pcre2_compile.html \ + doc/html/pcre2_compile_context_copy.html \ + doc/html/pcre2_compile_context_create.html \ + doc/html/pcre2_compile_context_free.html \ + doc/html/pcre2_config.html \ + doc/html/pcre2_dfa_match.html \ + doc/html/pcre2_general_context_copy.html \ + doc/html/pcre2_general_context_create.html \ + doc/html/pcre2_general_context_free.html \ + doc/html/pcre2_get_error_message.html \ + doc/html/pcre2_get_mark.html \ + doc/html/pcre2_get_ovector_count.html \ + doc/html/pcre2_get_ovector_pointer.html \ + doc/html/pcre2_get_startchar.html \ + doc/html/pcre2_jit_compile.html \ + doc/html/pcre2_jit_free_unused_memory.html \ + doc/html/pcre2_jit_match.html \ + doc/html/pcre2_jit_stack_assign.html \ + doc/html/pcre2_jit_stack_create.html \ + doc/html/pcre2_jit_stack_free.html \ + doc/html/pcre2_maketables.html \ + doc/html/pcre2_match.html \ + doc/html/pcre2_match_context_copy.html \ + doc/html/pcre2_match_context_create.html \ + doc/html/pcre2_match_context_free.html \ + doc/html/pcre2_match_data_create.html \ + doc/html/pcre2_match_data_create_from_pattern.html \ + doc/html/pcre2_match_data_free.html \ + doc/html/pcre2_pattern_info.html \ + doc/html/pcre2_serialize_decode.html \ + doc/html/pcre2_serialize_encode.html \ + doc/html/pcre2_serialize_free.html \ + doc/html/pcre2_serialize_get_number_of_codes.html \ + doc/html/pcre2_set_bsr.html \ + doc/html/pcre2_set_callout.html \ + doc/html/pcre2_set_character_tables.html \ + doc/html/pcre2_set_compile_recursion_guard.html \ + doc/html/pcre2_set_match_limit.html \ + doc/html/pcre2_set_offset_limit.html \ + doc/html/pcre2_set_newline.html \ + doc/html/pcre2_set_parens_nest_limit.html \ + doc/html/pcre2_set_recursion_limit.html \ + doc/html/pcre2_set_recursion_memory_management.html \ + doc/html/pcre2_substitute.html \ + doc/html/pcre2_substring_copy_byname.html \ + doc/html/pcre2_substring_copy_bynumber.html \ + doc/html/pcre2_substring_free.html \ + doc/html/pcre2_substring_get_byname.html \ + doc/html/pcre2_substring_get_bynumber.html \ + doc/html/pcre2_substring_length_byname.html \ + doc/html/pcre2_substring_length_bynumber.html \ + doc/html/pcre2_substring_list_free.html \ + doc/html/pcre2_substring_list_get.html \ + doc/html/pcre2_substring_nametable_scan.html \ + doc/html/pcre2_substring_number_from_name.html \ + doc/html/pcre2api.html \ + doc/html/pcre2build.html \ + doc/html/pcre2callout.html \ + doc/html/pcre2compat.html \ + doc/html/pcre2demo.html \ + doc/html/pcre2grep.html \ + doc/html/pcre2jit.html \ + doc/html/pcre2limits.html \ + doc/html/pcre2matching.html \ + doc/html/pcre2partial.html \ + doc/html/pcre2pattern.html \ + doc/html/pcre2perform.html \ + doc/html/pcre2posix.html \ + doc/html/pcre2sample.html \ + doc/html/pcre2serialize.html \ + doc/html/pcre2stack.html \ + doc/html/pcre2syntax.html \ + doc/html/pcre2test.html \ + doc/html/pcre2unicode.html + +dist_man_MANS = \ + doc/pcre2-config.1 \ + doc/pcre2.3 \ + doc/pcre2_callout_enumerate.3 \ + doc/pcre2_code_free.3 \ + doc/pcre2_compile.3 \ + doc/pcre2_compile_context_copy.3 \ + doc/pcre2_compile_context_create.3 \ + doc/pcre2_compile_context_free.3 \ + doc/pcre2_config.3 \ + doc/pcre2_dfa_match.3 \ + doc/pcre2_general_context_copy.3 \ + doc/pcre2_general_context_create.3 \ + doc/pcre2_general_context_free.3 \ + doc/pcre2_get_error_message.3 \ + doc/pcre2_get_mark.3 \ + doc/pcre2_get_ovector_count.3 \ + doc/pcre2_get_ovector_pointer.3 \ + doc/pcre2_get_startchar.3 \ + doc/pcre2_jit_compile.3 \ + doc/pcre2_jit_free_unused_memory.3 \ + doc/pcre2_jit_match.3 \ + doc/pcre2_jit_stack_assign.3 \ + doc/pcre2_jit_stack_create.3 \ + doc/pcre2_jit_stack_free.3 \ + doc/pcre2_maketables.3 \ + doc/pcre2_match.3 \ + doc/pcre2_match_context_copy.3 \ + doc/pcre2_match_context_create.3 \ + doc/pcre2_match_context_free.3 \ + doc/pcre2_match_data_create.3 \ + doc/pcre2_match_data_create_from_pattern.3 \ + doc/pcre2_match_data_free.3 \ + doc/pcre2_pattern_info.3 \ + doc/pcre2_serialize_decode.3 \ + doc/pcre2_serialize_encode.3 \ + doc/pcre2_serialize_free.3 \ + doc/pcre2_serialize_get_number_of_codes.3 \ + doc/pcre2_set_bsr.3 \ + doc/pcre2_set_callout.3 \ + doc/pcre2_set_character_tables.3 \ + doc/pcre2_set_compile_recursion_guard.3 \ + doc/pcre2_set_match_limit.3 \ + doc/pcre2_set_offset_limit.3 \ + doc/pcre2_set_newline.3 \ + doc/pcre2_set_parens_nest_limit.3 \ + doc/pcre2_set_recursion_limit.3 \ + doc/pcre2_set_recursion_memory_management.3 \ + doc/pcre2_substitute.3 \ + doc/pcre2_substring_copy_byname.3 \ + doc/pcre2_substring_copy_bynumber.3 \ + doc/pcre2_substring_free.3 \ + doc/pcre2_substring_get_byname.3 \ + doc/pcre2_substring_get_bynumber.3 \ + doc/pcre2_substring_length_byname.3 \ + doc/pcre2_substring_length_bynumber.3 \ + doc/pcre2_substring_list_free.3 \ + doc/pcre2_substring_list_get.3 \ + doc/pcre2_substring_nametable_scan.3 \ + doc/pcre2_substring_number_from_name.3 \ + doc/pcre2api.3 \ + doc/pcre2build.3 \ + doc/pcre2callout.3 \ + doc/pcre2compat.3 \ + doc/pcre2demo.3 \ + doc/pcre2grep.1 \ + doc/pcre2jit.3 \ + doc/pcre2limits.3 \ + doc/pcre2matching.3 \ + doc/pcre2partial.3 \ + doc/pcre2pattern.3 \ + doc/pcre2perform.3 \ + doc/pcre2posix.3 \ + doc/pcre2sample.3 \ + doc/pcre2serialize.3 \ + doc/pcre2stack.3 \ + doc/pcre2syntax.3 \ + doc/pcre2test.1 \ + doc/pcre2unicode.3 + + +# The Libtool libraries to install. We'll add to this later. +lib_LTLIBRARIES = $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_11) +check_SCRIPTS = +dist_noinst_SCRIPTS = RunTest $(am__append_30) + +# Additional files to delete on 'make clean', 'make distclean', +# and 'make maintainer-clean'. + +# RunTest and RunGrepTest should clean up after themselves, but just in case +# they don't, add their working files to CLEANFILES. +CLEANFILES = src/pcre2_chartables.c testSinput test3input test3output \ + test3outputA test3outputB testtry teststdout teststderr \ + teststderrgrep testtemp1grep testtemp2grep testtrygrep \ + testNinputgrep +DISTCLEANFILES = src/config.h.in~ config.h $(am__append_34) +MAINTAINERCLEANFILES = src/pcre2.h.generic src/config.h.generic + +# Additional files to bundle with the distribution, over and above what +# the Autotools include by default. + +# These files contain additional m4 macros that are used by autoconf. + +# These files contain maintenance information + +# These files are used in the preparation of a release + +# These files are usable versions of pcre2.h and config.h that are distributed +# for the benefit of people who are building PCRE2 manually, without the +# Autotools support. + +# The pcre2_chartables.c.dist file is the default version of +# pcre2_chartables.c, used unless --enable-rebuild-chartables is specified. + +# The JIT compiler lives in a separate directory, but its files are #included +# when pcre2_jit_compile.c is processed, so they must be distributed. + +# Some of the JIT sources are also in separate files that are #included. + +# PCRE2 demonstration program. Not built automatcally. The point is that the +# users should build it themselves. So just distribute the source. +EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \ + NON-AUTOTOOLS-BUILD HACKING PrepareRelease CheckMan CleanTxt \ + Detrail 132html doc/index.html.src src/pcre2.h.generic \ + src/config.h.generic src/pcre2_chartables.c.dist \ + src/sljit/sljitConfig.h src/sljit/sljitConfigInternal.h \ + src/sljit/sljitExecAllocator.c src/sljit/sljitLir.c \ + src/sljit/sljitLir.h src/sljit/sljitNativeARM_32.c \ + src/sljit/sljitNativeARM_64.c src/sljit/sljitNativeARM_T2_32.c \ + src/sljit/sljitNativeMIPS_32.c src/sljit/sljitNativeMIPS_64.c \ + src/sljit/sljitNativeMIPS_common.c \ + src/sljit/sljitNativePPC_32.c src/sljit/sljitNativePPC_64.c \ + src/sljit/sljitNativePPC_common.c \ + src/sljit/sljitNativeSPARC_32.c \ + src/sljit/sljitNativeSPARC_common.c \ + src/sljit/sljitNativeTILEGX-encoder.c \ + src/sljit/sljitNativeTILEGX_64.c src/sljit/sljitNativeX86_32.c \ + src/sljit/sljitNativeX86_64.c \ + src/sljit/sljitNativeX86_common.c src/sljit/sljitUtils.c \ + src/pcre2_jit_match.c src/pcre2_jit_misc.c \ + src/pcre2_printint.c RunTest.bat testdata/grepbinary \ + testdata/grepfilelist testdata/grepinput testdata/grepinput3 \ + testdata/grepinput8 testdata/grepinputv testdata/grepinputx \ + testdata/greplist testdata/grepoutput testdata/grepoutput8 \ + testdata/grepoutputN testdata/greppatN4 testdata/testinput1 \ + testdata/testinput2 testdata/testinput3 testdata/testinput4 \ + testdata/testinput5 testdata/testinput6 testdata/testinput7 \ + testdata/testinput8 testdata/testinput9 testdata/testinput10 \ + testdata/testinput11 testdata/testinput12 testdata/testinput13 \ + testdata/testinput14 testdata/testinput15 testdata/testinput16 \ + testdata/testinput17 testdata/testinput18 testdata/testinput19 \ + testdata/testinput20 testdata/testinput21 testdata/testinput22 \ + testdata/testinput23 testdata/testinputEBC \ + testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \ + testdata/testoutput3A testdata/testoutput3B \ + testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ + testdata/testoutput7 testdata/testoutput8-16-2 \ + testdata/testoutput8-16-3 testdata/testoutput8-16-3 \ + testdata/testoutput8-32-2 testdata/testoutput8-32-3 \ + testdata/testoutput8-32-4 testdata/testoutput8-8-2 \ + testdata/testoutput8-8-3 testdata/testoutput8-8-4 \ + testdata/testoutput9 testdata/testoutput10 \ + testdata/testoutput11-16 testdata/testoutput11-32 \ + testdata/testoutput12-16 testdata/testoutput12-32 \ + testdata/testoutput13 testdata/testoutput14-16 \ + testdata/testoutput14-32 testdata/testoutput14-8 \ + testdata/testoutput15 testdata/testoutput16 \ + testdata/testoutput17 testdata/testoutput18 \ + testdata/testoutput19 testdata/testoutput20 \ + testdata/testoutput21 testdata/testoutput22-16 \ + testdata/testoutput22-32 testdata/testoutput22-8 \ + testdata/testoutput23 testdata/testoutputEBC \ + testdata/valgrind-jit.supp testdata/wintestinput3 \ + testdata/wintestoutput3 perltest.sh src/pcre2demo.c \ + cmake/COPYING-CMAKE-SCRIPTS \ + cmake/FindPackageHandleStandardArgs.cmake \ + cmake/FindReadline.cmake cmake/FindEditline.cmake \ + CMakeLists.txt config-cmake.h.in + +# These are the header files we'll install. We do not distribute pcre2.h +# because it is generated from pcre2.h.in. +nodist_include_HEADERS = src/pcre2.h +include_HEADERS = src/pcre2posix.h + +# This is the "config" script. +bin_SCRIPTS = pcre2-config +@WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = src/dftables.c +BUILT_SOURCES = src/pcre2_chartables.c +NODIST_SOURCES = src/pcre2_chartables.c +COMMON_SOURCES = \ + src/pcre2_auto_possess.c \ + src/pcre2_compile.c \ + src/pcre2_config.c \ + src/pcre2_context.c \ + src/pcre2_dfa_match.c \ + src/pcre2_error.c \ + src/pcre2_find_bracket.c \ + src/pcre2_internal.h \ + src/pcre2_intmodedep.h \ + src/pcre2_jit_compile.c \ + src/pcre2_maketables.c \ + src/pcre2_match.c \ + src/pcre2_match_data.c \ + src/pcre2_newline.c \ + src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c \ + src/pcre2_serialize.c \ + src/pcre2_string_utils.c \ + src/pcre2_study.c \ + src/pcre2_substitute.c \ + src/pcre2_substring.c \ + src/pcre2_tables.c \ + src/pcre2_ucd.c \ + src/pcre2_ucp.h \ + src/pcre2_valid_utf.c \ + src/pcre2_xclass.c + +@WITH_PCRE2_8_TRUE@libpcre2_8_la_SOURCES = \ +@WITH_PCRE2_8_TRUE@ $(COMMON_SOURCES) + +@WITH_PCRE2_8_TRUE@nodist_libpcre2_8_la_SOURCES = \ +@WITH_PCRE2_8_TRUE@ $(NODIST_SOURCES) + +@WITH_PCRE2_8_TRUE@libpcre2_8_la_CFLAGS = -DPCRE2_CODE_UNIT_WIDTH=8 \ +@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ +@WITH_PCRE2_8_TRUE@ $(am__append_5) $(am__append_8) +@WITH_PCRE2_8_TRUE@libpcre2_8_la_LIBADD = +@WITH_PCRE2_16_TRUE@libpcre2_16_la_SOURCES = \ +@WITH_PCRE2_16_TRUE@ $(COMMON_SOURCES) + +@WITH_PCRE2_16_TRUE@nodist_libpcre2_16_la_SOURCES = \ +@WITH_PCRE2_16_TRUE@ $(NODIST_SOURCES) + +@WITH_PCRE2_16_TRUE@libpcre2_16_la_CFLAGS = \ +@WITH_PCRE2_16_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=16 \ +@WITH_PCRE2_16_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ +@WITH_PCRE2_16_TRUE@ $(am__append_6) $(am__append_9) +@WITH_PCRE2_16_TRUE@libpcre2_16_la_LIBADD = +@WITH_PCRE2_32_TRUE@libpcre2_32_la_SOURCES = \ +@WITH_PCRE2_32_TRUE@ $(COMMON_SOURCES) + +@WITH_PCRE2_32_TRUE@nodist_libpcre2_32_la_SOURCES = \ +@WITH_PCRE2_32_TRUE@ $(NODIST_SOURCES) + +@WITH_PCRE2_32_TRUE@libpcre2_32_la_CFLAGS = \ +@WITH_PCRE2_32_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=32 \ +@WITH_PCRE2_32_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ +@WITH_PCRE2_32_TRUE@ $(am__append_7) $(am__append_10) +@WITH_PCRE2_32_TRUE@libpcre2_32_la_LIBADD = +@WITH_PCRE2_8_TRUE@libpcre2_8_la_LDFLAGS = $(EXTRA_LIBPCRE2_8_LDFLAGS) +@WITH_PCRE2_16_TRUE@libpcre2_16_la_LDFLAGS = $(EXTRA_LIBPCRE2_16_LDFLAGS) +@WITH_PCRE2_32_TRUE@libpcre2_32_la_LDFLAGS = $(EXTRA_LIBPCRE2_32_LDFLAGS) +@WITH_PCRE2_8_TRUE@libpcre2_posix_la_SOURCES = src/pcre2posix.c +@WITH_PCRE2_8_TRUE@libpcre2_posix_la_CFLAGS = \ +@WITH_PCRE2_8_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=8 \ +@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ +@WITH_PCRE2_8_TRUE@ $(am__append_12) +@WITH_PCRE2_8_TRUE@libpcre2_posix_la_LDFLAGS = $(EXTRA_LIBPCRE2_POSIX_LDFLAGS) +@WITH_PCRE2_8_TRUE@libpcre2_posix_la_LIBADD = libpcre2-8.la +@WITH_PCRE2_8_TRUE@pcre2grep_SOURCES = src/pcre2grep.c +@WITH_PCRE2_8_TRUE@pcre2grep_CFLAGS = $(AM_CFLAGS) $(am__append_14) +@WITH_PCRE2_8_TRUE@pcre2grep_LDADD = $(LIBZ) $(LIBBZ2) libpcre2-8.la \ +@WITH_PCRE2_8_TRUE@ $(am__append_15) +@WITH_JIT_TRUE@pcre2_jit_test_SOURCES = src/pcre2_jit_test.c +@WITH_JIT_TRUE@pcre2_jit_test_CFLAGS = $(AM_CFLAGS) $(am__append_21) +@WITH_JIT_TRUE@pcre2_jit_test_LDADD = $(am__append_18) \ +@WITH_JIT_TRUE@ $(am__append_19) $(am__append_20) \ +@WITH_JIT_TRUE@ $(am__append_22) +pcre2test_SOURCES = src/pcre2test.c +pcre2test_CFLAGS = $(AM_CFLAGS) $(am__append_26) $(am__append_27) +pcre2test_LDADD = $(LIBREADLINE) $(am__append_23) $(am__append_24) \ + $(am__append_25) $(am__append_28) + +# We have .pc files for pkg-config users. +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = $(am__append_31) $(am__append_32) $(am__append_33) + +# gcov/lcov code coverage reporting +# +# Coverage reporting targets: +# +# coverage: Create a coverage report from 'make check' +# coverage-baseline: Capture baseline coverage information +# coverage-reset: This zeros the coverage counters only +# coverage-report: This creates the coverage report only +# coverage-clean-report: This removes the generated coverage report +# without cleaning the coverage data itself +# coverage-clean-data: This removes the captured coverage data without +# removing the coverage files created at compile time (*.gcno) +# coverage-clean: This cleans all coverage data including the generated +# coverage report. +@WITH_GCOV_TRUE@COVERAGE_TEST_NAME = $(PACKAGE) +@WITH_GCOV_TRUE@COVERAGE_NAME = $(PACKAGE)-$(VERSION) +@WITH_GCOV_TRUE@COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info +@WITH_GCOV_TRUE@COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage +@WITH_GCOV_TRUE@COVERAGE_LCOV_EXTRA_FLAGS = +@WITH_GCOV_TRUE@COVERAGE_GENHTML_EXTRA_FLAGS = +@WITH_GCOV_TRUE@coverage_quiet = $(coverage_quiet_$(V)) +@WITH_GCOV_TRUE@coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +@WITH_GCOV_TRUE@coverage_quiet_0 = --quiet +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +src/config.h: src/stamp-h1 + @test -f $@ || rm -f src/stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1 + +src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status + @rm -f src/stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/config.h +$(top_srcdir)/src/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f src/stamp-h1 + touch $@ + +distclean-hdr: + -rm -f src/config.h src/stamp-h1 +libpcre2-8.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-8.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libpcre2-16.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-16.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libpcre2-32.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-32.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libpcre2-posix.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-posix.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +pcre2-config: $(top_builddir)/config.status $(srcdir)/pcre2-config.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/pcre2.h: $(top_builddir)/config.status $(top_srcdir)/src/pcre2.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_config.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_context.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_error.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_maketables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_match_data.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_newline.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_serialize.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_study.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_substitute.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_substring.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_tables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_ucd.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_xclass.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_16_la-pcre2_chartables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +libpcre2-16.la: $(libpcre2_16_la_OBJECTS) $(libpcre2_16_la_DEPENDENCIES) $(EXTRA_libpcre2_16_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre2_16_la_LINK) $(am_libpcre2_16_la_rpath) $(libpcre2_16_la_OBJECTS) $(libpcre2_16_la_LIBADD) $(LIBS) +src/libpcre2_32_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_config.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_context.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_error.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_maketables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_match_data.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_newline.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_serialize.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_study.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_substitute.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_substring.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_tables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_ucd.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_xclass.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_32_la-pcre2_chartables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +libpcre2-32.la: $(libpcre2_32_la_OBJECTS) $(libpcre2_32_la_DEPENDENCIES) $(EXTRA_libpcre2_32_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre2_32_la_LINK) $(am_libpcre2_32_la_rpath) $(libpcre2_32_la_OBJECTS) $(libpcre2_32_la_LIBADD) $(LIBS) +src/libpcre2_8_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_config.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_context.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_error.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_maketables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_match.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_match_data.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_newline.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_serialize.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_study.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_substitute.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_substring.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_tables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_ucd.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_xclass.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libpcre2_8_la-pcre2_chartables.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +libpcre2-8.la: $(libpcre2_8_la_OBJECTS) $(libpcre2_8_la_DEPENDENCIES) $(EXTRA_libpcre2_8_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre2_8_la_LINK) $(am_libpcre2_8_la_rpath) $(libpcre2_8_la_OBJECTS) $(libpcre2_8_la_LIBADD) $(LIBS) +src/libpcre2_posix_la-pcre2posix.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +libpcre2-posix.la: $(libpcre2_posix_la_OBJECTS) $(libpcre2_posix_la_DEPENDENCIES) $(EXTRA_libpcre2_posix_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre2_posix_la_LINK) $(am_libpcre2_posix_la_rpath) $(libpcre2_posix_la_OBJECTS) $(libpcre2_posix_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +src/dftables.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES) + @rm -f dftables$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) +src/pcre2_jit_test-pcre2_jit_test.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +pcre2_jit_test$(EXEEXT): $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_DEPENDENCIES) $(EXTRA_pcre2_jit_test_DEPENDENCIES) + @rm -f pcre2_jit_test$(EXEEXT) + $(AM_V_CCLD)$(pcre2_jit_test_LINK) $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_LDADD) $(LIBS) +src/pcre2grep-pcre2grep.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +pcre2grep$(EXEEXT): $(pcre2grep_OBJECTS) $(pcre2grep_DEPENDENCIES) $(EXTRA_pcre2grep_DEPENDENCIES) + @rm -f pcre2grep$(EXEEXT) + $(AM_V_CCLD)$(pcre2grep_LINK) $(pcre2grep_OBJECTS) $(pcre2grep_LDADD) $(LIBS) +src/pcre2test-pcre2test.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +pcre2test$(EXEEXT): $(pcre2test_OBJECTS) $(pcre2test_DEPENDENCIES) $(EXTRA_pcre2test_DEPENDENCIES) + @rm -f pcre2test$(EXEEXT) + $(AM_V_CCLD)$(pcre2test_LINK) $(pcre2test_OBJECTS) $(pcre2test_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f src/*.$(OBJEXT) + -rm -f src/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dftables.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2grep-pcre2grep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2test-pcre2test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +src/libpcre2_16_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_16_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_16_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c + +src/libpcre2_16_la-pcre2_compile.lo: src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Tpo -c -o src/libpcre2_16_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_16_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c + +src/libpcre2_16_la-pcre2_config.lo: src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Tpo -c -o src/libpcre2_16_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_16_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c + +src/libpcre2_16_la-pcre2_context.lo: src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Tpo -c -o src/libpcre2_16_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_16_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c + +src/libpcre2_16_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_16_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_16_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c + +src/libpcre2_16_la-pcre2_error.lo: src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Tpo -c -o src/libpcre2_16_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_16_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c + +src/libpcre2_16_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_16_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_16_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c + +src/libpcre2_16_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_16_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_16_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c + +src/libpcre2_16_la-pcre2_maketables.lo: src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Tpo -c -o src/libpcre2_16_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_16_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c + +src/libpcre2_16_la-pcre2_match.lo: src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Tpo -c -o src/libpcre2_16_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_16_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c + +src/libpcre2_16_la-pcre2_match_data.lo: src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Tpo -c -o src/libpcre2_16_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_16_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c + +src/libpcre2_16_la-pcre2_newline.lo: src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Tpo -c -o src/libpcre2_16_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_16_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c + +src/libpcre2_16_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_16_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_16_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c + +src/libpcre2_16_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_16_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_16_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c + +src/libpcre2_16_la-pcre2_serialize.lo: src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Tpo -c -o src/libpcre2_16_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_16_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c + +src/libpcre2_16_la-pcre2_string_utils.lo: src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Tpo -c -o src/libpcre2_16_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_16_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c + +src/libpcre2_16_la-pcre2_study.lo: src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Tpo -c -o src/libpcre2_16_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_16_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c + +src/libpcre2_16_la-pcre2_substitute.lo: src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Tpo -c -o src/libpcre2_16_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_16_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c + +src/libpcre2_16_la-pcre2_substring.lo: src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Tpo -c -o src/libpcre2_16_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_16_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c + +src/libpcre2_16_la-pcre2_tables.lo: src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Tpo -c -o src/libpcre2_16_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_16_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c + +src/libpcre2_16_la-pcre2_ucd.lo: src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Tpo -c -o src/libpcre2_16_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_16_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c + +src/libpcre2_16_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_16_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_16_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c + +src/libpcre2_16_la-pcre2_xclass.lo: src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Tpo -c -o src/libpcre2_16_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_16_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c + +src/libpcre2_16_la-pcre2_chartables.lo: src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Tpo -c -o src/libpcre2_16_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_16_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c + +src/libpcre2_32_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_32_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_32_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c + +src/libpcre2_32_la-pcre2_compile.lo: src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Tpo -c -o src/libpcre2_32_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_32_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c + +src/libpcre2_32_la-pcre2_config.lo: src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Tpo -c -o src/libpcre2_32_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_32_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c + +src/libpcre2_32_la-pcre2_context.lo: src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Tpo -c -o src/libpcre2_32_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_32_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c + +src/libpcre2_32_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_32_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_32_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c + +src/libpcre2_32_la-pcre2_error.lo: src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Tpo -c -o src/libpcre2_32_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_32_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c + +src/libpcre2_32_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_32_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_32_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c + +src/libpcre2_32_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_32_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_32_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c + +src/libpcre2_32_la-pcre2_maketables.lo: src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Tpo -c -o src/libpcre2_32_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_32_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c + +src/libpcre2_32_la-pcre2_match.lo: src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Tpo -c -o src/libpcre2_32_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_32_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c + +src/libpcre2_32_la-pcre2_match_data.lo: src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Tpo -c -o src/libpcre2_32_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_32_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c + +src/libpcre2_32_la-pcre2_newline.lo: src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Tpo -c -o src/libpcre2_32_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_32_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c + +src/libpcre2_32_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_32_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_32_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c + +src/libpcre2_32_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_32_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_32_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c + +src/libpcre2_32_la-pcre2_serialize.lo: src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Tpo -c -o src/libpcre2_32_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_32_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c + +src/libpcre2_32_la-pcre2_string_utils.lo: src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Tpo -c -o src/libpcre2_32_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_32_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c + +src/libpcre2_32_la-pcre2_study.lo: src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Tpo -c -o src/libpcre2_32_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_32_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c + +src/libpcre2_32_la-pcre2_substitute.lo: src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Tpo -c -o src/libpcre2_32_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_32_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c + +src/libpcre2_32_la-pcre2_substring.lo: src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Tpo -c -o src/libpcre2_32_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_32_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c + +src/libpcre2_32_la-pcre2_tables.lo: src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Tpo -c -o src/libpcre2_32_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_32_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c + +src/libpcre2_32_la-pcre2_ucd.lo: src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Tpo -c -o src/libpcre2_32_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_32_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c + +src/libpcre2_32_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_32_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_32_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c + +src/libpcre2_32_la-pcre2_xclass.lo: src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Tpo -c -o src/libpcre2_32_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_32_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c + +src/libpcre2_32_la-pcre2_chartables.lo: src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Tpo -c -o src/libpcre2_32_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_32_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c + +src/libpcre2_8_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_8_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_8_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c + +src/libpcre2_8_la-pcre2_compile.lo: src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Tpo -c -o src/libpcre2_8_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_8_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c + +src/libpcre2_8_la-pcre2_config.lo: src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Tpo -c -o src/libpcre2_8_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_8_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c + +src/libpcre2_8_la-pcre2_context.lo: src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Tpo -c -o src/libpcre2_8_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_8_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c + +src/libpcre2_8_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_8_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_8_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c + +src/libpcre2_8_la-pcre2_error.lo: src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Tpo -c -o src/libpcre2_8_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_8_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c + +src/libpcre2_8_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_8_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_8_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c + +src/libpcre2_8_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_8_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_8_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c + +src/libpcre2_8_la-pcre2_maketables.lo: src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Tpo -c -o src/libpcre2_8_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_8_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c + +src/libpcre2_8_la-pcre2_match.lo: src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Tpo -c -o src/libpcre2_8_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_8_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c + +src/libpcre2_8_la-pcre2_match_data.lo: src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Tpo -c -o src/libpcre2_8_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_8_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c + +src/libpcre2_8_la-pcre2_newline.lo: src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Tpo -c -o src/libpcre2_8_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_8_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c + +src/libpcre2_8_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_8_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_8_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c + +src/libpcre2_8_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_8_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_8_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c + +src/libpcre2_8_la-pcre2_serialize.lo: src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Tpo -c -o src/libpcre2_8_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_8_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c + +src/libpcre2_8_la-pcre2_string_utils.lo: src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Tpo -c -o src/libpcre2_8_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_8_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c + +src/libpcre2_8_la-pcre2_study.lo: src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Tpo -c -o src/libpcre2_8_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_8_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c + +src/libpcre2_8_la-pcre2_substitute.lo: src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Tpo -c -o src/libpcre2_8_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_8_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c + +src/libpcre2_8_la-pcre2_substring.lo: src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Tpo -c -o src/libpcre2_8_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_8_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c + +src/libpcre2_8_la-pcre2_tables.lo: src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Tpo -c -o src/libpcre2_8_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_8_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c + +src/libpcre2_8_la-pcre2_ucd.lo: src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Tpo -c -o src/libpcre2_8_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_8_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c + +src/libpcre2_8_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_8_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_8_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c + +src/libpcre2_8_la-pcre2_xclass.lo: src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Tpo -c -o src/libpcre2_8_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_8_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c + +src/libpcre2_8_la-pcre2_chartables.lo: src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Tpo -c -o src/libpcre2_8_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_8_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c + +src/libpcre2_posix_la-pcre2posix.lo: src/pcre2posix.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_posix_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_posix_la-pcre2posix.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Tpo -c -o src/libpcre2_posix_la-pcre2posix.lo `test -f 'src/pcre2posix.c' || echo '$(srcdir)/'`src/pcre2posix.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Tpo src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2posix.c' object='src/libpcre2_posix_la-pcre2posix.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_posix_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_posix_la-pcre2posix.lo `test -f 'src/pcre2posix.c' || echo '$(srcdir)/'`src/pcre2posix.c + +src/pcre2_jit_test-pcre2_jit_test.o: src/pcre2_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -MT src/pcre2_jit_test-pcre2_jit_test.o -MD -MP -MF src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo -c -o src/pcre2_jit_test-pcre2_jit_test.o `test -f 'src/pcre2_jit_test.c' || echo '$(srcdir)/'`src/pcre2_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_test.c' object='src/pcre2_jit_test-pcre2_jit_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -c -o src/pcre2_jit_test-pcre2_jit_test.o `test -f 'src/pcre2_jit_test.c' || echo '$(srcdir)/'`src/pcre2_jit_test.c + +src/pcre2_jit_test-pcre2_jit_test.obj: src/pcre2_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -MT src/pcre2_jit_test-pcre2_jit_test.obj -MD -MP -MF src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo -c -o src/pcre2_jit_test-pcre2_jit_test.obj `if test -f 'src/pcre2_jit_test.c'; then $(CYGPATH_W) 'src/pcre2_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_jit_test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_test.c' object='src/pcre2_jit_test-pcre2_jit_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -c -o src/pcre2_jit_test-pcre2_jit_test.obj `if test -f 'src/pcre2_jit_test.c'; then $(CYGPATH_W) 'src/pcre2_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_jit_test.c'; fi` + +src/pcre2grep-pcre2grep.o: src/pcre2grep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -MT src/pcre2grep-pcre2grep.o -MD -MP -MF src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo -c -o src/pcre2grep-pcre2grep.o `test -f 'src/pcre2grep.c' || echo '$(srcdir)/'`src/pcre2grep.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo src/$(DEPDIR)/pcre2grep-pcre2grep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2grep.c' object='src/pcre2grep-pcre2grep.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -c -o src/pcre2grep-pcre2grep.o `test -f 'src/pcre2grep.c' || echo '$(srcdir)/'`src/pcre2grep.c + +src/pcre2grep-pcre2grep.obj: src/pcre2grep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -MT src/pcre2grep-pcre2grep.obj -MD -MP -MF src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo -c -o src/pcre2grep-pcre2grep.obj `if test -f 'src/pcre2grep.c'; then $(CYGPATH_W) 'src/pcre2grep.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2grep.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo src/$(DEPDIR)/pcre2grep-pcre2grep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2grep.c' object='src/pcre2grep-pcre2grep.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -c -o src/pcre2grep-pcre2grep.obj `if test -f 'src/pcre2grep.c'; then $(CYGPATH_W) 'src/pcre2grep.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2grep.c'; fi` + +src/pcre2test-pcre2test.o: src/pcre2test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -MT src/pcre2test-pcre2test.o -MD -MP -MF src/$(DEPDIR)/pcre2test-pcre2test.Tpo -c -o src/pcre2test-pcre2test.o `test -f 'src/pcre2test.c' || echo '$(srcdir)/'`src/pcre2test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2test-pcre2test.Tpo src/$(DEPDIR)/pcre2test-pcre2test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2test.c' object='src/pcre2test-pcre2test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -c -o src/pcre2test-pcre2test.o `test -f 'src/pcre2test.c' || echo '$(srcdir)/'`src/pcre2test.c + +src/pcre2test-pcre2test.obj: src/pcre2test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -MT src/pcre2test-pcre2test.obj -MD -MP -MF src/$(DEPDIR)/pcre2test-pcre2test.Tpo -c -o src/pcre2test-pcre2test.obj `if test -f 'src/pcre2test.c'; then $(CYGPATH_W) 'src/pcre2test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2test-pcre2test.Tpo src/$(DEPDIR)/pcre2test-pcre2test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2test.c' object='src/pcre2test-pcre2test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -c -o src/pcre2test-pcre2test.obj `if test -f 'src/pcre2test.c'; then $(CYGPATH_W) 'src/pcre2test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf src/.libs src/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +install-dist_htmlDATA: $(dist_html_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done + +uninstall-dist_htmlDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-nodist_includeHEADERS: $(nodist_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-nodist_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_SCRIPTS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +pcre2_jit_test.log: pcre2_jit_test$(EXEEXT) + @p='pcre2_jit_test$(EXEEXT)'; \ + b='pcre2_jit_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +RunTest.log: RunTest + @p='RunTest'; \ + b='RunTest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +RunGrepTest.log: RunGrepTest + @p='RunGrepTest'; \ + b='RunGrepTest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ + $(HEADERS) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +@WITH_GCOV_FALSE@clean-local: +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf src/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_docDATA install-dist_htmlDATA \ + install-includeHEADERS install-man \ + install-nodist_includeHEADERS install-pkgconfigDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-binSCRIPTS \ + install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man3 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf src/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_docDATA uninstall-dist_htmlDATA \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-nodist_includeHEADERS \ + uninstall-pkgconfigDATA + +uninstall-man: uninstall-man1 uninstall-man3 + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ + check-am clean clean-binPROGRAMS clean-cscope clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-local distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-binSCRIPTS \ + install-data install-data-am install-dist_docDATA \ + install-dist_htmlDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-libLTLIBRARIES install-man install-man1 install-man3 \ + install-nodist_includeHEADERS install-pdf install-pdf-am \ + install-pkgconfigDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_docDATA uninstall-dist_htmlDATA \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-man1 uninstall-man3 \ + uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# The only difference between pcre2.h.in and pcre2.h is the setting of the PCRE +# version number. Therefore, we can create the generic version just by copying. + +src/pcre2.h.generic: src/pcre2.h.in configure.ac + rm -f $@ + cp -p src/pcre2.h $@ + +# It is more complicated for config.h.generic. We need the version that results +# from a default configuration so as to get all the default values for PCRE +# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by +# doing a configure in a temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you just try +# running configure in a new directory, it complains. For this reason, we move +# config.status out of the way while doing the default configuration. The +# resulting config.h is munged by perl to put #ifdefs round any #defines for +# macros with values, and to #undef all boolean macros such as HAVE_xxx and +# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make +# sure that PCRE2_EXP_DEFN is unset (in case it has visibility settings). + +src/config.h.generic: configure.ac + rm -rf $@ _generic + mkdir _generic + cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside + cd _generic && $(abs_top_srcdir)/configure || : + cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs + test -f _generic/src/config.h + perl -n \ + -e 'BEGIN{$$blank=0;}' \ + -e 'if(/PCRE2_EXP_DEFN/){print"/* #undef PCRE2_EXP_DEFN */\n";$$blank=0;next;}' \ + -e 'if(/to make a symbol visible/){next;}' \ + -e 'if(/__attribute__ \(\(visibility/){next;}' \ + -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ + -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ + -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ + -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ + _generic/src/config.h >$@ + rm -rf _generic +@WITH_REBUILD_CHARTABLES_TRUE@src/pcre2_chartables.c: dftables$(EXEEXT) +@WITH_REBUILD_CHARTABLES_TRUE@ rm -f $@ +@WITH_REBUILD_CHARTABLES_TRUE@ ./dftables$(EXEEXT) $@ +@WITH_REBUILD_CHARTABLES_FALSE@src/pcre2_chartables.c: $(srcdir)/src/pcre2_chartables.c.dist +@WITH_REBUILD_CHARTABLES_FALSE@ rm -f $@ +@WITH_REBUILD_CHARTABLES_FALSE@ $(LN_S) $(abs_srcdir)/src/pcre2_chartables.c.dist $(abs_builddir)/src/pcre2_chartables.c + +@WITH_GCOV_TRUE@coverage-check: all +@WITH_GCOV_TRUE@ -$(MAKE) $(AM_MAKEFLAGS) -k check + +@WITH_GCOV_TRUE@coverage-baseline: +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --capture \ +@WITH_GCOV_TRUE@ --initial + +@WITH_GCOV_TRUE@coverage-report: +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --capture \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ +@WITH_GCOV_TRUE@ --test-name "$(COVERAGE_TEST_NAME)" \ +@WITH_GCOV_TRUE@ --no-checksum \ +@WITH_GCOV_TRUE@ --compat-libtool \ +@WITH_GCOV_TRUE@ $(COVERAGE_LCOV_EXTRA_FLAGS) +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ +@WITH_GCOV_TRUE@ "/tmp/*" \ +@WITH_GCOV_TRUE@ "/usr/include/*" \ +@WITH_GCOV_TRUE@ "$(includedir)/*" +@WITH_GCOV_TRUE@ -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" +@WITH_GCOV_TRUE@ LANG=C $(GENHTML) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --prefix $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-directory "$(COVERAGE_OUTPUT_DIR)" \ +@WITH_GCOV_TRUE@ --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ +@WITH_GCOV_TRUE@ --show-details "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --legend \ +@WITH_GCOV_TRUE@ $(COVERAGE_GENHTML_EXTRA_FLAGS) +@WITH_GCOV_TRUE@ @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" + +@WITH_GCOV_TRUE@coverage-reset: +@WITH_GCOV_TRUE@ -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) + +@WITH_GCOV_TRUE@coverage-clean-report: +@WITH_GCOV_TRUE@ -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" +@WITH_GCOV_TRUE@ -rm -rf "$(COVERAGE_OUTPUT_DIR)" + +@WITH_GCOV_TRUE@coverage-clean-data: +@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcda" -delete + +@WITH_GCOV_TRUE@coverage-clean: coverage-reset coverage-clean-report coverage-clean-data +@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcno" -delete + +@WITH_GCOV_TRUE@coverage-distclean: coverage-clean + +@WITH_GCOV_TRUE@coverage: coverage-reset coverage-baseline coverage-check coverage-report +@WITH_GCOV_TRUE@clean-local: coverage-clean +@WITH_GCOV_TRUE@distclean-local: coverage-distclean + +@WITH_GCOV_TRUE@.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean + +# Without coverage support, still arrange for 'make distclean' to get rid of +# any coverage files that may have been left from a different configuration. + +@WITH_GCOV_FALSE@coverage: +@WITH_GCOV_FALSE@ @echo "Configuring with --enable-coverage is required to generate code coverage report." + +@WITH_GCOV_FALSE@distclean-local: +@WITH_GCOV_FALSE@ rm -rf $(PACKAGE)-$(VERSION)-coverage* + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/pcre2/NEWS b/pcre2/NEWS new file mode 100644 index 000000000..aaeee5c24 --- /dev/null +++ b/pcre2/NEWS @@ -0,0 +1,88 @@ +News about PCRE2 releases +------------------------- + +Version 10.21 12-January-2016 +----------------------------- + +1. Many bugs have been fixed. A large number of them were provoked only by very +strange pattern input, and were discovered by fuzzers. Some others were +discovered by code auditing. See ChangeLog for details. + +2. The Unicode tables have been updated to Unicode version 8.0.0. + +3. For Perl compatibility in EBCDIC environments, ranges such as a-z in a +class, where both values are literal letters in the same case, omit the +non-letter EBCDIC code points within the range. + +4. There have been a number of enhancements to the pcre2_substitute() function, +giving more flexibility to replacement facilities. It is now also possible to +cause the function to return the needed buffer size if the one given is too +small. + +5. The PCRE2_ALT_VERBNAMES option causes the "name" parts of special verbs such +as (*THEN:name) to be processed for backslashes and to take note of +PCRE2_EXTENDED. + +6. PCRE2_INFO_HASBACKSLASHC makes it possible for a client to find out if a +pattern uses \C, and --never-backslash-C makes it possible to compile a version +PCRE2 in which the use of \C is always forbidden. + +7. A limit to the length of pattern that can be handled can now be set by +calling pcre2_set_max_pattern_length(). + +8. When matching an unanchored pattern, a match can be required to begin within +a given number of code units after the start of the subject by calling +pcre2_set_offset_limit(). + +9. The pcre2test program has been extended to test new facilities, and it can +now run the tests when LF on its own is not a valid newline sequence. + +10. The RunTest script has also been updated to enable more tests to be run. + +11. There have been some minor performance enhancements. + + +Version 10.20 30-June-2015 +-------------------------- + +1. Callouts with string arguments and the pcre2_callout_enumerate() function +have been implemented. + +2. The PCRE2_NEVER_BACKSLASH_C option, which locks out the use of \C, is added. + +3. The PCRE2_ALT_CIRCUMFLEX option lets ^ match after a newline at the end of a +subject in multiline mode. + +4. The way named subpatterns are handled has been refactored. The previous +approach had several bugs. + +5. The handling of \c in EBCDIC environments has been changed to conform to the +perlebcdic document. This is an incompatible change. + +6. Bugs have been mended, many of them discovered by fuzzers. + + +Version 10.10 06-March-2015 +--------------------------- + +1. Serialization and de-serialization functions have been added to the API, +making it possible to save and restore sets of compiled patterns, though +restoration must be done in the same environment that was used for compilation. + +2. The (*NO_JIT) feature has been added; this makes it possible for a pattern +creator to specify that JIT is not to be used. + +3. A number of bugs have been fixed. In particular, bugs that caused building +on Windows using CMake to fail have been mended. + + +Version 10.00 05-January-2015 +----------------------------- + +Version 10.00 is the first release of PCRE2, a revised API for the PCRE +library. Changes prior to 10.00 are logged in the ChangeLog file for the old +API, up to item 20 for release 8.36. New programs are recommended to use the +new library. Programs that use the original (PCRE1) API will need changing +before linking with the new library. + +**** diff --git a/pcre2/NON-AUTOTOOLS-BUILD b/pcre2/NON-AUTOTOOLS-BUILD new file mode 100644 index 000000000..ceb92450c --- /dev/null +++ b/pcre2/NON-AUTOTOOLS-BUILD @@ -0,0 +1,392 @@ +Building PCRE2 without using autotools +-------------------------------------- + +This document has been converted from the PCRE1 document. I have removed a +number of sections about building in various environments, as they applied only +to PCRE1 and are probably out of date. + +This document contains the following sections: + + General + Generic instructions for the PCRE2 C library + Stack size in Windows environments + Linking programs in Windows environments + Calling conventions in Windows environments + Comments about Win32 builds + Building PCRE2 on Windows with CMake + Testing with RunTest.bat + Building PCRE2 on native z/OS and z/VM + + +GENERAL + +The basic PCRE2 library consists entirely of code written in Standard C, and so +should compile successfully on any system that has a Standard C compiler and +library. + +The PCRE2 distribution includes a "configure" file for use by the +configure/make (autotools) build system, as found in many Unix-like +environments. The README file contains information about the options for +"configure". + +There is also support for CMake, which some users prefer, especially in Windows +environments, though it can also be run in Unix-like environments. See the +section entitled "Building PCRE2 on Windows with CMake" below. + +Versions of src/config.h and src/pcre2.h are distributed in the PCRE2 tarballs +under the names src/config.h.generic and src/pcre2.h.generic. These are +provided for those who build PCRE2 without using "configure" or CMake. If you +use "configure" or CMake, the .generic versions are not used. + + +GENERIC INSTRUCTIONS FOR THE PCRE2 C LIBRARY + +The following are generic instructions for building the PCRE2 C library "by +hand". If you are going to use CMake, this section does not apply to you; you +can skip ahead to the CMake section. + + (1) Copy or rename the file src/config.h.generic as src/config.h, and edit the + macro settings that it contains to whatever is appropriate for your + environment. In particular, you can alter the definition of the NEWLINE + macro to specify what character(s) you want to be interpreted as line + terminators. + + When you compile any of the PCRE2 modules, you must specify + -DHAVE_CONFIG_H to your compiler so that src/config.h is included in the + sources. + + An alternative approach is not to edit src/config.h, but to use -D on the + compiler command line to make any changes that you need to the + configuration options. In this case -DHAVE_CONFIG_H must not be set. + + NOTE: There have been occasions when the way in which certain parameters + in src/config.h are used has changed between releases. (In the + configure/make world, this is handled automatically.) When upgrading to a + new release, you are strongly advised to review src/config.h.generic + before re-using what you had previously. + + (2) Copy or rename the file src/pcre2.h.generic as src/pcre2.h. + + (3) EITHER: + Copy or rename file src/pcre2_chartables.c.dist as + src/pcre2_chartables.c. + + OR: + Compile src/dftables.c as a stand-alone program (using -DHAVE_CONFIG_H + if you have set up src/config.h), and then run it with the single + argument "src/pcre2_chartables.c". This generates a set of standard + character tables and writes them to that file. The tables are generated + using the default C locale for your system. If you want to use a locale + that is specified by LC_xxx environment variables, add the -L option to + the dftables command. You must use this method if you are building on a + system that uses EBCDIC code. + + The tables in src/pcre2_chartables.c are defaults. The caller of PCRE2 can + specify alternative tables at run time. + + (4) For an 8-bit library, compile the following source files from the src + directory, setting -DPCRE2_CODE_UNIT_WIDTH=8 as a compiler option. Also + set -DHAVE_CONFIG_H if you have set up src/config.h with your + configuration, or else use other -D settings to change the configuration + as required. + + pcre2_auto_possess.c + pcre2_chartables.c + pcre2_compile.c + pcre2_config.c + pcre2_context.c + pcre2_dfa_match.c + pcre2_error.c + pcre2_find_bracket.c + pcre2_jit_compile.c + pcre2_maketables.c + pcre2_match.c + pcre2_match_data.c + pcre2_newline.c + pcre2_ord2utf.c + pcre2_pattern_info.c + pcre2_serialize.c + pcre2_string_utils.c + pcre2_study.c + pcre2_substitute.c + pcre2_substring.c + pcre2_tables.c + pcre2_ucd.c + pcre2_valid_utf.c + pcre2_xclass.c + + Make sure that you include -I. in the compiler command (or equivalent for + an unusual compiler) so that all included PCRE2 header files are first + sought in the src directory under the current directory. Otherwise you run + the risk of picking up a previously-installed file from somewhere else. + + Note that you must compile pcre2_jit_compile.c, even if you have not + defined SUPPORT_JIT in src/config.h, because when JIT support is not + configured, dummy functions are compiled. When JIT support IS configured, + pcre2_compile.c #includes other files from the sljit subdirectory, where + there should be 16 files, all of whose names begin with "sljit". It also + #includes src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should + not compile these yourself. + + (5) Now link all the compiled code into an object library in whichever form + your system keeps such libraries. This is the basic PCRE2 C 8-bit library. + If your system has static and shared libraries, you may have to do this + once for each type. + + (6) If you want to build a 16-bit library or 32-bit library (as well as, or + instead of the 8-bit library) just supply 16 or 32 as the value of + -DPCRE2_CODE_UNIT_WIDTH when you are compiling. + + (7) If you want to build the POSIX wrapper functions (which apply only to the + 8-bit library), ensure that you have the src/pcre2posix.h file and then + compile src/pcre2posix.c. Link the result (on its own) as the pcre2posix + library. + + (8) The pcre2test program can be linked with any combination of the 8-bit, + 16-bit and 32-bit libraries (depending on what you selected in + src/config.h). Compile src/pcre2test.c; don't forget -DHAVE_CONFIG_H if + necessary, but do NOT define PCRE2_CODE_UNIT_WIDTH. Then link with the + appropriate library/ies. If you compiled an 8-bit library, pcre2test also + needs the pcre2posix wrapper library. + + (9) Run pcre2test on the testinput files in the testdata directory, and check + that the output matches the corresponding testoutput files. There are + comments about what each test does in the section entitled "Testing PCRE2" + in the README file. If you compiled more than one of the 8-bit, 16-bit and + 32-bit libraries, you need to run pcre2test with the -16 option to do + 16-bit tests and with the -32 option to do 32-bit tests. + + Some tests are relevant only when certain build-time options are selected. + For example, test 4 is for Unicode support, and will not run if you have + built PCRE2 without it. See the comments at the start of each testinput + file. If you have a suitable Unix-like shell, the RunTest script will run + the appropriate tests for you. The command "RunTest list" will output a + list of all the tests. + + Note that the supplied files are in Unix format, with just LF characters + as line terminators. You may need to edit them to change this if your + system uses a different convention. + +(10) If you have built PCRE2 with SUPPORT_JIT, the JIT features can be tested + by running pcre2test with the -jit option. This is done automatically by + the RunTest script. You might also like to build and run the freestanding + JIT test program, src/pcre2_jit_test.c. + +(11) If you want to use the pcre2grep command, compile and link + src/pcre2grep.c; it uses only the basic 8-bit PCRE2 library (it does not + need the pcre2posix library). + + +STACK SIZE IN WINDOWS ENVIRONMENTS + +The default processor stack size of 1Mb in some Windows environments is too +small for matching patterns that need much recursion. In particular, test 2 may +fail because of this. Normally, running out of stack causes a crash, but there +have been cases where the test program has just died silently. See your linker +documentation for how to increase stack size if you experience problems. If you +are using CMake (see "BUILDING PCRE2 ON WINDOWS WITH CMAKE" below) and the gcc +compiler, you can increase the stack size for pcre2test and pcre2grep by +setting the CMAKE_EXE_LINKER_FLAGS variable to "-Wl,--stack,8388608" (for +example). The Linux default of 8Mb is a reasonable choice for the stack, though +even that can be too small for some pattern/subject combinations. + +PCRE2 has a compile configuration option to disable the use of stack for +recursion so that heap is used instead. However, pattern matching is +significantly slower when this is done. There is more about stack usage in the +"pcre2stack" documentation. + + +LINKING PROGRAMS IN WINDOWS ENVIRONMENTS + +If you want to statically link a program against a PCRE2 library in the form of +a non-dll .a file, you must define PCRE2_STATIC before including src/pcre2.h. + + +CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS + +It is possible to compile programs to use different calling conventions using +MSVC. Search the web for "calling conventions" for more information. To make it +easier to change the calling convention for the exported functions in the +PCRE2 library, the macro PCRE2_CALL_CONVENTION is present in all the external +definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is +not set, it defaults to empty; the default calling convention is then used +(which is what is wanted most of the time). + + +COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE2 ON WINDOWS WITH CMAKE") + +There are two ways of building PCRE2 using the "configure, make, make install" +paradigm on Windows systems: using MinGW or using Cygwin. These are not at all +the same thing; they are completely different from each other. There is also +support for building using CMake, which some users find a more straightforward +way of building PCRE2 under Windows. + +The MinGW home page (http://www.mingw.org/) says this: + + MinGW: A collection of freely available and freely distributable Windows + specific header files and import libraries combined with GNU toolsets that + allow one to produce native Windows programs that do not rely on any + 3rd-party C runtime DLLs. + +The Cygwin home page (http://www.cygwin.com/) says this: + + Cygwin is a Linux-like environment for Windows. It consists of two parts: + + . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing + substantial Linux API functionality + + . A collection of tools which provide Linux look and feel. + +On both MinGW and Cygwin, PCRE2 should build correctly using: + + ./configure && make && make install + +This should create two libraries called libpcre2-8 and libpcre2-posix. These +are independent libraries: when you link with libpcre2-posix you must also link +with libpcre2-8, which contains the basic functions. + +Using Cygwin's compiler generates libraries and executables that depend on +cygwin1.dll. If a library that is generated this way is distributed, +cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL +licence, this forces not only PCRE2 to be under the GPL, but also the entire +application. A distributor who wants to keep their own code proprietary must +purchase an appropriate Cygwin licence. + +MinGW has no such restrictions. The MinGW compiler generates a library or +executable that can run standalone on Windows without any third party dll or +licensing issues. + +But there is more complication: + +If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is +to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a +front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's +gcc and MinGW's gcc). So, a user can: + +. Build native binaries by using MinGW or by getting Cygwin and using + -mno-cygwin. + +. Build binaries that depend on cygwin1.dll by using Cygwin with the normal + compiler flags. + +The test files that are supplied with PCRE2 are in UNIX format, with LF +characters as line terminators. Unless your PCRE2 library uses a default +newline option that includes LF as a valid newline, it may be necessary to +change the line terminators in the test files to get some of the tests to work. + + +BUILDING PCRE2 ON WINDOWS WITH CMAKE + +CMake is an alternative configuration facility that can be used instead of +"configure". CMake creates project files (make files, solution files, etc.) +tailored to numerous development environments, including Visual Studio, +Borland, Msys, MinGW, NMake, and Unix. If possible, use short paths with no +spaces in the names for your CMake installation and your PCRE2 source and build +directories. + +The following instructions were contributed by a PCRE1 user, but they should +also work for PCRE2. If they are not followed exactly, errors may occur. In the +event that errors do occur, it is recommended that you delete the CMake cache +before attempting to repeat the CMake build process. In the CMake GUI, the +cache can be deleted by selecting "File > Delete Cache". + +1. Install the latest CMake version available from http://www.cmake.org/, and + ensure that cmake\bin is on your path. + +2. Unzip (retaining folder structure) the PCRE2 source tree into a source + directory such as C:\pcre2. You should ensure your local date and time + is not earlier than the file dates in your source dir if the release is + very new. + +3. Create a new, empty build directory, preferably a subdirectory of the + source dir. For example, C:\pcre2\pcre2-xx\build. + +4. Run cmake-gui from the Shell envirornment of your build tool, for example, + Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. Do not try + to start Cmake from the Windows Start menu, as this can lead to errors. + +5. Enter C:\pcre2\pcre2-xx and C:\pcre2\pcre2-xx\build for the source and + build directories, respectively. + +6. Hit the "Configure" button. + +7. Select the particular IDE / build tool that you are using (Visual + Studio, MSYS makefiles, MinGW makefiles, etc.) + +8. The GUI will then list several configuration options. This is where + you can disable Unicode support or select other PCRE2 optional features. + +9. Hit "Configure" again. The adjacent "Generate" button should now be + active. + +10. Hit "Generate". + +11. The build directory should now contain a usable build system, be it a + solution file for Visual Studio, makefiles for MinGW, etc. Exit from + cmake-gui and use the generated build system with your compiler or IDE. + E.g., for MinGW you can run "make", or for Visual Studio, open the PCRE2 + solution, select the desired configuration (Debug, or Release, etc.) and + build the ALL_BUILD project. + +12. If during configuration with cmake-gui you've elected to build the test + programs, you can execute them by building the test project. E.g., for + MinGW: "make test"; for Visual Studio build the RUN_TESTS project. The + most recent build configuration is targeted by the tests. A summary of + test results is presented. Complete test output is subsequently + available for review in Testing\Temporary under your build dir. + + +TESTING WITH RUNTEST.BAT + +If configured with CMake, building the test project ("make test" or building +ALL_TESTS in Visual Studio) creates (and runs) pcre2_test.bat (and depending +on your configuration options, possibly other test programs) in the build +directory. The pcre2_test.bat script runs RunTest.bat with correct source and +exe paths. + +For manual testing with RunTest.bat, provided the build dir is a subdirectory +of the source directory: Open command shell window. Chdir to the location +of your pcre2test.exe and pcre2grep.exe programs. Call RunTest.bat with +"..\RunTest.Bat" or "..\..\RunTest.bat" as appropriate. + +To run only a particular test with RunTest.Bat provide a test number argument. + +Otherwise: + +1. Copy RunTest.bat into the directory where pcre2test.exe and pcre2grep.exe + have been created. + +2. Edit RunTest.bat to indentify the full or relative location of + the pcre2 source (wherein which the testdata folder resides), e.g.: + + set srcdir=C:\pcre2\pcre2-10.00 + +3. In a Windows command environment, chdir to the location of your bat and + exe programs. + +4. Run RunTest.bat. Test outputs will automatically be compared to expected + results, and discrepancies will be identified in the console output. + +To independently test the just-in-time compiler, run pcre2_jit_test.exe. + + +BUILDING PCRE2 ON NATIVE Z/OS AND Z/VM + +z/OS and z/VM are operating systems for mainframe computers, produced by IBM. +The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and +applications can be supported through UNIX System Services, and in such an +environment PCRE2 can be built in the same way as in other systems. However, in +native z/OS (without UNIX System Services) and in z/VM, special ports are +required. For details, please see this web site: + + http://www.zaconsultants.net + +The site currently has ports for PCRE1 releases, but PCRE2 should follow in due +course. + +You may also download PCRE1 from WWW.CBTTAPE.ORG, file 882. Everything, source +and executable, is in EBCDIC and native z/OS file formats and this is the +recommended download site. + +============================= +Last Updated: 16 July 2015 diff --git a/pcre2/PrepareRelease b/pcre2/PrepareRelease new file mode 100755 index 000000000..114fce01d --- /dev/null +++ b/pcre2/PrepareRelease @@ -0,0 +1,235 @@ +#/bin/sh + +# Script to prepare the files for building a PCRE2 release. It does some +# processing of the documentation, detrails files, and creates pcre2.h.generic +# and config.h.generic (for use by builders who can't run ./configure). + +# You must run this script before runnning "make dist". If its first argument +# is "doc", it stops after preparing the documentation. There are no other +# arguments. The script makes use of the following files: + +# 132html A Perl script that converts a .1 or .3 man page into HTML. It +# "knows" the relevant troff constructs that are used in the PCRE2 +# man pages. + +# CheckMan A Perl script that checks man pages for typos in the mark up. + +# CleanTxt A Perl script that cleans up the output of "nroff -man" by +# removing backspaces and other redundant text so as to produce +# a readable .txt file. + +# Detrail A Perl script that removes trailing spaces from files. + +# doc/index.html.src +# A file that is copied as index.html into the doc/html directory +# when the HTML documentation is built. It works like this so that +# doc/html can be deleted and re-created from scratch. + +# README & NON-AUTOTOOLS-BUILD +# These files are copied into the doc/html directory, with .txt +# extensions so that they can by hyperlinked from the HTML +# documentation, because some people just go to the HTML without +# looking for text files. + + +# First, sort out the documentation. Remove pcre2demo.3 first because it won't +# pass the markup check (it is created below, using markup that none of the +# other pages use). + +cd doc +echo Processing documentation + +/bin/rm -f pcre2demo.3 + +# Check the remaining man pages + +perl ../CheckMan *.1 *.3 +if [ $? != 0 ] ; then exit 1; fi + +# Make Text form of the documentation. It needs some mangling to make it +# tidy for online reading. Concatenate all the .3 stuff, but omit the +# individual function pages. + +cat <pcre2.txt +----------------------------------------------------------------------------- +This file contains a concatenation of the PCRE2 man pages, converted to plain +text format for ease of searching with a text editor, or for use on systems +that do not have a man page processor. The small individual files that give +synopses of each function in the library have not been included. Neither has +the pcre2demo program. There are separate text files for the pcre2grep and +pcre2test commands. +----------------------------------------------------------------------------- + + +End + +echo "Making pcre2.txt" +for file in pcre2 pcre2api pcre2build pcre2callout pcre2compat pcre2jit \ + pcre2limits pcre2matching pcre2partial pcre2pattern pcre2perform \ + pcre2posix pcre2sample pcre2serialize pcre2stack pcre2syntax \ + pcre2unicode ; do + echo " Processing $file.3" + nroff -c -man $file.3 >$file.rawtxt + perl ../CleanTxt <$file.rawtxt >>pcre2.txt + /bin/rm $file.rawtxt + echo "------------------------------------------------------------------------------" >>pcre2.txt + if [ "$file" != "pcre2sample" ] ; then + echo " " >>pcre2.txt + echo " " >>pcre2.txt + fi +done + +# The three commands +for file in pcre2test pcre2grep pcre2-config ; do + echo Making $file.txt + nroff -c -man $file.1 >$file.rawtxt + perl ../CleanTxt <$file.rawtxt >$file.txt + /bin/rm $file.rawtxt +done + + +# Make pcre2demo.3 from the pcre2demo.c source file + +echo "Making pcre2demo.3" +perl <<"END" >pcre2demo.3 + open(IN, "../src/pcre2demo.c") || die "Failed to open src/pcre2demo.c\n"; + open(OUT, ">pcre2demo.3") || die "Failed to open pcre2demo.3\n"; + print OUT ".\\\" Start example.\n" . + ".de EX\n" . + ". nr mE \\\\n(.f\n" . + ". nf\n" . + ". nh\n" . + ". ft CW\n" . + "..\n" . + ".\n" . + ".\n" . + ".\\\" End example.\n" . + ".de EE\n" . + ". ft \\\\n(mE\n" . + ". fi\n" . + ". hy \\\\n(HY\n" . + "..\n" . + ".\n" . + ".EX\n" ; + while () + { + s/\\/\\e/g; + print OUT; + } + print OUT ".EE\n"; + close(IN); + close(OUT); +END +if [ $? != 0 ] ; then exit 1; fi + + +# Make HTML form of the documentation. + +echo "Making HTML documentation" +/bin/rm html/* +cp index.html.src html/index.html +cp ../README html/README.txt +cp ../NON-AUTOTOOLS-BUILD html/NON-AUTOTOOLS-BUILD.txt + +for file in *.1 ; do + base=`basename $file .1` + echo " Making $base.html" + perl ../132html -toc $base <$file >html/$base.html +done + +# Exclude table of contents for function summaries. It seems that expr +# forces an anchored regex. Also exclude them for small pages that have +# only one section. + +for file in *.3 ; do + base=`basename $file .3` + toc=-toc + if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi + if [ "$base" = "pcre2sample" ] || \ + [ "$base" = "pcre2stack" ] || \ + [ "$base" = "pcre2compat" ] || \ + [ "$base" = "pcre2limits" ] || \ + [ "$base" = "pcre2unicode" ] ; then + toc="" + fi + echo " Making $base.html" + perl ../132html $toc $base <$file >html/$base.html + if [ $? != 0 ] ; then exit 1; fi +done + +# End of documentation processing; stop if only documentation required. + +cd .. +echo Documentation done +if [ "$1" = "doc" ] ; then exit; fi + +# These files are detrailed; do not detrail the test data because there may be +# significant trailing spaces. Do not detrail RunTest.bat, because it has CRLF +# line endings and the detrail script removes all trailing white space. The +# configure files are also omitted from the detrailing. + +files="\ + Makefile.am \ + configure.ac \ + README \ + LICENCE \ + COPYING \ + AUTHORS \ + NEWS \ + NON-AUTOTOOLS-BUILD \ + INSTALL \ + 132html \ + CleanTxt \ + Detrail \ + ChangeLog \ + CMakeLists.txt \ + RunGrepTest \ + RunTest \ + pcre2-config.in \ + perltest.sh \ + libpcre2-8.pc.in \ + libpcre2-16.pc.in \ + libpcre2-32.pc.in \ + libpcre2-posix.pc.in \ + src/dftables.c \ + src/pcre2.h.in \ + src/pcre2_auto_possess.c \ + src/pcre2_compile.c \ + src/pcre2_config.c \ + src/pcre2_context.c \ + src/pcre2_dfa_match.c \ + src/pcre2_error.c \ + src/pcre2_find_bracket.c \ + src/pcre2_internal.h \ + src/pcre2_intmodedep.h \ + src/pcre2_jit_compile.c \ + src/pcre2_jit_match.c \ + src/pcre2_jit_misc.c \ + src/pcre2_jit_test.c \ + src/pcre2_maketables.c \ + src/pcre2_match.c \ + src/pcre2_match_data.c \ + src/pcre2_newline.c \ + src/pcre2_ord2utf.c \ + src/pcre2_pattern_info.c \ + src/pcre2_printint.c \ + src/pcre2_string_utils.c \ + src/pcre2_study.c \ + src/pcre2_substring.c \ + src/pcre2_tables.c \ + src/pcre2_ucd.c \ + src/pcre2_ucp.h \ + src/pcre2_valid_utf.c \ + src/pcre2_xclass.c \ + src/pcre2demo.c \ + src/pcre2grep.c \ + src/pcre2posix.c \ + src/pcre2posix.h \ + src/pcre2test.c" + +echo Detrailing +perl ./Detrail $files doc/p* doc/html/* + +echo Done + +#End diff --git a/pcre2/README b/pcre2/README new file mode 100644 index 000000000..48d2ffdd7 --- /dev/null +++ b/pcre2/README @@ -0,0 +1,843 @@ +README file for PCRE2 (Perl-compatible regular expression library) +------------------------------------------------------------------ + +PCRE2 is a re-working of the original PCRE library to provide an entirely new +API. The latest release of PCRE2 is always available in three alternative +formats from: + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.tar.gz + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.tar.bz2 + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.zip + +There is a mailing list for discussion about the development of PCRE (both the +original and new APIs) at pcre-dev@exim.org. You can access the archives and +subscribe or manage your subscription here: + + https://lists.exim.org/mailman/listinfo/pcre-dev + +Please read the NEWS file if you are upgrading from a previous release. +The contents of this README file are: + + The PCRE2 APIs + Documentation for PCRE2 + Contributions by users of PCRE2 + Building PCRE2 on non-Unix-like systems + Building PCRE2 without using autotools + Building PCRE2 using autotools + Retrieving configuration information + Shared libraries + Cross-compiling using autotools + Making new tarballs + Testing PCRE2 + Character tables + File manifest + + +The PCRE2 APIs +-------------- + +PCRE2 is written in C, and it has its own API. There are three sets of +functions, one for the 8-bit library, which processes strings of bytes, one for +the 16-bit library, which processes strings of 16-bit values, and one for the +32-bit library, which processes strings of 32-bit values. There are no C++ +wrappers. + +The distribution does contain a set of C wrapper functions for the 8-bit +library that are based on the POSIX regular expression API (see the pcre2posix +man page). These can be found in a library called libpcre2posix. Note that this +just provides a POSIX calling interface to PCRE2; the regular expressions +themselves still follow Perl syntax and semantics. The POSIX API is restricted, +and does not give full access to all of PCRE2's facilities. + +The header file for the POSIX-style functions is called pcre2posix.h. The +official POSIX name is regex.h, but I did not want to risk possible problems +with existing files of that name by distributing it that way. To use PCRE2 with +an existing program that uses the POSIX API, pcre2posix.h will have to be +renamed or pointed at by a link. + +If you are using the POSIX interface to PCRE2 and there is already a POSIX +regex library installed on your system, as well as worrying about the regex.h +header file (as mentioned above), you must also take care when linking programs +to ensure that they link with PCRE2's libpcre2posix library. Otherwise they may +pick up the POSIX functions of the same name from the other library. + +One way of avoiding this confusion is to compile PCRE2 with the addition of +-Dregcomp=PCRE2regcomp (and similarly for the other POSIX functions) to the +compiler flags (CFLAGS if you are using "configure" -- see below). This has the +effect of renaming the functions so that the names no longer clash. Of course, +you have to do the same thing for your applications, or write them using the +new names. + + +Documentation for PCRE2 +----------------------- + +If you install PCRE2 in the normal way on a Unix-like system, you will end up +with a set of man pages whose names all start with "pcre2". The one that is +just called "pcre2" lists all the others. In addition to these man pages, the +PCRE2 documentation is supplied in two other forms: + + 1. There are files called doc/pcre2.txt, doc/pcre2grep.txt, and + doc/pcre2test.txt in the source distribution. The first of these is a + concatenation of the text forms of all the section 3 man pages except the + listing of pcre2demo.c and those that summarize individual functions. The + other two are the text forms of the section 1 man pages for the pcre2grep + and pcre2test commands. These text forms are provided for ease of scanning + with text editors or similar tools. They are installed in + /share/doc/pcre2, where is the installation prefix + (defaulting to /usr/local). + + 2. A set of files containing all the documentation in HTML form, hyperlinked + in various ways, and rooted in a file called index.html, is distributed in + doc/html and installed in /share/doc/pcre2/html. + + +Building PCRE2 on non-Unix-like systems +--------------------------------------- + +For a non-Unix-like system, please read the comments in the file +NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and +"make" you may be able to build PCRE2 using autotools in the same way as for +many Unix-like systems. + +PCRE2 can also be configured using CMake, which can be run in various ways +(command line, GUI, etc). This creates Makefiles, solution files, etc. The file +NON-AUTOTOOLS-BUILD has information about CMake. + +PCRE2 has been compiled on many different operating systems. It should be +straightforward to build PCRE2 on any system that has a Standard C compiler and +library, because it uses only Standard C functions. + + +Building PCRE2 without using autotools +-------------------------------------- + +The use of autotools (in particular, libtool) is problematic in some +environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD +file for ways of building PCRE2 without using autotools. + + +Building PCRE2 using autotools +------------------------------ + +The following instructions assume the use of the widely used "configure; make; +make install" (autotools) process. + +To build PCRE2 on system that supports autotools, first run the "configure" +command from the PCRE2 distribution directory, with your current directory set +to the directory where you want the files to be created. This command is a +standard GNU "autoconf" configuration script, for which generic instructions +are supplied in the file INSTALL. + +Most commonly, people build PCRE2 within its own distribution directory, and in +this case, on many systems, just running "./configure" is sufficient. However, +the usual methods of changing standard defaults are available. For example: + +CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local + +This command specifies that the C compiler should be run with the flags '-O2 +-Wall' instead of the default, and that "make install" should install PCRE2 +under /opt/local instead of the default /usr/local. + +If you want to build in a different directory, just run "configure" with that +directory as current. For example, suppose you have unpacked the PCRE2 source +into /source/pcre2/pcre2-xxx, but you want to build it in +/build/pcre2/pcre2-xxx: + +cd /build/pcre2/pcre2-xxx +/source/pcre2/pcre2-xxx/configure + +PCRE2 is written in C and is normally compiled as a C library. However, it is +possible to build it as a C++ library, though the provided building apparatus +does not have any features to support this. + +There are some optional features that can be included or omitted from the PCRE2 +library. They are also documented in the pcre2build man page. + +. By default, both shared and static libraries are built. You can change this + by adding one of these options to the "configure" command: + + --disable-shared + --disable-static + + (See also "Shared libraries on Unix-like systems" below.) + +. By default, only the 8-bit library is built. If you add --enable-pcre2-16 to + the "configure" command, the 16-bit library is also built. If you add + --enable-pcre2-32 to the "configure" command, the 32-bit library is also + built. If you want only the 16-bit or 32-bit library, use --disable-pcre2-8 + to disable building the 8-bit library. + +. If you want to include support for just-in-time compiling, which can give + large performance improvements on certain platforms, add --enable-jit to the + "configure" command. This support is available only for certain hardware + architectures. If you try to enable it on an unsupported architecture, there + will be a compile time error. + +. When JIT support is enabled, pcre2grep automatically makes use of it, unless + you add --disable-pcre2grep-jit to the "configure" command. + +. If you do not want to make use of the support for UTF-8 Unicode character + strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit + library, or UTF-32 Unicode character strings in the 32-bit library, you can + add --disable-unicode to the "configure" command. This reduces the size of + the libraries. It is not possible to configure one library with Unicode + support, and another without, in the same configuration. + + When Unicode support is available, the use of a UTF encoding still has to be + enabled by setting the PCRE2_UTF option at run time or starting a pattern + with (*UTF). When PCRE2 is compiled with Unicode support, its input can only + either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms. It is + not possible to use both --enable-unicode and --enable-ebcdic at the same + time. + + As well as supporting UTF strings, Unicode support includes support for the + \P, \p, and \X sequences that recognize Unicode character properties. + However, only the basic two-letter properties such as Lu are supported. + Escape sequences such as \d and \w in patterns do not by default make use of + Unicode properties, but can be made to do so by setting the PCRE2_UCP option + or starting a pattern with (*UCP). + +. You can build PCRE2 to recognize either CR or LF or the sequence CRLF, or any + of the preceding, or any of the Unicode newline sequences, as indicating the + end of a line. Whatever you specify at build time is the default; the caller + of PCRE2 can change the selection at run time. The default newline indicator + is a single LF character (the Unix standard). You can specify the default + newline indicator by adding --enable-newline-is-cr, --enable-newline-is-lf, + --enable-newline-is-crlf, --enable-newline-is-anycrlf, or + --enable-newline-is-any to the "configure" command, respectively. + + If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of + the standard tests will fail, because the lines in the test files end with + LF. Even if the files are edited to change the line endings, there are likely + to be some failures. With --enable-newline-is-anycrlf or + --enable-newline-is-any, many tests should succeed, but there may be some + failures. + +. By default, the sequence \R in a pattern matches any Unicode line ending + sequence. This is independent of the option specifying what PCRE2 considers + to be the end of a line (see above). However, the caller of PCRE2 can + restrict \R to match only CR, LF, or CRLF. You can make this the default by + adding --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R"). + +. In a pattern, the escape sequence \C matches a single code unit, even in a + UTF mode. This can be dangerous because it breaks up multi-code-unit + characters. You can build PCRE2 with the use of \C permanently locked out by + adding --enable-never-backslash-C (note the upper case C) to the "configure" + command. When \C is allowed by the library, individual applications can lock + it out by calling pcre2_compile() with the PCRE2_NEVER_BACKSLASH_C option. + +. PCRE2 has a counter that limits the depth of nesting of parentheses in a + pattern. This limits the amount of system stack that a pattern uses when it + is compiled. The default is 250, but you can change it by setting, for + example, + + --with-parens-nest-limit=500 + +. PCRE2 has a counter that can be set to limit the amount of resources it uses + when matching a pattern. If the limit is exceeded during a match, the match + fails. The default is ten million. You can change the default by setting, for + example, + + --with-match-limit=500000 + + on the "configure" command. This is just the default; individual calls to + pcre2_match() can supply their own value. There is more discussion on the + pcre2api man page. + +. There is a separate counter that limits the depth of recursive function calls + during a matching process. This also has a default of ten million, which is + essentially "unlimited". You can change the default by setting, for example, + + --with-match-limit-recursion=500000 + + Recursive function calls use up the runtime stack; running out of stack can + cause programs to crash in strange ways. There is a discussion about stack + sizes in the pcre2stack man page. + +. In the 8-bit library, the default maximum compiled pattern size is around + 64K. You can increase this by adding --with-link-size=3 to the "configure" + command. PCRE2 then uses three bytes instead of two for offsets to different + parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is + the same as --with-link-size=4, which (in both libraries) uses four-byte + offsets. Increasing the internal link size reduces performance in the 8-bit + and 16-bit libraries. In the 32-bit library, the link size setting is + ignored, as 4-byte offsets are always used. + +. You can build PCRE2 so that its internal match() function that is called from + pcre2_match() does not call itself recursively. Instead, it uses memory + blocks obtained from the heap to save data that would otherwise be saved on + the stack. To build PCRE2 like this, use + + --disable-stack-for-recursion + + on the "configure" command. PCRE2 runs more slowly in this mode, but it may + be necessary in environments with limited stack sizes. This applies only to + the normal execution of the pcre2_match() function; if JIT support is being + successfully used, it is not relevant. Equally, it does not apply to + pcre2_dfa_match(), which does not use deeply nested recursion. There is a + discussion about stack sizes in the pcre2stack man page. + +. For speed, PCRE2 uses four tables for manipulating and identifying characters + whose code point values are less than 256. By default, it uses a set of + tables for ASCII encoding that is part of the distribution. If you specify + + --enable-rebuild-chartables + + a program called dftables is compiled and run in the default C locale when + you obey "make". It builds a source file called pcre2_chartables.c. If you do + not specify this option, pcre2_chartables.c is created as a copy of + pcre2_chartables.c.dist. See "Character tables" below for further + information. + +. It is possible to compile PCRE2 for use on systems that use EBCDIC as their + character code (as opposed to ASCII/Unicode) by specifying + + --enable-ebcdic --disable-unicode + + This automatically implies --enable-rebuild-chartables (see above). However, + when PCRE2 is built this way, it always operates in EBCDIC. It cannot support + both EBCDIC and UTF-8/16/32. There is a second option, --enable-ebcdic-nl25, + which specifies that the code value for the EBCDIC NL character is 0x25 + instead of the default 0x15. + +. If you specify --enable-debug, additional debugging code is included in the + build. This option is intended for use by the PCRE2 maintainers. + +. In environments where valgrind is installed, if you specify + + --enable-valgrind + + PCRE2 will use valgrind annotations to mark certain memory regions as + unaddressable. This allows it to detect invalid memory accesses, and is + mostly useful for debugging PCRE2 itself. + +. In environments where the gcc compiler is used and lcov version 1.6 or above + is installed, if you specify + + --enable-coverage + + the build process implements a code coverage report for the test suite. The + report is generated by running "make coverage". If ccache is installed on + your system, it must be disabled when building PCRE2 for coverage reporting. + You can do this by setting the environment variable CCACHE_DISABLE=1 before + running "make" to build PCRE2. There is more information about coverage + reporting in the "pcre2build" documentation. + +. The pcre2grep program currently supports only 8-bit data files, and so + requires the 8-bit PCRE2 library. It is possible to compile pcre2grep to use + libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by + specifying one or both of + + --enable-pcre2grep-libz + --enable-pcre2grep-libbz2 + + Of course, the relevant libraries must be installed on your system. + +. The default size (in bytes) of the internal buffer used by pcre2grep can be + set by, for example: + + --with-pcre2grep-bufsize=51200 + + The value must be a plain integer. The default is 20480. + +. It is possible to compile pcre2test so that it links with the libreadline + or libedit libraries, by specifying, respectively, + + --enable-pcre2test-libreadline or --enable-pcre2test-libedit + + If this is done, when pcre2test's input is from a terminal, it reads it using + the readline() function. This provides line-editing and history facilities. + Note that libreadline is GPL-licenced, so if you distribute a binary of + pcre2test linked in this way, there may be licensing issues. These can be + avoided by linking with libedit (which has a BSD licence) instead. + + Enabling libreadline causes the -lreadline option to be added to the + pcre2test build. In many operating environments with a sytem-installed + readline library this is sufficient. However, in some environments (e.g. if + an unmodified distribution version of readline is in use), it may be + necessary to specify something like LIBS="-lncurses" as well. This is + because, to quote the readline INSTALL, "Readline uses the termcap functions, + but does not link with the termcap or curses library itself, allowing + applications which link with readline the to choose an appropriate library." + If you get error messages about missing functions tgetstr, tgetent, tputs, + tgetflag, or tgoto, this is the problem, and linking with the ncurses library + should fix it. + +The "configure" script builds the following files for the basic C library: + +. Makefile the makefile that builds the library +. src/config.h build-time configuration options for the library +. src/pcre2.h the public PCRE2 header file +. pcre2-config script that shows the building settings such as CFLAGS + that were set for "configure" +. libpcre2-8.pc ) +. libpcre2-16.pc ) data for the pkg-config command +. libpcre2-32.pc ) +. libpcre2-posix.pc ) +. libtool script that builds shared and/or static libraries + +Versions of config.h and pcre2.h are distributed in the src directory of PCRE2 +tarballs under the names config.h.generic and pcre2.h.generic. These are +provided for those who have to build PCRE2 without using "configure" or CMake. +If you use "configure" or CMake, the .generic versions are not used. + +The "configure" script also creates config.status, which is an executable +script that can be run to recreate the configuration, and config.log, which +contains compiler output from tests that "configure" runs. + +Once "configure" has run, you can run "make". This builds whichever of the +libraries libpcre2-8, libpcre2-16 and libpcre2-32 are configured, and a test +program called pcre2test. If you enabled JIT support with --enable-jit, another +test program called pcre2_jit_test is built as well. If the 8-bit library is +built, libpcre2-posix and the pcre2grep command are also built. Running +"make" with the -j option may speed up compilation on multiprocessor systems. + +The command "make check" runs all the appropriate tests. Details of the PCRE2 +tests are given below in a separate section of this document. The -j option of +"make" can also be used when running the tests. + +You can use "make install" to install PCRE2 into live directories on your +system. The following are installed (file names are all relative to the + that is set when "configure" is run): + + Commands (bin): + pcre2test + pcre2grep (if 8-bit support is enabled) + pcre2-config + + Libraries (lib): + libpcre2-8 (if 8-bit support is enabled) + libpcre2-16 (if 16-bit support is enabled) + libpcre2-32 (if 32-bit support is enabled) + libpcre2-posix (if 8-bit support is enabled) + + Configuration information (lib/pkgconfig): + libpcre2-8.pc + libpcre2-16.pc + libpcre2-32.pc + libpcre2-posix.pc + + Header files (include): + pcre2.h + pcre2posix.h + + Man pages (share/man/man{1,3}): + pcre2grep.1 + pcre2test.1 + pcre2-config.1 + pcre2.3 + pcre2*.3 (lots more pages, all starting "pcre2") + + HTML documentation (share/doc/pcre2/html): + index.html + *.html (lots more pages, hyperlinked from index.html) + + Text file documentation (share/doc/pcre2): + AUTHORS + COPYING + ChangeLog + LICENCE + NEWS + README + pcre2.txt (a concatenation of the man(3) pages) + pcre2test.txt the pcre2test man page + pcre2grep.txt the pcre2grep man page + pcre2-config.txt the pcre2-config man page + +If you want to remove PCRE2 from your system, you can run "make uninstall". +This removes all the files that "make install" installed. However, it does not +remove any directories, because these are often shared with other programs. + + +Retrieving configuration information +------------------------------------ + +Running "make install" installs the command pcre2-config, which can be used to +recall information about the PCRE2 configuration and installation. For example: + + pcre2-config --version + +prints the version number, and + + pcre2-config --libs8 + +outputs information about where the 8-bit library is installed. This command +can be included in makefiles for programs that use PCRE2, saving the programmer +from having to remember too many details. Run pcre2-config with no arguments to +obtain a list of possible arguments. + +The pkg-config command is another system for saving and retrieving information +about installed libraries. Instead of separate commands for each library, a +single command is used. For example: + + pkg-config --libs libpcre2-16 + +The data is held in *.pc files that are installed in a directory called +/lib/pkgconfig. + + +Shared libraries +---------------- + +The default distribution builds PCRE2 as shared libraries and static libraries, +as long as the operating system supports shared libraries. Shared library +support relies on the "libtool" script which is built as part of the +"configure" process. + +The libtool script is used to compile and link both shared and static +libraries. They are placed in a subdirectory called .libs when they are newly +built. The programs pcre2test and pcre2grep are built to use these uninstalled +libraries (by means of wrapper scripts in the case of shared libraries). When +you use "make install" to install shared libraries, pcre2grep and pcre2test are +automatically re-built to use the newly installed shared libraries before being +installed themselves. However, the versions left in the build directory still +use the uninstalled libraries. + +To build PCRE2 using static libraries only you must use --disable-shared when +configuring it. For example: + +./configure --prefix=/usr/gnu --disable-shared + +Then run "make" in the usual way. Similarly, you can use --disable-static to +build only shared libraries. + + +Cross-compiling using autotools +------------------------------- + +You can specify CC and CFLAGS in the normal way to the "configure" command, in +order to cross-compile PCRE2 for some other host. However, you should NOT +specify --enable-rebuild-chartables, because if you do, the dftables.c source +file is compiled and run on the local host, in order to generate the inbuilt +character tables (the pcre2_chartables.c file). This will probably not work, +because dftables.c needs to be compiled with the local compiler, not the cross +compiler. + +When --enable-rebuild-chartables is not specified, pcre2_chartables.c is +created by making a copy of pcre2_chartables.c.dist, which is a default set of +tables that assumes ASCII code. Cross-compiling with the default tables should +not be a problem. + +If you need to modify the character tables when cross-compiling, you should +move pcre2_chartables.c.dist out of the way, then compile dftables.c by hand +and run it on the local host to make a new version of pcre2_chartables.c.dist. +Then when you cross-compile PCRE2 this new version of the tables will be used. + + +Making new tarballs +------------------- + +The command "make dist" creates three PCRE2 tarballs, in tar.gz, tar.bz2, and +zip formats. The command "make distcheck" does the same, but then does a trial +build of the new distribution to ensure that it works. + +If you have modified any of the man page sources in the doc directory, you +should first run the PrepareRelease script before making a distribution. This +script creates the .txt and HTML forms of the documentation from the man pages. + + +Testing PCRE2 +------------ + +To test the basic PCRE2 library on a Unix-like system, run the RunTest script. +There is another script called RunGrepTest that tests the pcre2grep command. +When JIT support is enabled, a third test program called pcre2_jit_test is +built. Both the scripts and all the program tests are run if you obey "make +check". For other environments, see the instructions in NON-AUTOTOOLS-BUILD. + +The RunTest script runs the pcre2test test program (which is documented in its +own man page) on each of the relevant testinput files in the testdata +directory, and compares the output with the contents of the corresponding +testoutput files. RunTest uses a file called testtry to hold the main output +from pcre2test. Other files whose names begin with "test" are used as working +files in some tests. + +Some tests are relevant only when certain build-time options were selected. For +example, the tests for UTF-8/16/32 features are run only when Unicode support +is available. RunTest outputs a comment when it skips a test. + +Many (but not all) of the tests that are not skipped are run twice if JIT +support is available. On the second run, JIT compilation is forced. This +testing can be suppressed by putting "nojit" on the RunTest command line. + +The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit +libraries that are enabled. If you want to run just one set of tests, call +RunTest with either the -8, -16 or -32 option. + +If valgrind is installed, you can run the tests under it by putting "valgrind" +on the RunTest command line. To run pcre2test on just one or more specific test +files, give their numbers as arguments to RunTest, for example: + + RunTest 2 7 11 + +You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the +end), or a number preceded by ~ to exclude a test. For example: + + Runtest 3-15 ~10 + +This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests +except test 13. Whatever order the arguments are in, the tests are always run +in numerical order. + +You can also call RunTest with the single argument "list" to cause it to output +a list of tests. + +The test sequence starts with "test 0", which is a special test that has no +input file, and whose output is not checked. This is because it will be +different on different hardware and with different configurations. The test +exists in order to exercise some of pcre2test's code that would not otherwise +be run. + +Tests 1 and 2 can always be run, as they expect only plain text strings (not +UTF) and make no use of Unicode properties. The first test file can be fed +directly into the perltest.sh script to check that Perl gives the same results. +The only difference you should see is in the first few lines, where the Perl +version is given instead of the PCRE2 version. The second set of tests check +auxiliary functions, error detection, and run-time flags that are specific to +PCRE2. It also uses the debugging flags to check some of the internals of +pcre2_compile(). + +If you build PCRE2 with a locale setting that is not the standard C locale, the +character tables may be different (see next paragraph). In some cases, this may +cause failures in the second set of tests. For example, in a locale where the +isprint() function yields TRUE for characters in the range 128-255, the use of +[:isascii:] inside a character class defines a different set of characters, and +this shows up in this test as a difference in the compiled code, which is being +listed for checking. For example, where the comparison test output contains +[\x00-\x7f] the test might contain [\x00-\xff], and similarly in some other +cases. This is not a bug in PCRE2. + +Test 3 checks pcre2_maketables(), the facility for building a set of character +tables for a specific locale and using them instead of the default tables. The +script uses the "locale" command to check for the availability of the "fr_FR", +"french", or "fr" locale, and uses the first one that it finds. If the "locale" +command fails, or if its output doesn't include "fr_FR", "french", or "fr" in +the list of available locales, the third test cannot be run, and a comment is +output to say why. If running this test produces an error like this: + + ** Failed to set locale "fr_FR" + +it means that the given locale is not available on your system, despite being +listed by "locale". This does not mean that PCRE2 is broken. There are three +alternative output files for the third test, because three different versions +of the French locale have been encountered. The test passes if its output +matches any one of them. + +Tests 4 and 5 check UTF and Unicode property support, test 4 being compatible +with the perltest.sh script, and test 5 checking PCRE2-specific things. + +Tests 6 and 7 check the pcre2_dfa_match() alternative matching function, in +non-UTF mode and UTF-mode with Unicode property support, respectively. + +Test 8 checks some internal offsets and code size features; it is run only when +the default "link size" of 2 is set (in other cases the sizes change) and when +Unicode support is enabled. + +Tests 9 and 10 are run only in 8-bit mode, and tests 11 and 12 are run only in +16-bit and 32-bit modes. These are tests that generate different output in +8-bit mode. Each pair are for general cases and Unicode support, respectively. +Test 13 checks the handling of non-UTF characters greater than 255 by +pcre2_dfa_match() in 16-bit and 32-bit modes. + +Test 14 contains a number of tests that must not be run with JIT. They check, +among other non-JIT things, the match-limiting features of the intepretive +matcher. + +Test 15 is run only when JIT support is not available. It checks that an +attempt to use JIT has the expected behaviour. + +Test 16 is run only when JIT support is available. It checks JIT complete and +partial modes, match-limiting under JIT, and other JIT-specific features. + +Tests 17 and 18 are run only in 8-bit mode. They check the POSIX interface to +the 8-bit library, without and with Unicode support, respectively. + +Test 19 checks the serialization functions by writing a set of compiled +patterns to a file, and then reloading and checking them. + + +Character tables +---------------- + +For speed, PCRE2 uses four tables for manipulating and identifying characters +whose code point values are less than 256. By default, a set of tables that is +built into the library is used. The pcre2_maketables() function can be called +by an application to create a new set of tables in the current locale. This are +passed to PCRE2 by calling pcre2_set_character_tables() to put a pointer into a +compile context. + +The source file called pcre2_chartables.c contains the default set of tables. +By default, this is created as a copy of pcre2_chartables.c.dist, which +contains tables for ASCII coding. However, if --enable-rebuild-chartables is +specified for ./configure, a different version of pcre2_chartables.c is built +by the program dftables (compiled from dftables.c), which uses the ANSI C +character handling functions such as isalnum(), isalpha(), isupper(), +islower(), etc. to build the table sources. This means that the default C +locale which is set for your system will control the contents of these default +tables. You can change the default tables by editing pcre2_chartables.c and +then re-building PCRE2. If you do this, you should take care to ensure that the +file does not get automatically re-generated. The best way to do this is to +move pcre2_chartables.c.dist out of the way and replace it with your customized +tables. + +When the dftables program is run as a result of --enable-rebuild-chartables, +it uses the default C locale that is set on your system. It does not pay +attention to the LC_xxx environment variables. In other words, it uses the +system's default locale rather than whatever the compiling user happens to have +set. If you really do want to build a source set of character tables in a +locale that is specified by the LC_xxx variables, you can run the dftables +program by hand with the -L option. For example: + + ./dftables -L pcre2_chartables.c.special + +The first two 256-byte tables provide lower casing and case flipping functions, +respectively. The next table consists of three 32-byte bit maps which identify +digits, "word" characters, and white space, respectively. These are used when +building 32-byte bit maps that represent character classes for code points less +than 256. The final 256-byte table has bits indicating various character types, +as follows: + + 1 white space character + 2 letter + 4 decimal digit + 8 hexadecimal digit + 16 alphanumeric or '_' + 128 regular expression metacharacter or binary zero + +You should not alter the set of characters that contain the 128 bit, as that +will cause PCRE2 to malfunction. + + +File manifest +------------- + +The distribution should contain the files listed below. + +(A) Source files for the PCRE2 library functions and their headers are found in + the src directory: + + src/dftables.c auxiliary program for building pcre2_chartables.c + when --enable-rebuild-chartables is specified + + src/pcre2_chartables.c.dist a default set of character tables that assume + ASCII coding; unless --enable-rebuild-chartables is + specified, used by copying to pcre2_chartables.c + + src/pcre2posix.c ) + src/pcre2_auto_possess.c ) + src/pcre2_compile.c ) + src/pcre2_config.c ) + src/pcre2_context.c ) + src/pcre2_dfa_match.c ) + src/pcre2_error.c ) + src/pcre2_find_bracket.c ) + src/pcre2_jit_compile.c ) + src/pcre2_jit_match.c ) sources for the functions in the library, + src/pcre2_jit_misc.c ) and some internal functions that they use + src/pcre2_maketables.c ) + src/pcre2_match.c ) + src/pcre2_match_data.c ) + src/pcre2_newline.c ) + src/pcre2_ord2utf.c ) + src/pcre2_pattern_info.c ) + src/pcre2_serialize.c ) + src/pcre2_string_utils.c ) + src/pcre2_study.c ) + src/pcre2_substitute.c ) + src/pcre2_substring.c ) + src/pcre2_tables.c ) + src/pcre2_ucd.c ) + src/pcre2_valid_utf.c ) + src/pcre2_xclass.c ) + + src/pcre2_printint.c debugging function that is used by pcre2test, + + src/config.h.in template for config.h, when built by "configure" + src/pcre2.h.in template for pcre2.h when built by "configure" + src/pcre2posix.h header for the external POSIX wrapper API + src/pcre2_internal.h header for internal use + src/pcre2_intmodedep.h a mode-specific internal header + src/pcre2_ucp.h header for Unicode property handling + + sljit/* source files for the JIT compiler + +(B) Source files for programs that use PCRE2: + + src/pcre2demo.c simple demonstration of coding calls to PCRE2 + src/pcre2grep.c source of a grep utility that uses PCRE2 + src/pcre2test.c comprehensive test program + src/pcre2_printint.c part of pcre2test + src/pcre2_jit_test.c JIT test program + +(C) Auxiliary files: + + 132html script to turn "man" pages into HTML + AUTHORS information about the author of PCRE2 + ChangeLog log of changes to the code + CleanTxt script to clean nroff output for txt man pages + Detrail script to remove trailing spaces + HACKING some notes about the internals of PCRE2 + INSTALL generic installation instructions + LICENCE conditions for the use of PCRE2 + COPYING the same, using GNU's standard name + Makefile.in ) template for Unix Makefile, which is built by + ) "configure" + Makefile.am ) the automake input that was used to create + ) Makefile.in + NEWS important changes in this release + NON-AUTOTOOLS-BUILD notes on building PCRE2 without using autotools + PrepareRelease script to make preparations for "make dist" + README this file + RunTest a Unix shell script for running tests + RunGrepTest a Unix shell script for pcre2grep tests + aclocal.m4 m4 macros (generated by "aclocal") + config.guess ) files used by libtool, + config.sub ) used only when building a shared library + configure a configuring shell script (built by autoconf) + configure.ac ) the autoconf input that was used to build + ) "configure" and config.h + depcomp ) script to find program dependencies, generated by + ) automake + doc/*.3 man page sources for PCRE2 + doc/*.1 man page sources for pcre2grep and pcre2test + doc/index.html.src the base HTML page + doc/html/* HTML documentation + doc/pcre2.txt plain text version of the man pages + doc/pcre2test.txt plain text documentation of test program + install-sh a shell script for installing files + libpcre2-8.pc.in template for libpcre2-8.pc for pkg-config + libpcre2-16.pc.in template for libpcre2-16.pc for pkg-config + libpcre2-32.pc.in template for libpcre2-32.pc for pkg-config + libpcre2posix.pc.in template for libpcre2posix.pc for pkg-config + ltmain.sh file used to build a libtool script + missing ) common stub for a few missing GNU programs while + ) installing, generated by automake + mkinstalldirs script for making install directories + perltest.sh Script for running a Perl test program + pcre2-config.in source of script which retains PCRE2 information + testdata/testinput* test data for main library tests + testdata/testoutput* expected test results + testdata/grep* input and output for pcre2grep tests + testdata/* other supporting test files + +(D) Auxiliary files for cmake support + + cmake/COPYING-CMAKE-SCRIPTS + cmake/FindPackageHandleStandardArgs.cmake + cmake/FindEditline.cmake + cmake/FindReadline.cmake + CMakeLists.txt + config-cmake.h.in + +(E) Auxiliary files for building PCRE2 "by hand" + + pcre2.h.generic ) a version of the public PCRE2 header file + ) for use in non-"configure" environments + config.h.generic ) a version of config.h for use in non-"configure" + ) environments + +Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk +Last updated: 16 October 2015 diff --git a/pcre2/RunGrepTest b/pcre2/RunGrepTest new file mode 100755 index 000000000..67d672ba3 --- /dev/null +++ b/pcre2/RunGrepTest @@ -0,0 +1,633 @@ +#! /bin/sh + +# Run pcre2grep tests. The assumption is that the PCRE2 tests check the library +# itself. What we are checking here is the file handling and options that are +# supported by pcre2grep. This script must be run in the build directory. + +# Set the C locale, so that sort(1) behaves predictably. + +LC_ALL=C +export LC_ALL + +# Remove any non-default colouring and aliases that the caller may have set. + +unset PCRE2GREP_COLOUR PCRE2GREP_COLOR +unset cp ls mv rm + +# Remember the current (build) directory, set the program to be tested, and +# valgrind settings when requested. + +builddir=`pwd` +pcre2grep=$builddir/pcre2grep +pcre2test=$builddir/pcre2test + +if [ ! -x $pcre2grep ] ; then + echo "** $pcre2grep does not exist or is not execuatble." + exit 1 +fi + +if [ ! -x $pcre2test ] ; then + echo "** $pcre2test does not exist or is not execuatble." + exit 1 +fi + +valgrind= +while [ $# -gt 0 ] ; do + case $1 in + valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; + *) echo "RunGrepTest: Unknown argument $1"; exit 1;; + esac + shift +done + +pcre2grep_version=`$pcre2grep -V` +if [ "$valgrind" = "" ] ; then + echo "Testing $pcre2grep_version" +else + echo "Testing $pcre2grep_version using valgrind" +fi + +# Set up a suitable "diff" command for comparison. Some systems have a diff +# that lacks a -u option. Try to deal with this; better do the test for the -b +# option as well. + +cf="diff" +diff -b /dev/null /dev/null 2>/dev/null && cf="diff -b" +diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" +diff -ub /dev/null /dev/null 2>/dev/null && cf="diff -ub" + +# If this test is being run from "make check", $srcdir will be set. If not, set +# it to the current or parent directory, whichever one contains the test data. +# Subsequently, we run most of the pcre2grep tests in the source directory so +# that the file names in the output are always the same. + +if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then + if [ -d "./testdata" ] ; then + srcdir=. + elif [ -d "../testdata" ] ; then + srcdir=.. + else + echo "Cannot find the testdata directory" + exit 1 + fi +fi + +# Check for the availability of UTF-8 support + +$pcre2test -C unicode >/dev/null +utf8=$? + +# Check default newline convention. If it does not include LF, force LF. + +nl=`$pcre2test -C newline` +if [ "$nl" != "LF" -a "$nl" != "ANY" -a "$nl" != "ANYCRLF" ]; then + pcre2grep="$pcre2grep -N LF" + echo "Default newline setting forced to LF" +fi + +# ------ Function to run and check a special pcre2grep arguments test ------- + +checkspecial() + { + $valgrind $pcre2grep $1 >>testtrygrep 2>&1 + if [ $? -ne $2 ] ; then + echo "** pcre2grep $1 failed - check testtrygrep" + exit 1 + fi + } + +# ------ Normal tests ------ + +echo "Testing pcre2grep main features" + +echo "---------------------------- Test 1 ------------------------------" >testtrygrep +(cd $srcdir; $valgrind $pcre2grep PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 2 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep '^PATTERN' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 3 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 4 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -ic PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 5 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 6 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 7 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 8 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 9 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 10 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 11 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -vn pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 12 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -ix pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 13 -----------------------------" >>testtrygrep +echo seventeen >testtemp1grep +(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 14 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 15 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 16 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 17 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 18 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 19 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 20 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 21 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -nA3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 22 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -nB3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 23 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -C3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 24 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -A9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 25 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -nB9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 26 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 27 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -A10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 28 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -nB10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 29 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 30 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 31 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 32 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 33 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 34 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 35 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 36 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 37 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep +echo "RC=$?" >>testtrygrep +echo "======== STDERR ========" >>testtrygrep +cat teststderrgrep >>testtrygrep + +echo "---------------------------- Test 38 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep '>\x00<' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 39 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 40 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 41 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 42 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 43 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 44 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 45 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 46 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 47 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Fx "AB.VE +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 48 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -F "AB.VE +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 49 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -F -e DATA -e "AB.VE +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 50 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 51 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 52 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --colour=always jumps ./testdata/grepinputv) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 53 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 54 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 55 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 56 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -c lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 57 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -c -l lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 58 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --regex=PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 59 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 60 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --regex PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 61 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --regexp PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 62 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 63 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 64 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 65 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 66 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 67 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 68 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 69 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 70 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 71 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 72 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 73 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 74 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 75 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 76 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 77 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 78 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 79 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 80 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 81 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 82 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 83 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 84 -----------------------------" >>testtrygrep +echo testdata/grepinput3 >testtemp1grep +(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 85 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 86 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 87 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 88 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 89 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 90 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 91 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 92 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 93 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 94 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 95 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 96 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 97 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >>testtemp1grep +(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 98 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >>testtemp1grep +(cd $srcdir; $valgrind $pcre2grep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 99 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >testtemp2grep +(cd $srcdir; $valgrind $pcre2grep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 100 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 101 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 102 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 103 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 104 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 105 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 106 -----------------------------" >>testtrygrep +(cd $srcdir; echo "a" | $valgrind $pcre2grep -M "|a" ) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 107 -----------------------------" >>testtrygrep +echo "a" >testtemp1grep +echo "aaaaa" >>testtemp1grep +(cd $srcdir; $valgrind $pcre2grep --line-offsets '(?<=\Ka)' $builddir/testtemp1grep) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 108 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -lq PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 109 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcre2grep -cq lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +# Now compare the results. + +$cf $srcdir/testdata/grepoutput testtrygrep +if [ $? != 0 ] ; then exit 1; fi + + +# These tests require UTF-8 support + +if [ $utf8 -ne 0 ] ; then + echo "Testing pcre2grep UTF-8 features" + + echo "---------------------------- Test U1 ------------------------------" >testtrygrep + (cd $srcdir; $valgrind $pcre2grep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep + echo "RC=$?" >>testtrygrep + + echo "---------------------------- Test U2 ------------------------------" >>testtrygrep + (cd $srcdir; $valgrind $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep + echo "RC=$?" >>testtrygrep + + echo "---------------------------- Test U3 ------------------------------" >>testtrygrep + (cd $srcdir; $valgrind $pcre2grep --line-offsets -u --newline=any '(?<=\K\x{17f})' ./testdata/grepinput8) >>testtrygrep + echo "RC=$?" >>testtrygrep + + $cf $srcdir/testdata/grepoutput8 testtrygrep + if [ $? != 0 ] ; then exit 1; fi + +else + echo "Skipping pcre2grep UTF-8 tests: no UTF-8 support in PCRE2 library" +fi + + +# We go to some contortions to try to ensure that the tests for the various +# newline settings will work in environments where the normal newline sequence +# is not \n. Do not use exported files, whose line endings might be changed. +# Instead, create an input file using printf so that its contents are exactly +# what we want. Note the messy fudge to get printf to write a string that +# starts with a hyphen. These tests are run in the build directory. + +echo "Testing pcre2grep newline settings" +printf "abc\rdef\r\nghi\njkl" >testNinputgrep + +printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtrygrep +$valgrind $pcre2grep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep + +printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcre2grep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep + +printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtrygrep +pattern=`printf 'def\rjkl'` +$valgrind $pcre2grep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep + +printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcre2grep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep + +printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcre2grep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep + +printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep + +$cf $srcdir/testdata/grepoutputN testtrygrep +if [ $? != 0 ] ; then exit 1; fi + + +# Finally, some tests to exercise code that is not tested above, just to be +# sure that it runs OK. Doing this improves the coverage statistics. The output +# is not checked. + +echo "Testing miscellaneous pcre2grep arguments (unchecked)" +echo '' >testtrygrep +checkspecial '-xxxxx' 2 +checkspecial '--help' 0 +checkspecial '--line-buffered --colour=auto abc /dev/null' 1 + +# Clean up local working files +rm -f testNinputgrep teststderrgrep testtrygrep testtemp1grep testtemp2grep + +exit 0 + +# End diff --git a/pcre2/RunTest b/pcre2/RunTest new file mode 100755 index 000000000..36dc638ed --- /dev/null +++ b/pcre2/RunTest @@ -0,0 +1,850 @@ +#! /bin/sh + +############################################################################### +# Run the PCRE2 tests using the pcre2test program. The appropriate tests are +# selected, depending on which build-time options were used. +# +# When JIT support is available, all appropriate tests are run with and without +# JIT, unless "-nojit" is given on the command line. There are also two tests +# for JIT-specific features, one to be run when JIT support is available +# (unless "-nojit" is specified), and one when it is not. +# +# Whichever of the 8-, 16- and 32-bit libraries exist are tested. It is also +# possible to select which to test by giving "-8", "-16" or "-32" on the +# command line. +# +# As well as "-nojit", "-8", "-16", and "-32", arguments for this script are +# individual test numbers, ranges of tests such as 3-6 or 3- (meaning 3 to the +# end), or a number preceded by ~ to exclude a test. For example, "3-15 ~10" +# runs tests 3 to 15, excluding test 10, and just "~10" runs all the tests +# except test 10. Whatever order the arguments are in, the tests are always run +# in numerical order. +# +# Inappropriate tests are automatically skipped (with a comment to say so). For +# example, if JIT support is not compiled, test 16 is skipped, whereas if JIT +# support is compiled, test 15 is skipped. +# +# Other arguments can be one of the words "-valgrind", "-valgrind-log", or +# "-sim" followed by an argument to run cross-compiled executables under a +# simulator, for example: +# +# RunTest 3 -sim "qemu-arm -s 8388608" +# +# For backwards compatibility, -nojit, -valgrind, -valgrind-log, and -sim may +# be given without the leading "-" character. +# +# When PCRE2 is compiled by clang with -fsanitize arguments, some tests need +# very much more stack than normal. In environments where the stack can be +# set at runtime, -bigstack sets a gigantic stack. +# +# There are two special cases where only one argument is allowed: +# +# If the first and only argument is "ebcdic", the script runs the special +# EBCDIC test that can be useful for checking certain EBCDIC features, even +# when run in an ASCII environment. PCRE2 must be built with EBCDIC support for +# this test to be run. +# +# If the script is obeyed as "RunTest list", a list of available tests is +# output, but none of them are run. +############################################################################### + +# Define test titles in variables so that they can be output as a list. Some +# of them are modified (e.g. with -8 or -16) when used in the actual tests. + +title0="Test 0: Unchecked pcre2test argument tests (to improve coverage)" +title1="Test 1: Main non-UTF, non-UCP functionality (compatible with Perl >= 5.10)" +title2="Test 2: API, errors, internals, and non-Perl stuff" +title3="Test 3: Locale-specific features" +title4A="Test 4: UTF" +title4B=" and Unicode property support (compatible with Perl >= 5.10)" +title5A="Test 5: API, internals, and non-Perl stuff for UTF" +title5B=" and UCP support" +title6="Test 6: DFA matching main non-UTF, non-UCP functionality" +title7A="Test 7: DFA matching with UTF" +title7B=" and Unicode property support" +title8="Test 8: Internal offsets and code size tests" +title9="Test 9: Specials for the basic 8-bit library" +title10="Test 10: Specials for the 8-bit library with UTF-8 and UCP support" +title11="Test 11: Specials for the basic 16-bit and 32-bit libraries" +title12="Test 12: Specials for the 16-bit and 32-bit libraries UTF and UCP support" +title13="Test 13: DFA specials for the basic 16-bit and 32-bit libraries" +title14="Test 14: DFA specials for UTF and UCP support" +title15="Test 15: Non-JIT limits and other non-JIT tests" +title16="Test 16: JIT-specific features when JIT is not available" +title17="Test 17: JIT-specific features when JIT is available" +title18="Test 18: Tests of the POSIX interface, excluding UTF/UCP" +title19="Test 19: Tests of the POSIX interface with UTF/UCP" +title20="Test 20: Serialization tests" +title21="Test 21: \C tests without UTF (supported for DFA matching)" +title22="Test 22: \C tests with UTF (not supported for DFA matching)" +title23="Test 23: \C disabled test" +maxtest=23 + +if [ $# -eq 1 -a "$1" = "list" ]; then + echo $title0 + echo $title1 + echo $title2 "(not UTF or UCP)" + echo $title3 + echo $title4A $title4B + echo $title5A $title5B + echo $title6 + echo $title7A $title7B + echo $title8 + echo $title9 + echo $title10 + echo $title11 + echo $title12 + echo $title13 + echo $title14 + echo $title15 + echo $title16 + echo $title17 + echo $title18 + echo $title19 + echo $title20 + echo $title21 + echo $title22 + echo $title23 + exit 0 +fi + +# Set up a suitable "diff" command for comparison. Some systems +# have a diff that lacks a -u option. Try to deal with this. + +cf="diff" +diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" + +# Find the test data + +if [ -n "$srcdir" -a -d "$srcdir" ] ; then + testdata="$srcdir/testdata" +elif [ -d "./testdata" ] ; then + testdata=./testdata +elif [ -d "../testdata" ] ; then + testdata=../testdata +else + echo "Cannot find the testdata directory" + exit 1 +fi + + +# ------ Function to check results of a test ------- + +# This function is called with three parameters: +# +# $1 the value of $? after a call to pcre2test +# $2 the suffix of the output file to compare with +# $3 the $opt value (empty, -jit, or -dfa) +# +# Note: must define using name(), not "function name", for Solaris. + +checkresult() + { + if [ $1 -ne 0 ] ; then + echo "** pcre2test failed - check testtry" + exit 1 + fi + case "$3" in + -jit) with=" with JIT";; + -dfa) with=" with DFA";; + *) with="";; + esac + $cf $testdata/testoutput$2 testtry + if [ $? != 0 ] ; then + echo "" + echo "** Test $2 failed$with" + exit 1 + fi + echo " OK$with" + } + + +# ------ Function to run and check a special pcre2test arguments test ------- + +checkspecial() + { + $valgrind $vjs ./pcre2test $1 >>testtry + if [ $? -ne 0 ] ; then + echo "** pcre2test $1 failed - check testtry" + exit 1 + fi + } + + +# ------ Special EBCDIC Test ------- + +if [ $# -eq 1 -a "$1" = "ebcdic" ]; then + $valgrind ./pcre2test -C ebcdic >/dev/null + ebcdic=$? + if [ $ebcdic -ne 1 ] ; then + echo "Cannot run EBCDIC tests: EBCDIC support not compiled" + exit 1 + fi + for opt in "" "-dfa"; do + ./pcre2test -q $opt $testdata/testinputEBC >testtry + checkresult $? EBC "$opt" + done +exit 0 +fi + + +# ------ Normal Tests ------ + +# Default values + +arg8= +arg16= +arg32= +nojit= +bigstack= +sim= +skip= +valgrind= +vjs= + +# This is in case the caller has set aliases (as I do - PH) +unset cp ls mv rm + +# Process options and select which tests to run; for those that are explicitly +# requested, check that the necessary optional facilities are available. + +do0=no +do1=no +do2=no +do3=no +do4=no +do5=no +do6=no +do7=no +do8=no +do9=no +do10=no +do11=no +do12=no +do13=no +do14=no +do15=no +do16=no +do17=no +do18=no +do19=no +do20=no +do21=no +do22=no +do23=no + +while [ $# -gt 0 ] ; do + case $1 in + 0) do0=yes;; + 1) do1=yes;; + 2) do2=yes;; + 3) do3=yes;; + 4) do4=yes;; + 5) do5=yes;; + 6) do6=yes;; + 7) do7=yes;; + 8) do8=yes;; + 9) do9=yes;; + 10) do10=yes;; + 11) do11=yes;; + 12) do12=yes;; + 13) do13=yes;; + 14) do14=yes;; + 15) do15=yes;; + 16) do16=yes;; + 17) do17=yes;; + 18) do18=yes;; + 19) do19=yes;; + 20) do20=yes;; + 21) do21=yes;; + 22) do22=yes;; + 23) do23=yes;; + -8) arg8=yes;; + -16) arg16=yes;; + -32) arg32=yes;; + bigstack|-bigstack) bigstack=yes;; + nojit|-nojit) nojit=yes;; + sim|-sim) shift; sim=$1;; + valgrind|-valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all";; + valgrind-log|-valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all --log-file=report.%p ";; + ~*) + if expr "$1" : '~[0-9][0-9]*$' >/dev/null; then + skip="$skip `expr "$1" : '~\([0-9]*\)*$'`" + else + echo "Unknown option or test selector '$1'"; exit 1 + fi + ;; + *-*) + if expr "$1" : '[0-9][0-9]*-[0-9]*$' >/dev/null; then + tf=`expr "$1" : '\([0-9]*\)'` + tt=`expr "$1" : '.*-\([0-9]*\)'` + if [ "$tt" = "" ] ; then tt=$maxtest; fi + if expr \( "$tt" ">" "$maxtest" \) >/dev/null; then + echo "Invalid test range '$1'"; exit 1 + fi + while expr "$tf" "<=" "$tt" >/dev/null; do + eval do${tf}=yes + tf=`expr $tf + 1` + done + else + echo "Invalid test range '$1'"; exit 1 + fi + ;; + *) echo "Unknown option or test selector '$1'"; exit 1;; + esac + shift +done + +# Find which optional facilities are available. + +$sim ./pcre2test -C linksize >/dev/null +link_size=$? +if [ $link_size -lt 2 ] ; then + echo "RunTest: Failed to find internal link size" + exit 1 +fi +if [ $link_size -gt 4 ] ; then + echo "RunTest: Failed to find internal link size" + exit 1 +fi + +# If it is possible to set the system stack size, arrange to set a value for +# test 2, which needs more than the even the Linux default when PCRE2 has been +# compiled by gcc with -fsanitize=address. When the compiler is clang, sanitize +# options require an even bigger stack for test 2, and an increased stack for +# some of the other tests. + +$sim ./pcre2test -S 1 /dev/null /dev/null +if [ $? -eq 0 ] ; then + if [ "$bigstack" = "" ] ; then + test2stack="-S 16" + defaultstack="" + else + test2stack="-S 1024" + defaultstack="-S 64" + fi +else + test2stack="" + defaultstack="" +fi + +# All of 8-bit, 16-bit, and 32-bit character strings may be supported, but only +# one need be. + +$sim ./pcre2test -C pcre2-8 >/dev/null +support8=$? +$sim ./pcre2test -C pcre2-16 >/dev/null +support16=$? +$sim ./pcre2test -C pcre2-32 >/dev/null +support32=$? + +# \C may be disabled + +$sim ./pcre2test -C backslash-C >/dev/null +supportBSC=$? + +# Initialize all bitsizes skipped + +test8=skip +test16=skip +test32=skip + +# If no bitsize arguments, select all that are available + +if [ "$arg8$arg16$arg32" = "" ] ; then + if [ $support8 -ne 0 ] ; then + test8=-8 + fi + if [ $support16 -ne 0 ] ; then + test16=-16 + fi + if [ $support32 -ne 0 ] ; then + test32=-32 + fi + +# Otherwise, select requested bit sizes + +else + if [ "$arg8" = yes ] ; then + if [ $support8 -eq 0 ] ; then + echo "Cannot run 8-bit library tests: 8-bit library not compiled" + exit 1 + fi + test8=-8 + fi + if [ "$arg16" = yes ] ; then + if [ $support16 -eq 0 ] ; then + echo "Cannot run 16-bit library tests: 16-bit library not compiled" + exit 1 + fi + test16=-16 + fi + if [ "$arg32" = yes ] ; then + if [ $support32 -eq 0 ] ; then + echo "Cannot run 32-bit library tests: 32-bit library not compiled" + exit 1 + fi + test32=-32 + fi +fi + +# UTF support is implied by Unicode support, and it always applies to all bit +# sizes if both are supported; we can't have UTF-8 support without UTF-16 or +# UTF-32 support. + +$sim ./pcre2test -C unicode >/dev/null +utf=$? + +# When JIT is used with valgrind, we need to set up valgrind suppressions as +# otherwise there are a lot of false positive valgrind reports when the +# the hardware supports SSE2. + +jitopt= +$sim ./pcre2test -C jit >/dev/null +jit=$? +if [ $jit -ne 0 -a "$nojit" != "yes" ] ; then + jitopt=-jit + if [ "$valgrind" != "" ] ; then + vjs="--suppressions=$testdata/valgrind-jit.supp" + fi +fi + +# If no specific tests were requested, select all. Those that are not +# relevant will be automatically skipped. + +if [ $do0 = no -a $do1 = no -a $do2 = no -a $do3 = no -a \ + $do4 = no -a $do5 = no -a $do6 = no -a $do7 = no -a \ + $do8 = no -a $do9 = no -a $do10 = no -a $do11 = no -a \ + $do12 = no -a $do13 = no -a $do14 = no -a $do15 = no -a \ + $do16 = no -a $do17 = no -a $do18 = no -a $do19 = no -a \ + $do20 = no -a $do21 = no -a $do22 = no -a $do23 = no \ + ]; then + do0=yes + do1=yes + do2=yes + do3=yes + do4=yes + do5=yes + do6=yes + do7=yes + do8=yes + do9=yes + do10=yes + do11=yes + do12=yes + do13=yes + do14=yes + do15=yes + do16=yes + do17=yes + do18=yes + do19=yes + do20=yes + do21=yes + do22=yes + do23=yes +fi + +# Handle any explicit skips at this stage, so that an argument list may consist +# only of explicit skips. + +for i in $skip; do eval do$i=no; done + +# Show which release and which test data + +echo "" +echo PCRE2 C library tests using test data from $testdata +$sim ./pcre2test /dev/null +echo "" + +for bmode in "$test8" "$test16" "$test32"; do + case "$bmode" in + skip) continue;; + -16) if [ "$test8$test32" != "skipskip" ] ; then echo ""; fi + bits=16; echo "---- Testing 16-bit library ----"; echo "";; + -32) if [ "$test8$test16" != "skipskip" ] ; then echo ""; fi + bits=32; echo "---- Testing 32-bit library ----"; echo "";; + -8) bits=8; echo "---- Testing 8-bit library ----"; echo "";; + esac + + # Test 0 is a special test. Its output is not checked, because it will + # be different on different hardware and with different configurations. + # Running this test just exercises the code. + + if [ $do0 = yes ] ; then + echo $title0 + echo '/abc/jit,memory' >testSinput + echo ' abc' >>testSinput + echo '' >testtry + checkspecial '-C' + checkspecial '--help' + checkspecial '-S 1 -t 10 testSinput' + echo " OK" + fi + + # Primary non-UTF test, compatible with JIT and all versions of Perl >= 5.8 + + if [ $do1 = yes ] ; then + echo $title1 + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput1 testtry + checkresult $? 1 "$opt" + done + fi + + # PCRE2 tests that are not Perl-compatible: API, errors, internals + + if [ $do2 = yes ] ; then + echo $title2 "(excluding UTF-$bits)" + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $test2stack $bmode $opt $testdata/testinput2 testtry + if [ $? = 0 ] ; then + checkresult $? 2 "$opt" + else + echo " " + echo "** Test 2 requires a lot of stack. If it has crashed with a" + echo "** segmentation fault, it may be that you do not have enough" + echo "** stack available by default. Please see the 'pcre2stack' man" + echo "** page for a discussion of PCRE2's stack usage." + echo " " + exit 1 + fi + done + fi + + # Locale-specific tests, provided that either the "fr_FR", "fr_CA", "french" + # or "fr" locale is available. The first two are Unix-like standards; the + # last two are for Windows. Unfortunately, different versions of the French + # locale give different outputs for some items. This test passes if the + # output matches any one of the alternative output files. + + if [ $do3 = yes ] ; then + locale= + + # In some environments locales that are listed by the "locale -a" + # command do not seem to work with setlocale(). Therefore, we do + # a preliminary test to see if pcre2test can set one before going + # on to use it. + + for loc in 'fr_FR' 'french' 'fr' 'fr_CA'; do + locale -a | grep "^$loc\$" >/dev/null + if [ $? -eq 0 ] ; then + echo "/a/locale=$loc" | \ + $sim $valgrind ./pcre2test -q $bmode | \ + grep "Failed to set locale" >/dev/null + if [ $? -ne 0 ] ; then + locale=$loc + if [ "$locale" = "fr_FR" ] ; then + infile=$testdata/testinput3 + outfile=$testdata/testoutput3 + outfile2=$testdata/testoutput3A + outfile3=$testdata/testoutput3B + else + infile=test3input + outfile=test3output + outfile2=test3outputA + outfile3=test3outputB + sed "s/fr_FR/$loc/" $testdata/testinput3 >test3input + sed "s/fr_FR/$loc/" $testdata/testoutput3 >test3output + sed "s/fr_FR/$loc/" $testdata/testoutput3A >test3outputA + sed "s/fr_FR/$loc/" $testdata/testoutput3B >test3outputB + fi + break + fi + fi + done + + if [ "$locale" != "" ] ; then + echo $title3 "(using '$locale' locale)" + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $infile testtry + if [ $? = 0 ] ; then + case "$opt" in + -jit) with=" with JIT";; + *) with="";; + esac + if $cf $outfile testtry >teststdout || \ + $cf $outfile2 testtry >teststdout || \ + $cf $outfile3 testtry >teststdout + then + echo " OK$with" + else + echo "** Locale test did not run successfully$with. The output did not match" + echo " $outfile, $outfile2 or $outfile3." + echo " This may mean that there is a problem with the locale settings rather" + echo " than a bug in PCRE2." + exit 1 + fi + else exit 1 + fi + done + else + echo "Cannot test locale-specific features - none of the 'fr_FR', 'fr_CA'," + echo "'fr' or 'french' locales can be set, or the \"locale\" command is" + echo "not available to check for them." + echo " " + fi + fi + + # Tests for UTF and Unicode property support + + if [ $do4 = yes ] ; then + echo ${title4A}-${bits}${title4B} + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput4 testtry + checkresult $? 4 "$opt" + done + fi + fi + + if [ $do5 = yes ] ; then + echo ${title5A}-${bits}$title5B + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput5 testtry + checkresult $? 5 "$opt" + done + fi + fi + + # Tests for DFA matching support + + if [ $do6 = yes ] ; then + echo $title6 + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput6 testtry + checkresult $? 6 "" + fi + + if [ $do7 = yes ] ; then + echo ${title7A}-${bits}$title7B + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput7 testtry + checkresult $? 7 "" + fi + fi + + # Test of internal offsets and code sizes. This test is run only when there + # is UTF/UCP support. The actual tests are mostly the same as in some of the + # above, but in this test we inspect some offsets and sizes. This is a + # doublecheck for the maintainer, just in case something changes unexpectely. + # The output from this test is different in 8-bit, 16-bit, and 32-bit modes + # and for different link sizes, so there are different output files for each + # mode and link size. + + if [ $do8 = yes ] ; then + echo $title8 + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput8 testtry + checkresult $? 8-$bits-$link_size "" + fi + fi + + # Tests for 8-bit-specific features + + if [ "$do9" = yes ] ; then + echo $title9 + if [ "$bits" = "16" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-bit tests" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput9 testtry + checkresult $? 9 "$opt" + done + fi + fi + + # Tests for UTF-8 and UCP 8-bit-specific features + + if [ "$do10" = yes ] ; then + echo $title10 + if [ "$bits" = "16" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput10 testtry + checkresult $? 10 "$opt" + done + fi + fi + + # Tests for 16-bit and 32-bit features. Output is different for the two widths. + + if [ $do11 = yes ] ; then + echo $title11 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput11 testtry + checkresult $? 11-$bits "$opt" + done + fi + fi + + # Tests for 16-bit and 32-bit features with UTF-16/32 and UCP support. Output + # is different for the two widths. + + if [ $do12 = yes ] ; then + echo $title12 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput12 testtry + checkresult $? 12-$bits "$opt" + done + fi + fi + + # Tests for 16/32-bit-specific features in DFA non-UTF modes + + if [ $do13 = yes ] ; then + echo $title13 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput13 testtry + checkresult $? 13 "" + fi + fi + + # Tests for DFA UTF and UCP features. Output is different for the different widths. + + if [ $do14 = yes ] ; then + echo $title14 + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput14 testtry + checkresult $? 14-$bits "" + fi + fi + + # Test non-JIT match and recursion limits + + if [ $do15 = yes ] ; then + echo $title15 + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput15 testtry + checkresult $? 15 "" + fi + + # Test JIT-specific features when JIT is not available + + if [ $do16 = yes ] ; then + echo $title16 + if [ $jit -ne 0 ] ; then + echo " Skipped because JIT is available" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput16 testtry + checkresult $? 16 "" + fi + fi + + # Test JIT-specific features when JIT is available + + if [ $do17 = yes ] ; then + echo $title17 + if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then + echo " Skipped because JIT is not available or nojit was specified" + else + $sim $valgrind $vjs ./pcre2test -q $defaultstack $bmode $testdata/testinput17 testtry + checkresult $? 17 "" + fi + fi + + # Tests for the POSIX interface without UTF/UCP (8-bit only) + + if [ $do18 = yes ] ; then + echo $title18 + if [ "$bits" = "16" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-bit tests" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput18 testtry + checkresult $? 18 "" + fi + fi + + # Tests for the POSIX interface with UTF/UCP (8-bit only) + + if [ $do19 = yes ] ; then + echo $title19 + if [ "$bits" = "16" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput19 testtry + checkresult $? 19 "" + fi + fi + + # Serialization tests + + if [ $do20 = yes ] ; then + echo $title20 + $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput20 testtry + checkresult $? 20 "" + fi + + # \C tests without UTF - DFA matching is supported + + if [ "$do21" = yes ] ; then + echo $title21 + if [ $supportBSC -eq 0 ] ; then + echo " Skipped because \C is disabled" + else + for opt in "" $jitopt -dfa; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput21 testtry + checkresult $? 21 "$opt" + done + fi + fi + + # \C tests with UTF - DFA matching is not supported for \C in UTF mode + + if [ "$do22" = yes ] ; then + echo $title22 + if [ $supportBSC -eq 0 ] ; then + echo " Skipped because \C is disabled" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" $jitopt; do + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput22 testtry + checkresult $? 22-$bits "$opt" + done + fi + fi + + # Test when \C is disabled + + if [ "$do23" = yes ] ; then + echo $title23 + if [ $supportBSC -ne 0 ] ; then + echo " Skipped because \C is not disabled" + else + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput23 testtry + checkresult $? 23 "" + fi + fi + +# End of loop for 8/16/32-bit tests +done + +# Clean up local working files +rm -f testSinput test3input testsaved1 testsaved2 test3output test3outputA test3outputB teststdout teststderr testtry + +# End diff --git a/pcre2/aclocal.m4 b/pcre2/aclocal.m4 new file mode 100644 index 000000000..795657e89 --- /dev/null +++ b/pcre2/aclocal.m4 @@ -0,0 +1,1531 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_pthread.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/pcre2_visibility.m4]) diff --git a/pcre2/ar-lib b/pcre2/ar-lib new file mode 100755 index 000000000..463b9ec02 --- /dev/null +++ b/pcre2/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2014 Free Software Foundation, Inc. +# Written by Peter Rosin . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <_FOUND variable. +# The package is found if all variables listed are TRUE. +# Example: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, the location is reported using the VAR1 argument, so +# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. +# If the second argument is DEFAULT_MSG, the message in the failure case will +# be "Could NOT find LibXml2", if you don't like this message you can specify +# your own custom failure message there. + +MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) + + IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + IF (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") + ELSE (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") + ENDIF (${_NAME}_FIND_REQUIRED) + ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + SET(_FAIL_MESSAGE "${_FAIL_MSG}") + ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + + SET(${_NAME_UPPER}_FOUND TRUE) + IF(NOT ${_VAR1}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_VAR1}) + + FOREACH(_CURRENT_VAR ${ARGN}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + IF (${_NAME_UPPER}_FOUND) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ELSE (${_NAME_UPPER}_FOUND) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_FAIL_MESSAGE}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) + ENDIF (${_NAME_UPPER}_FOUND) +ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) diff --git a/pcre2/cmake/FindReadline.cmake b/pcre2/cmake/FindReadline.cmake new file mode 100644 index 000000000..1d4cc5584 --- /dev/null +++ b/pcre2/cmake/FindReadline.cmake @@ -0,0 +1,29 @@ +# from http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/FindReadline.cmake +# http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/COPYING-CMAKE-SCRIPTS +# --> BSD licensed +# +# GNU Readline library finder +if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) + set(READLINE_FOUND TRUE) +else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) + FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h + /usr/include/readline + ) + +# 2008-04-22 The next clause used to read like this: +# +# FIND_LIBRARY(READLINE_LIBRARY NAMES readline) +# FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses ) +# include(FindPackageHandleStandardArgs) +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY ) +# +# I was advised to modify it such that it will find an ncurses library if +# required, but not if one was explicitly given, that is, it allows the +# default to be overridden. PH + + FIND_LIBRARY(READLINE_LIBRARY NAMES readline) + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY ) + + MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY) +endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) diff --git a/pcre2/compile b/pcre2/compile new file mode 100755 index 000000000..a85b723c7 --- /dev/null +++ b/pcre2/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/pcre2/config-cmake.h.in b/pcre2/config-cmake.h.in new file mode 100644 index 000000000..0cfd8b134 --- /dev/null +++ b/pcre2/config-cmake.h.in @@ -0,0 +1,48 @@ +/* config.h for CMake builds */ + +#cmakedefine HAVE_DIRENT_H 1 +#cmakedefine HAVE_INTTYPES_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_STRERROR 1 +#cmakedefine HAVE_SYS_STAT_H 1 +#cmakedefine HAVE_SYS_TYPES_H 1 +#cmakedefine HAVE_UNISTD_H 1 +#cmakedefine HAVE_WINDOWS_H 1 + +#cmakedefine HAVE_BCOPY 1 +#cmakedefine HAVE_MEMMOVE 1 + +#cmakedefine PCRE2_STATIC 1 + +#cmakedefine SUPPORT_PCRE2_8 1 +#cmakedefine SUPPORT_PCRE2_16 1 +#cmakedefine SUPPORT_PCRE2_32 1 +#cmakedefine PCRE2_DEBUG 1 + +#cmakedefine SUPPORT_LIBBZ2 1 +#cmakedefine SUPPORT_LIBEDIT 1 +#cmakedefine SUPPORT_LIBREADLINE 1 +#cmakedefine SUPPORT_LIBZ 1 + +#cmakedefine SUPPORT_JIT 1 +#cmakedefine SUPPORT_PCRE2GREP_JIT 1 +#cmakedefine SUPPORT_UNICODE 1 +#cmakedefine SUPPORT_VALGRIND 1 + +#cmakedefine BSR_ANYCRLF 1 +#cmakedefine EBCDIC 1 +#cmakedefine EBCDIC_NL25 1 +#cmakedefine HEAP_MATCH_RECURSE 1 +#cmakedefine NEVER_BACKSLASH_C 1 + +#define LINK_SIZE @PCRE2_LINK_SIZE@ +#define MATCH_LIMIT @PCRE2_MATCH_LIMIT@ +#define MATCH_LIMIT_RECURSION @PCRE2_MATCH_LIMIT_RECURSION@ +#define NEWLINE_DEFAULT @NEWLINE_DEFAULT@ +#define PARENS_NEST_LIMIT @PCRE2_PARENS_NEST_LIMIT@ +#define PCRE2GREP_BUFSIZE @PCRE2GREP_BUFSIZE@ + +#define MAX_NAME_SIZE 32 +#define MAX_NAME_COUNT 10000 + +/* end config.h for CMake builds */ diff --git a/pcre2/config.guess b/pcre2/config.guess new file mode 100755 index 000000000..6c32c8645 --- /dev/null +++ b/pcre2/config.guess @@ -0,0 +1,1421 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-11-04' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/pcre2/config.sub b/pcre2/config.sub new file mode 100755 index 000000000..7ffe37378 --- /dev/null +++ b/pcre2/config.sub @@ -0,0 +1,1807 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-12-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/pcre2/configure b/pcre2/configure new file mode 100755 index 000000000..ad2696549 --- /dev/null +++ b/pcre2/configure @@ -0,0 +1,18296 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for PCRE2 10.21. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='PCRE2' +PACKAGE_TARNAME='pcre2' +PACKAGE_VERSION='10.21' +PACKAGE_STRING='PCRE2 10.21' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="src/pcre2.h.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +WITH_GCOV_FALSE +WITH_GCOV_TRUE +GCOV_LIBS +GCOV_CXXFLAGS +GCOV_CFLAGS +GENHTML +LCOV +SHTOOL +VALGRIND_LIBS +VALGRIND_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +LIBBZ2 +LIBZ +DISTCHECK_CONFIGURE_FLAGS +EXTRA_LIBPCRE2_POSIX_LDFLAGS +EXTRA_LIBPCRE2_32_LDFLAGS +EXTRA_LIBPCRE2_16_LDFLAGS +EXTRA_LIBPCRE2_8_LDFLAGS +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +ax_pthread_config +PCRE2_STATIC_CFLAG +LIBREADLINE +WITH_VALGRIND_FALSE +WITH_VALGRIND_TRUE +WITH_UNICODE_FALSE +WITH_UNICODE_TRUE +WITH_JIT_FALSE +WITH_JIT_TRUE +WITH_REBUILD_CHARTABLES_FALSE +WITH_REBUILD_CHARTABLES_TRUE +WITH_DEBUG_FALSE +WITH_DEBUG_TRUE +WITH_PCRE2_32_FALSE +WITH_PCRE2_32_TRUE +WITH_PCRE2_16_FALSE +WITH_PCRE2_16_TRUE +WITH_PCRE2_8_FALSE +WITH_PCRE2_8_TRUE +enable_pcre2_32 +enable_pcre2_16 +enable_pcre2_8 +PCRE2_DATE +PCRE2_PRERELEASE +PCRE2_MINOR +PCRE2_MAJOR +HAVE_VISIBILITY +VISIBILITY_CXXFLAGS +VISIBILITY_CFLAGS +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +ac_ct_AR +AR +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_pcre8 +enable_pcre16 +enable_pcre32 +enable_pcre2_8 +enable_pcre2_16 +enable_pcre2_32 +enable_debug +enable_jit +enable_pcre2grep_jit +enable_rebuild_chartables +enable_unicode +enable_newline_is_cr +enable_newline_is_lf +enable_newline_is_crlf +enable_newline_is_anycrlf +enable_newline_is_any +enable_bsr_anycrlf +enable_never_backslash_C +enable_ebcdic +enable_ebcdic_nl25 +enable_stack_for_recursion +enable_pcre2grep_libz +enable_pcre2grep_libbz2 +with_pcre2grep_bufsize +enable_pcre2test_libedit +enable_pcre2test_libreadline +with_link_size +with_parens_nest_limit +with_match_limit +with_match_limit_recursion +enable_valgrind +enable_coverage +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +LT_SYS_LIBRARY_PATH +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +VALGRIND_CFLAGS +VALGRIND_LIBS +LCOV +GENHTML' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures PCRE2 10.21 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/pcre2] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of PCRE2 10.21:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + + --disable-pcre2-8 disable 8 bit character support + --enable-pcre2-16 enable 16 bit character support + --enable-pcre2-32 enable 32 bit character support + --enable-debug enable debugging code + --enable-jit enable Just-In-Time compiling support + --disable-pcre2grep-jit disable JIT support in pcre2grep + --enable-rebuild-chartables + rebuild character tables in current locale + --disable-unicode disable Unicode support + --enable-newline-is-cr use CR as newline character + --enable-newline-is-lf use LF as newline character (default) + --enable-newline-is-crlf + use CRLF as newline sequence + --enable-newline-is-anycrlf + use CR, LF, or CRLF as newline sequence + --enable-newline-is-any use any valid Unicode newline sequence + --enable-bsr-anycrlf \R matches only CR, LF, CRLF by default + --enable-never-backslash-C + use of \C causes an error + --enable-ebcdic assume EBCDIC coding rather than ASCII; incompatible + with --enable-utf; use only in (uncommon) EBCDIC + environments; it implies --enable-rebuild-chartables + --enable-ebcdic-nl25 set EBCDIC code for NL to 0x25 instead of 0x15; it + implies --enable-ebcdic + --disable-stack-for-recursion + don't use stack recursion when matching + --enable-pcre2grep-libz link pcre2grep with libz to handle .gz files + --enable-pcre2grep-libbz2 + link pcre2grep with libbz2 to handle .bz2 files + --enable-pcre2test-libedit + link pcre2test with libedit + --enable-pcre2test-libreadline + link pcre2test with libreadline + --enable-valgrind valgrind support + --enable-coverage enable code coverage reports using gcov + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-pcre2grep-bufsize=N + pcre2grep buffer size (default=20480, minimum=8192) + --with-link-size=N internal link size (2, 3, or 4 allowed; default=2) + --with-parens-nest-limit=N + nested parentheses limit (default=250) + --with-match-limit=N default limit on internal looping (default=10000000) + --with-match-limit-recursion=N + default limit on internal recursion + (default=MATCH_LIMIT) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + VALGRIND_CFLAGS + C compiler flags for VALGRIND, overriding pkg-config + VALGRIND_LIBS + linker flags for VALGRIND, overriding pkg-config + LCOV the ltp lcov program + GENHTML the ltp genhtml program + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +PCRE2 configure 10.21 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by PCRE2 $as_me 10.21, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='pcre2' + VERSION='10.21' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +ac_config_headers="$ac_config_headers src/config.h" + + +# FISH PATCH +# Enable maintainer mode to avoid spurious rebuilds due to timestamps in git +# not being stored. Discussion in https://github.com/fish-shell/fish-shell/issues/2469 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +# END FISH PATCH + +# This is a new thing required to stop a warning from automake 1.12 +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + + +# This was added at the suggestion of libtoolize (03-Jan-10) + + +# The default CFLAGS in Autoconf are "-g -O2" for gcc and just "-g" for any +# other compiler. There doesn't seem to be a standard way of getting rid of the +# -g (which I don't think is needed for a production library). This fudge seems +# to achieve the necessary. First, we remember the externally set values of +# CFLAGS. Then call the AC_PROG_CC macro to find the compiler - if CFLAGS is +# not set, it will be set to Autoconf's defaults. Afterwards, if the original +# values were not set, remove the -g from the Autoconf defaults. + +remember_set_CFLAGS="$CFLAGS" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + +if test "x$remember_set_CFLAGS" = "x" +then + if test "$CFLAGS" = "-g -O2" + then + CFLAGS="-O2" + elif test "$CFLAGS" = "-g" + then + CFLAGS="" + fi +fi + +# Check for a 64-bit integer type +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +# Check for GCC visibility feature + + + + VISIBILITY_CFLAGS= + VISIBILITY_CXXFLAGS= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the -Werror option is usable" >&5 +$as_echo_n "checking whether the -Werror option is usable... " >&6; } + if ${pcre2_cv_cc_vis_werror+:} false; then : + $as_echo_n "(cached) " >&6 +else + + pcre2_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pcre2_cv_cc_vis_werror=yes +else + pcre2_cv_cc_vis_werror=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$pcre2_save_CFLAGS" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre2_cv_cc_vis_werror" >&5 +$as_echo "$pcre2_cv_cc_vis_werror" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for simple visibility declarations" >&5 +$as_echo_n "checking for simple visibility declarations... " >&6; } + if ${pcre2_cv_cc_visibility+:} false; then : + $as_echo_n "(cached) " >&6 +else + + pcre2_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + if test $pcre2_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pcre2_cv_cc_visibility=yes +else + pcre2_cv_cc_visibility=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$pcre2_save_CFLAGS" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre2_cv_cc_visibility" >&5 +$as_echo "$pcre2_cv_cc_visibility" >&6; } + if test $pcre2_cv_cc_visibility = yes; then + VISIBILITY_CFLAGS="-fvisibility=hidden" + VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" + HAVE_VISIBILITY=1 + +$as_echo "#define PCRE2_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRE2_EXP_DEFN __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRE2POSIX_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRE2POSIX_EXP_DEFN extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + fi + fi + + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_VISIBILITY $HAVE_VISIBILITY +_ACEOF + + + +# Versioning + +PCRE2_MAJOR="10" +PCRE2_MINOR="21" +PCRE2_PRERELEASE="" +PCRE2_DATE="2016-01-12" + +if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09" +then + echo "***" + echo "*** Minor version number $PCRE2_MINOR must not be used. ***" + echo "*** Use only 00 to 07 or 10 onwards, to avoid octal issues. ***" + echo "***" + exit 1 +fi + + + + + + +# Set a more sensible default value for $(htmldir). +if test "x$htmldir" = 'x${docdir}' +then + htmldir='${docdir}/html' +fi + +# Force an error for PCRE1 size options +# Check whether --enable-pcre8 was given. +if test "${enable_pcre8+set}" = set; then : + enableval=$enable_pcre8; +else + enable_pcre8=no +fi + +# Check whether --enable-pcre16 was given. +if test "${enable_pcre16+set}" = set; then : + enableval=$enable_pcre16; +else + enable_pcre16=no +fi + +# Check whether --enable-pcre32 was given. +if test "${enable_pcre32+set}" = set; then : + enableval=$enable_pcre32; +else + enable_pcre32=no +fi + + +if test "$enable_pcre8$enable_pcre16$enable_pcre32" != "nonono" +then + echo "** ERROR: Use --[en|dis]able-pcre2-[8|16|32], not --[en|dis]able-pcre[8|16|32]" + exit 1 +fi + +# Handle --disable-pcre2-8 (enabled by default) +# Check whether --enable-pcre2-8 was given. +if test "${enable_pcre2_8+set}" = set; then : + enableval=$enable_pcre2_8; +else + enable_pcre2_8=unset +fi + + + +# Handle --enable-pcre2-16 (disabled by default) +# Check whether --enable-pcre2-16 was given. +if test "${enable_pcre2_16+set}" = set; then : + enableval=$enable_pcre2_16; +else + enable_pcre2_16=unset +fi + + + +# Handle --enable-pcre2-32 (disabled by default) +# Check whether --enable-pcre2-32 was given. +if test "${enable_pcre2_32+set}" = set; then : + enableval=$enable_pcre2_32; +else + enable_pcre2_32=unset +fi + + + +# Handle --dnable-debug (disabled by default) +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug=no +fi + + +# Handle --enable-jit (disabled by default) +# Check whether --enable-jit was given. +if test "${enable_jit+set}" = set; then : + enableval=$enable_jit; +else + enable_jit=no +fi + + +# Handle --disable-pcre2grep-jit (enabled by default) +# Check whether --enable-pcre2grep-jit was given. +if test "${enable_pcre2grep_jit+set}" = set; then : + enableval=$enable_pcre2grep_jit; +else + enable_pcre2grep_jit=yes +fi + + +# Handle --enable-rebuild-chartables +# Check whether --enable-rebuild-chartables was given. +if test "${enable_rebuild_chartables+set}" = set; then : + enableval=$enable_rebuild_chartables; +else + enable_rebuild_chartables=no +fi + + +# Handle --disable-unicode (enabled by default) +# Check whether --enable-unicode was given. +if test "${enable_unicode+set}" = set; then : + enableval=$enable_unicode; +else + enable_unicode=unset +fi + + +# Handle newline options +ac_pcre2_newline=lf +# Check whether --enable-newline-is-cr was given. +if test "${enable_newline_is_cr+set}" = set; then : + enableval=$enable_newline_is_cr; ac_pcre2_newline=cr +fi + +# Check whether --enable-newline-is-lf was given. +if test "${enable_newline_is_lf+set}" = set; then : + enableval=$enable_newline_is_lf; ac_pcre2_newline=lf +fi + +# Check whether --enable-newline-is-crlf was given. +if test "${enable_newline_is_crlf+set}" = set; then : + enableval=$enable_newline_is_crlf; ac_pcre2_newline=crlf +fi + +# Check whether --enable-newline-is-anycrlf was given. +if test "${enable_newline_is_anycrlf+set}" = set; then : + enableval=$enable_newline_is_anycrlf; ac_pcre2_newline=anycrlf +fi + +# Check whether --enable-newline-is-any was given. +if test "${enable_newline_is_any+set}" = set; then : + enableval=$enable_newline_is_any; ac_pcre2_newline=any +fi + +enable_newline="$ac_pcre2_newline" + +# Handle --enable-bsr-anycrlf +# Check whether --enable-bsr-anycrlf was given. +if test "${enable_bsr_anycrlf+set}" = set; then : + enableval=$enable_bsr_anycrlf; +else + enable_bsr_anycrlf=no +fi + + +# Handle --enable-never-backslash-C +# Check whether --enable-never-backslash-C was given. +if test "${enable_never_backslash_C+set}" = set; then : + enableval=$enable_never_backslash_C; +else + enable_never_backslash_C=no +fi + + +# Handle --enable-ebcdic +# Check whether --enable-ebcdic was given. +if test "${enable_ebcdic+set}" = set; then : + enableval=$enable_ebcdic; +else + enable_ebcdic=no +fi + + +# Handle --enable-ebcdic-nl25 +# Check whether --enable-ebcdic-nl25 was given. +if test "${enable_ebcdic_nl25+set}" = set; then : + enableval=$enable_ebcdic_nl25; +else + enable_ebcdic_nl25=no +fi + + +# Handle --disable-stack-for-recursion +# Check whether --enable-stack-for-recursion was given. +if test "${enable_stack_for_recursion+set}" = set; then : + enableval=$enable_stack_for_recursion; +else + enable_stack_for_recursion=yes +fi + + +# Handle --enable-pcre2grep-libz +# Check whether --enable-pcre2grep-libz was given. +if test "${enable_pcre2grep_libz+set}" = set; then : + enableval=$enable_pcre2grep_libz; +else + enable_pcre2grep_libz=no +fi + + +# Handle --enable-pcre2grep-libbz2 +# Check whether --enable-pcre2grep-libbz2 was given. +if test "${enable_pcre2grep_libbz2+set}" = set; then : + enableval=$enable_pcre2grep_libbz2; +else + enable_pcre2grep_libbz2=no +fi + + +# Handle --with-pcre2grep-bufsize=N + +# Check whether --with-pcre2grep-bufsize was given. +if test "${with_pcre2grep_bufsize+set}" = set; then : + withval=$with_pcre2grep_bufsize; +else + with_pcre2grep_bufsize=20480 +fi + + +# Handle --enable-pcre2test-libedit +# Check whether --enable-pcre2test-libedit was given. +if test "${enable_pcre2test_libedit+set}" = set; then : + enableval=$enable_pcre2test_libedit; +else + enable_pcre2test_libedit=no +fi + + +# Handle --enable-pcre2test-libreadline +# Check whether --enable-pcre2test-libreadline was given. +if test "${enable_pcre2test_libreadline+set}" = set; then : + enableval=$enable_pcre2test_libreadline; +else + enable_pcre2test_libreadline=no +fi + + +# Handle --with-link-size=N + +# Check whether --with-link-size was given. +if test "${with_link_size+set}" = set; then : + withval=$with_link_size; +else + with_link_size=2 +fi + + +# Handle --with-parens-nest-limit=N + +# Check whether --with-parens-nest-limit was given. +if test "${with_parens_nest_limit+set}" = set; then : + withval=$with_parens_nest_limit; +else + with_parens_nest_limit=250 +fi + + +# Handle --with-match-limit=N + +# Check whether --with-match-limit was given. +if test "${with_match_limit+set}" = set; then : + withval=$with_match_limit; +else + with_match_limit=10000000 +fi + + +# Handle --with-match-limit_recursion=N +# +# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION +# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric +# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some +# different numeric value (or even the same numeric value as MATCH_LIMIT, +# though no longer defined in terms of the latter). +# + +# Check whether --with-match-limit-recursion was given. +if test "${with_match_limit_recursion+set}" = set; then : + withval=$with_match_limit_recursion; +else + with_match_limit_recursion=MATCH_LIMIT +fi + + +# Handle --enable-valgrind +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; +else + enable_valgrind=no +fi + + +# Enable code coverage reports using gcov +# Check whether --enable-coverage was given. +if test "${enable_coverage+set}" = set; then : + enableval=$enable_coverage; +else + enable_coverage=no +fi + + +# Set the default value for pcre2-8 +if test "x$enable_pcre2_8" = "xunset" +then + enable_pcre2_8=yes +fi + +# Set the default value for pcre2-16 +if test "x$enable_pcre2_16" = "xunset" +then + enable_pcre2_16=no +fi + +# Set the default value for pcre2-32 +if test "x$enable_pcre2_32" = "xunset" +then + enable_pcre2_32=no +fi + +# Make sure at least one library is selected +if test "x$enable_pcre2_8$enable_pcre2_16$enable_pcre2_32" = "xnonono" +then + as_fn_error $? "At least one of the 8, 16 or 32 bit libraries must be enabled" "$LINENO" 5 +fi + +# Unicode is enabled by default. +if test "x$enable_unicode" = "xunset" +then + enable_unicode=yes +fi + +# Convert the newline identifier into the appropriate integer value. These must +# agree with the PCRE2_NEWLINE_xxx values in pcre2.h. + +case "$enable_newline" in + cr) ac_pcre2_newline_value=1 ;; + lf) ac_pcre2_newline_value=2 ;; + crlf) ac_pcre2_newline_value=3 ;; + any) ac_pcre2_newline_value=4 ;; + anycrlf) ac_pcre2_newline_value=5 ;; + *) + as_fn_error $? "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5 + ;; +esac + +# --enable-ebcdic-nl25 implies --enable-ebcdic +if test "x$enable_ebcdic_nl25" = "xyes"; then + enable_ebcdic=yes +fi + +# Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. +# Also check that UTF support is not requested, because PCRE2 cannot handle +# EBCDIC and UTF in the same build. To do so it would need to use different +# character constants depending on the mode. Also, EBCDIC cannot be used with +# 16-bit and 32-bit libraries. +# +if test "x$enable_ebcdic" = "xyes"; then + enable_rebuild_chartables=yes + if test "x$enable_unicode" = "xyes"; then + as_fn_error $? "support for EBCDIC and Unicode cannot be enabled at the same time" "$LINENO" 5 + fi + if test "x$enable_pcre2_16" = "xyes" -o "x$enable_pcre2_32" = "xyes"; then + as_fn_error $? "EBCDIC support is available only for the 8-bit library" "$LINENO" 5 + fi +fi + +# Check argument to --with-link-size +case "$with_link_size" in + 2|3|4) ;; + *) + as_fn_error $? "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 + ;; +esac + + + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in limits.h sys/types.h sys/stat.h dirent.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in windows.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" +if test "x$ac_cv_header_windows_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + HAVE_WINDOWS_H=1 +fi + +done + + +# Conditional compilation + if test "x$enable_pcre2_8" = "xyes"; then + WITH_PCRE2_8_TRUE= + WITH_PCRE2_8_FALSE='#' +else + WITH_PCRE2_8_TRUE='#' + WITH_PCRE2_8_FALSE= +fi + + if test "x$enable_pcre2_16" = "xyes"; then + WITH_PCRE2_16_TRUE= + WITH_PCRE2_16_FALSE='#' +else + WITH_PCRE2_16_TRUE='#' + WITH_PCRE2_16_FALSE= +fi + + if test "x$enable_pcre2_32" = "xyes"; then + WITH_PCRE2_32_TRUE= + WITH_PCRE2_32_FALSE='#' +else + WITH_PCRE2_32_TRUE='#' + WITH_PCRE2_32_FALSE= +fi + + if test "x$enable_debug" = "xyes"; then + WITH_DEBUG_TRUE= + WITH_DEBUG_FALSE='#' +else + WITH_DEBUG_TRUE='#' + WITH_DEBUG_FALSE= +fi + + if test "x$enable_rebuild_chartables" = "xyes"; then + WITH_REBUILD_CHARTABLES_TRUE= + WITH_REBUILD_CHARTABLES_FALSE='#' +else + WITH_REBUILD_CHARTABLES_TRUE='#' + WITH_REBUILD_CHARTABLES_FALSE= +fi + + if test "x$enable_jit" = "xyes"; then + WITH_JIT_TRUE= + WITH_JIT_FALSE='#' +else + WITH_JIT_TRUE='#' + WITH_JIT_FALSE= +fi + + if test "x$enable_unicode" = "xyes"; then + WITH_UNICODE_TRUE= + WITH_UNICODE_FALSE='#' +else + WITH_UNICODE_TRUE='#' + WITH_UNICODE_FALSE= +fi + + if test "x$enable_valgrind" = "xyes"; then + WITH_VALGRIND_TRUE= + WITH_VALGRIND_FALSE='#' +else + WITH_VALGRIND_TRUE='#' + WITH_VALGRIND_FALSE= +fi + + +# Checks for typedefs, structures, and compiler characteristics. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + +# Checks for library functions. + +for ac_func in bcopy memmove strerror +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check for the availability of libz (aka zlib) + +for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + HAVE_ZLIB_H=1 +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 +$as_echo_n "checking for gzopen in -lz... " >&6; } +if ${ac_cv_lib_z_gzopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzopen (); +int +main () +{ +return gzopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzopen=yes +else + ac_cv_lib_z_gzopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 +$as_echo "$ac_cv_lib_z_gzopen" >&6; } +if test "x$ac_cv_lib_z_gzopen" = xyes; then : + HAVE_LIBZ=1 +fi + + +# Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, +# as for libz. However, this had the following problem, diagnosed and fixed by +# a user: +# +# - libbz2 uses the Pascal calling convention (WINAPI) for the functions +# under Win32. +# - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", +# therefore missing the function definition. +# - The compiler thus generates a "C" signature for the test function. +# - The linker fails to find the "C" function. +# - PCRE2 fails to configure if asked to do so against libbz2. +# +# Solution: +# +# - Replace the AC_CHECK_LIB test with a custom test. + +for ac_header in bzlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_BZLIB_H 1 +_ACEOF + HAVE_BZLIB_H=1 +fi + +done + +# Original test +# AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) +# +# Custom test follows + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbz2" >&5 +$as_echo_n "checking for libbz2... " >&6; } +OLD_LIBS="$LIBS" +LIBS="$LIBS -lbz2" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_BZLIB_H +#include +#endif +int +main () +{ +return (int)BZ2_bzopen("conftest", "rb"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };HAVE_LIBBZ2=1; break; +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$OLD_LIBS" + +# Check for the availabiity of libreadline + +if test "$enable_pcre2test_libreadline" = "yes"; then + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_H=1 +fi + +done + + for ac_header in readline/history.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_history_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_HISTORY_H 1 +_ACEOF + HAVE_HISTORY_H=1 +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lreadline" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-ltinfo" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lcurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lcurses" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lncurses" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lncursesw" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-ltermcap" +else + LIBREADLINE="" +fi + +fi + +fi + +fi + +fi + +fi + + + if test -n "$LIBREADLINE"; then + if test "$LIBREADLINE" != "-lreadline"; then + echo "-lreadline needs $LIBREADLINE" + LIBREADLINE="-lreadline $LIBREADLINE" + fi + fi +fi + + +# Check for the availability of libedit. Different distributions put its +# headers in different places. Try to cover the most common ones. + +if test "$enable_pcre2test_libedit" = "yes"; then + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDITLINE_READLINE_H 1 +_ACEOF + HAVE_EDITLINE_READLINE_H=1 +else + for ac_header in edit/readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "edit/readline/readline.h" "ac_cv_header_edit_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_edit_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDIT_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_READLINE_H=1 +else + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_READLINE_H=1 +fi + +done + +fi + +done + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +$as_echo_n "checking for readline in -ledit... " >&6; } +if ${ac_cv_lib_edit_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_edit_readline=yes +else + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +$as_echo "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes; then : + LIBEDIT="-ledit" +fi + +fi + +# This facilitates -ansi builds under Linux + +PCRE2_STATIC_CFLAG="" +if test "x$enable_shared" = "xno" ; then + +$as_echo "#define PCRE2_STATIC 1" >>confdefs.h + + PCRE2_STATIC_CFLAG="-DPCRE2_STATIC" +fi + + +# Here is where PCRE2-specific defines are handled + +if test "$enable_pcre2_8" = "yes"; then + +$as_echo "#define SUPPORT_PCRE2_8 /**/" >>confdefs.h + +fi + +if test "$enable_pcre2_16" = "yes"; then + +$as_echo "#define SUPPORT_PCRE2_16 /**/" >>confdefs.h + +fi + +if test "$enable_pcre2_32" = "yes"; then + +$as_echo "#define SUPPORT_PCRE2_32 /**/" >>confdefs.h + +fi + +if test "$enable_debug" = "yes"; then + +$as_echo "#define PCRE2_DEBUG /**/" >>confdefs.h + +fi + +# Unless running under Windows, JIT support requires pthreads. + +if test "$enable_jit" = "yes"; then + if test "$HAVE_WINDOWS_H" != "1"; then + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ax_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ax_pthread_config"; then + ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ax_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" +fi +fi +ax_pthread_config=$ac_cv_prog_ax_pthread_config +if test -n "$ax_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 +$as_echo "$ax_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; } +int +main () +{ +pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr = $attr; return attr /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 +$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } +if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include +int +main () +{ +int i = PTHREAD_PRIO_INHERIT; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_PRIO_INHERIT=yes +else + ax_cv_PTHREAD_PRIO_INHERIT=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 +$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : + +$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + +fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + for ac_prog in xlc_r cc_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" + + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + ax_pthread_ok=no + as_fn_error $? "JIT support requires pthreads" "$LINENO" 5 +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + fi + +$as_echo "#define SUPPORT_JIT /**/" >>confdefs.h + +else + enable_pcre2grep_jit="no" +fi + +if test "$enable_pcre2grep_jit" = "yes"; then + +$as_echo "#define SUPPORT_PCRE2GREP_JIT /**/" >>confdefs.h + +fi + +if test "$enable_unicode" = "yes"; then + +$as_echo "#define SUPPORT_UNICODE /**/" >>confdefs.h + +fi + +if test "$enable_stack_for_recursion" = "no"; then + +$as_echo "#define HEAP_MATCH_RECURSE /**/" >>confdefs.h + +fi + +if test "$enable_pcre2grep_libz" = "yes"; then + +$as_echo "#define SUPPORT_LIBZ /**/" >>confdefs.h + +fi + +if test "$enable_pcre2grep_libbz2" = "yes"; then + +$as_echo "#define SUPPORT_LIBBZ2 /**/" >>confdefs.h + +fi + +if test $with_pcre2grep_bufsize -lt 8192 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192" >&5 +$as_echo "$as_me: WARNING: $with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192" >&2;} + with_pcre2grep_bufsize="8192" +else + if test $? -gt 1 ; then + as_fn_error $? "Bad value for --with-pcre2grep-bufsize" "$LINENO" 5 + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define PCRE2GREP_BUFSIZE $with_pcre2grep_bufsize +_ACEOF + + +if test "$enable_pcre2test_libedit" = "yes"; then + +$as_echo "#define SUPPORT_LIBEDIT /**/" >>confdefs.h + + LIBREADLINE="$LIBEDIT" +elif test "$enable_pcre2test_libreadline" = "yes"; then + +$as_echo "#define SUPPORT_LIBREADLINE /**/" >>confdefs.h + +fi + + +cat >>confdefs.h <<_ACEOF +#define NEWLINE_DEFAULT $ac_pcre2_newline_value +_ACEOF + + +if test "$enable_bsr_anycrlf" = "yes"; then + +$as_echo "#define BSR_ANYCRLF /**/" >>confdefs.h + +fi + +if test "$enable_never_backslash_C" = "yes"; then + +$as_echo "#define NEVER_BACKSLASH_C /**/" >>confdefs.h + +fi + + +cat >>confdefs.h <<_ACEOF +#define LINK_SIZE $with_link_size +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define PARENS_NEST_LIMIT $with_parens_nest_limit +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define MATCH_LIMIT $with_match_limit +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define MATCH_LIMIT_RECURSION $with_match_limit_recursion +_ACEOF + + + +$as_echo "#define MAX_NAME_SIZE 32" >>confdefs.h + + + +$as_echo "#define MAX_NAME_COUNT 10000" >>confdefs.h + + + + +if test "$enable_ebcdic" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define EBCDIC /**/ +_ACEOF + +fi + +if test "$enable_ebcdic_nl25" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define EBCDIC_NL25 /**/ +_ACEOF + +fi + +if test "$enable_valgrind" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define SUPPORT_VALGRIND /**/ +_ACEOF + +fi + +# Platform specific issues +NO_UNDEFINED= +EXPORT_ALL_SYMBOLS= +case $host_os in + cygwin* | mingw* ) + if test X"$enable_shared" = Xyes; then + NO_UNDEFINED="-no-undefined" + EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" + fi + ;; +esac + +# The extra LDFLAGS for each particular library. The libpcre2*_version values +# are m4 variables, assigned above. + +EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \ + $NO_UNDEFINED -version-info 3:0:3" + +EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \ + $NO_UNDEFINED -version-info 3:0:3" + +EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \ + $NO_UNDEFINED -version-info 3:0:3" + +EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \ + $NO_UNDEFINED -version-info 0:1:0" + + + + + + +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre2-16 --enable-pcre2-32 --enable-jit --enable-utf" + + +# Check that, if --enable-pcre2grep-libz or --enable-pcre2grep-libbz2 is +# specified, the relevant library is available. + +if test "$enable_pcre2grep_libz" = "yes"; then + if test "$HAVE_ZLIB_H" != "1"; then + echo "** Cannot --enable-pcre2grep-libz because zlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBZ" != "1"; then + echo "** Cannot --enable-pcre2grep-libz because libz was not found" + exit 1 + fi + LIBZ="-lz" +fi + + +if test "$enable_pcre2grep_libbz2" = "yes"; then + if test "$HAVE_BZLIB_H" != "1"; then + echo "** Cannot --enable-pcre2grep-libbz2 because bzlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBBZ2" != "1"; then + echo "** Cannot --enable-pcre2grep-libbz2 because libbz2 was not found" + exit 1 + fi + LIBBZ2="-lbz2" +fi + + +# Similarly for --enable-pcre2test-readline + +if test "$enable_pcre2test_libedit" = "yes"; then + if test "$enable_pcre2test_libreadline" = "yes"; then + echo "** Cannot use both --enable-pcre2test-libedit and --enable-pcre2test-readline" + exit 1 + fi + if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ + "$HAVE_READLINE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcre2test-libedit because neither editline/readline.h" + echo "** nor readline/readline.h was found." + exit 1 + fi + if test -z "$LIBEDIT"; then + echo "** Cannot --enable-pcre2test-libedit because libedit library was not found." + exit 1 + fi +fi + +if test "$enable_pcre2test_libreadline" = "yes"; then + if test "$HAVE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcre2test-readline because readline/readline.h was not found." + exit 1 + fi + if test "$HAVE_HISTORY_H" != "1"; then + echo "** Cannot --enable-pcre2test-readline because readline/history.h was not found." + exit 1 + fi + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcre2test-readline because readline library was not found." + exit 1 + fi +fi + +# Handle valgrind support + +if test "$enable_valgrind" = "yes"; then + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5 +$as_echo_n "checking for VALGRIND... " >&6; } + +if test -n "$VALGRIND_CFLAGS"; then + pkg_cv_VALGRIND_CFLAGS="$VALGRIND_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_VALGRIND_CFLAGS=`$PKG_CONFIG --cflags "valgrind" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$VALGRIND_LIBS"; then + pkg_cv_VALGRIND_LIBS="$VALGRIND_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_VALGRIND_LIBS=`$PKG_CONFIG --libs "valgrind" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + VALGRIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "valgrind" 2>&1` + else + VALGRIND_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "valgrind" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$VALGRIND_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (valgrind) were not met: + +$VALGRIND_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables VALGRIND_CFLAGS +and VALGRIND_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables VALGRIND_CFLAGS +and VALGRIND_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + VALGRIND_CFLAGS=$pkg_cv_VALGRIND_CFLAGS + VALGRIND_LIBS=$pkg_cv_VALGRIND_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + +# Handle code coverage reporting support +if test "$enable_coverage" = "yes"; then + if test "x$GCC" != "xyes"; then + as_fn_error $? "Code coverage reports can only be generated when using GCC" "$LINENO" 5 + fi + + # ccache is incompatible with gcov + # Extract the first word of "shtool", so it can be a program name with args. +set dummy shtool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SHTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SHTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_SHTOOL="$SHTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SHTOOL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SHTOOL" && ac_cv_path_SHTOOL="false" + ;; +esac +fi +SHTOOL=$ac_cv_path_SHTOOL +if test -n "$SHTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHTOOL" >&5 +$as_echo "$SHTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + case `$SHTOOL path $CC` in + *ccache*) cc_ccache=yes;; + *) cc_ccache=no;; + esac + + if test "$cc_ccache" = "yes"; then + if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then + as_fn_error $? "must export CCACHE_DISABLE=1 to disable ccache for code coverage" "$LINENO" 5 + fi + fi + + + # Extract the first word of "lcov", so it can be a program name with args. +set dummy lcov; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LCOV in + [\\/]* | ?:[\\/]*) + ac_cv_path_LCOV="$LCOV" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LCOV="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LCOV" && ac_cv_path_LCOV="false" + ;; +esac +fi +LCOV=$ac_cv_path_LCOV +if test -n "$LCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 +$as_echo "$LCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$LCOV" = "xfalse"; then + as_fn_error $? "lcov not found" "$LINENO" 5 + fi + + + # Extract the first word of "genhtml", so it can be a program name with args. +set dummy genhtml; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GENHTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GENHTML in + [\\/]* | ?:[\\/]*) + ac_cv_path_GENHTML="$GENHTML" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GENHTML="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GENHTML" && ac_cv_path_GENHTML="false" + ;; +esac +fi +GENHTML=$ac_cv_path_GENHTML +if test -n "$GENHTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 +$as_echo "$GENHTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$GENHTML" = "xfalse"; then + as_fn_error $? "genhtml not found" "$LINENO" 5 + fi + + # Set flags needed for gcov + GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_LIBS="-lgcov" + + + +fi # enable_coverage + + if test "x$enable_coverage" = "xyes"; then + WITH_GCOV_TRUE= + WITH_GCOV_FALSE='#' +else + WITH_GCOV_TRUE='#' + WITH_GCOV_FALSE= +fi + + +# Produce these files, in addition to config.h. +ac_config_files="$ac_config_files Makefile libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc libpcre2-posix.pc pcre2-config src/pcre2.h" + + +# Make the generated script files executable. +ac_config_commands="$ac_config_commands script-chmod" + + +# Make sure that pcre2_chartables.c is removed in case the method for +# creating it was changed by reconfiguration. +ac_config_commands="$ac_config_commands delete-old-chartables" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_PCRE2_8_TRUE}" && test -z "${WITH_PCRE2_8_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE2_8\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_PCRE2_16_TRUE}" && test -z "${WITH_PCRE2_16_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE2_16\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_PCRE2_32_TRUE}" && test -z "${WITH_PCRE2_32_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE2_32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_DEBUG_TRUE}" && test -z "${WITH_DEBUG_FALSE}"; then + as_fn_error $? "conditional \"WITH_DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_REBUILD_CHARTABLES_TRUE}" && test -z "${WITH_REBUILD_CHARTABLES_FALSE}"; then + as_fn_error $? "conditional \"WITH_REBUILD_CHARTABLES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_JIT_TRUE}" && test -z "${WITH_JIT_FALSE}"; then + as_fn_error $? "conditional \"WITH_JIT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_UNICODE_TRUE}" && test -z "${WITH_UNICODE_FALSE}"; then + as_fn_error $? "conditional \"WITH_UNICODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_VALGRIND_TRUE}" && test -z "${WITH_VALGRIND_FALSE}"; then + as_fn_error $? "conditional \"WITH_VALGRIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_GCOV_TRUE}" && test -z "${WITH_GCOV_FALSE}"; then + as_fn_error $? "conditional \"WITH_GCOV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by PCRE2 $as_me 10.21, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +PCRE2 config.status 10.21 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "libpcre2-8.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-8.pc" ;; + "libpcre2-16.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-16.pc" ;; + "libpcre2-32.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-32.pc" ;; + "libpcre2-posix.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-posix.pc" ;; + "pcre2-config") CONFIG_FILES="$CONFIG_FILES pcre2-config" ;; + "src/pcre2.h") CONFIG_FILES="$CONFIG_FILES src/pcre2.h" ;; + "script-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS script-chmod" ;; + "delete-old-chartables") CONFIG_COMMANDS="$CONFIG_COMMANDS delete-old-chartables" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "script-chmod":C) chmod a+x pcre2-config ;; + "delete-old-chartables":C) rm -f pcre2_chartables.c ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +# Print out a nice little message after configure is run displaying the +# chosen options. + +ebcdic_nl_code=n/a +if test "$enable_ebcdic_nl25" = "yes"; then + ebcdic_nl_code=0x25 +elif test "$enable_ebcdic" = "yes"; then + ebcdic_nl_code=0x15 +fi + +cat < +#endif]], +[[return (int)BZ2_bzopen("conftest", "rb");]])], +[AC_MSG_RESULT([yes]);HAVE_LIBBZ2=1; break;], +AC_MSG_RESULT([no])) +LIBS="$OLD_LIBS" + +# Check for the availabiity of libreadline + +if test "$enable_pcre2test_libreadline" = "yes"; then + AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1]) + AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1]) + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lreadline"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltinfo"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lcurses"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncurses"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncursesw"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltermcap"], + [LIBREADLINE=""], + [-ltermcap])], + [-lncursesw])], + [-lncurses])], + [-lcurses])], + [-ltinfo])]) + AC_SUBST(LIBREADLINE) + if test -n "$LIBREADLINE"; then + if test "$LIBREADLINE" != "-lreadline"; then + echo "-lreadline needs $LIBREADLINE" + LIBREADLINE="-lreadline $LIBREADLINE" + fi + fi +fi + + +# Check for the availability of libedit. Different distributions put its +# headers in different places. Try to cover the most common ones. + +if test "$enable_pcre2test_libedit" = "yes"; then + AC_CHECK_HEADERS([editline/readline.h], [HAVE_EDITLINE_READLINE_H=1], + [AC_CHECK_HEADERS([edit/readline/readline.h], [HAVE_READLINE_READLINE_H=1], + [AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_READLINE_H=1])])]) + AC_CHECK_LIB([edit], [readline], [LIBEDIT="-ledit"]) +fi + +# This facilitates -ansi builds under Linux +dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc]) + +PCRE2_STATIC_CFLAG="" +if test "x$enable_shared" = "xno" ; then + AC_DEFINE([PCRE2_STATIC], [1], [ + Define to any value if linking statically (TODO: make nice with Libtool)]) + PCRE2_STATIC_CFLAG="-DPCRE2_STATIC" +fi +AC_SUBST(PCRE2_STATIC_CFLAG) + +# Here is where PCRE2-specific defines are handled + +if test "$enable_pcre2_8" = "yes"; then + AC_DEFINE([SUPPORT_PCRE2_8], [], [ + Define to any value to enable the 8 bit PCRE2 library.]) +fi + +if test "$enable_pcre2_16" = "yes"; then + AC_DEFINE([SUPPORT_PCRE2_16], [], [ + Define to any value to enable the 16 bit PCRE2 library.]) +fi + +if test "$enable_pcre2_32" = "yes"; then + AC_DEFINE([SUPPORT_PCRE2_32], [], [ + Define to any value to enable the 32 bit PCRE2 library.]) +fi + +if test "$enable_debug" = "yes"; then + AC_DEFINE([PCRE2_DEBUG], [], [ + Define to any value to include debugging code.]) +fi + +# Unless running under Windows, JIT support requires pthreads. + +if test "$enable_jit" = "yes"; then + if test "$HAVE_WINDOWS_H" != "1"; then + AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])]) + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + fi + AC_DEFINE([SUPPORT_JIT], [], [ + Define to any value to enable support for Just-In-Time compiling.]) +else + enable_pcre2grep_jit="no" +fi + +if test "$enable_pcre2grep_jit" = "yes"; then + AC_DEFINE([SUPPORT_PCRE2GREP_JIT], [], [ + Define to any value to enable JIT support in pcre2grep.]) +fi + +if test "$enable_unicode" = "yes"; then + AC_DEFINE([SUPPORT_UNICODE], [], [ + Define to any value to enable support for Unicode and UTF encoding. + This will work even in an EBCDIC environment, but it is incompatible + with the EBCDIC macro. That is, PCRE2 can support *either* EBCDIC + code *or* ASCII/Unicode, but not both at once.]) +fi + +if test "$enable_stack_for_recursion" = "no"; then + AC_DEFINE([HEAP_MATCH_RECURSE], [], [ + PCRE2 uses recursive function calls to handle backtracking while + matching. This can sometimes be a problem on systems that have + stacks of limited size. Define HEAP_MATCH_RECURSE to any value to get a + version that doesn't use recursion in the match() function; instead + it creates its own stack by steam using memory from the heap. For more + detail, see the comments and other stuff just above the match() function.]) +fi + +if test "$enable_pcre2grep_libz" = "yes"; then + AC_DEFINE([SUPPORT_LIBZ], [], [ + Define to any value to allow pcre2grep to be linked with libz, so that it is + able to handle .gz files.]) +fi + +if test "$enable_pcre2grep_libbz2" = "yes"; then + AC_DEFINE([SUPPORT_LIBBZ2], [], [ + Define to any value to allow pcre2grep to be linked with libbz2, so that it + is able to handle .bz2 files.]) +fi + +if test $with_pcre2grep_bufsize -lt 8192 ; then + AC_MSG_WARN([$with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192]) + with_pcre2grep_bufsize="8192" +else + if test $? -gt 1 ; then + AC_MSG_ERROR([Bad value for --with-pcre2grep-bufsize]) + fi +fi + +AC_DEFINE_UNQUOTED([PCRE2GREP_BUFSIZE], [$with_pcre2grep_bufsize], [ + The value of PCRE2GREP_BUFSIZE determines the size of buffer used by pcre2grep + to hold parts of the file it is searching. This is also the minimum value. + The actual amount of memory used by pcre2grep is three times this number, + because it allows for the buffering of "before" and "after" lines.]) + +if test "$enable_pcre2test_libedit" = "yes"; then + AC_DEFINE([SUPPORT_LIBEDIT], [], [ + Define to any value to allow pcre2test to be linked with libedit.]) + LIBREADLINE="$LIBEDIT" +elif test "$enable_pcre2test_libreadline" = "yes"; then + AC_DEFINE([SUPPORT_LIBREADLINE], [], [ + Define to any value to allow pcre2test to be linked with libreadline.]) +fi + +AC_DEFINE_UNQUOTED([NEWLINE_DEFAULT], [$ac_pcre2_newline_value], [ + The value of NEWLINE_DEFAULT determines the default newline character + sequence. PCRE2 client programs can override this by selecting other values + at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), + and 5 (ANYCRLF).]) + +if test "$enable_bsr_anycrlf" = "yes"; then + AC_DEFINE([BSR_ANYCRLF], [], [ + By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE2 at runtime.]) +fi + +if test "$enable_never_backslash_C" = "yes"; then + AC_DEFINE([NEVER_BACKSLASH_C], [], [ + Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns.]) +fi + +AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [ + The value of LINK_SIZE determines the number of bytes used to store + links as offsets within the compiled regex. The default is 2, which + allows for compiled patterns up to 64K long. This covers the vast + majority of cases. However, PCRE2 can also be compiled to use 3 or 4 + bytes instead. This allows for longer patterns in extreme cases.]) + +AC_DEFINE_UNQUOTED([PARENS_NEST_LIMIT], [$with_parens_nest_limit], [ + The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern.]) + +AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ + The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre2_match(). There is a runtime interface for setting a different + limit. The limit exists in order to catch runaway regular + expressions that take for ever to determine that they do not match. + The default is set very large so that it does not accidentally catch + legitimate cases.]) + +AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ + The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable + to limit the depth of recursive calls of match() more strictly, in + order to restrict the maximum amount of stack (or heap, if + HEAP_MATCH_RECURSE is defined) that is used. The value of + MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To + have any useful effect, it must be less than the value of + MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. + There is a runtime method for setting a different limit.]) + +AC_DEFINE([MAX_NAME_SIZE], [32], [ + This limit is parameterized just in case anybody ever wants to + change it. Care must be taken if it is increased, because it guards + against integer overflow caused by enormously large patterns.]) + +AC_DEFINE([MAX_NAME_COUNT], [10000], [ + This limit is parameterized just in case anybody ever wants to + change it. Care must be taken if it is increased, because it guards + against integer overflow caused by enormously large patterns.]) + +AH_VERBATIM([PCRE2_EXP_DEFN], [ +/* If you are compiling for a system other than a Unix-like system or + Win32, and it needs some magic to be inserted before the definition + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +#undef PCRE2_EXP_DEFN]) + +if test "$enable_ebcdic" = "yes"; then + AC_DEFINE_UNQUOTED([EBCDIC], [], [ + If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. When EBCDIC is set, PCRE2 + assumes that all input strings are in EBCDIC. If you do not define this + macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It + is not possible to build a version of PCRE2 that supports both EBCDIC and + UTF-8/16/32.]) +fi + +if test "$enable_ebcdic_nl25" = "yes"; then + AC_DEFINE_UNQUOTED([EBCDIC_NL25], [], [ + In an EBCDIC environment, define this macro to any value to arrange for + the NL character to be 0x25 instead of the default 0x15. NL plays the role + that LF does in an ASCII/Unicode environment.]) +fi + +if test "$enable_valgrind" = "yes"; then + AC_DEFINE_UNQUOTED([SUPPORT_VALGRIND], [], [ + Define to any value for valgrind support to find invalid memory reads.]) +fi + +# Platform specific issues +NO_UNDEFINED= +EXPORT_ALL_SYMBOLS= +case $host_os in + cygwin* | mingw* ) + if test X"$enable_shared" = Xyes; then + NO_UNDEFINED="-no-undefined" + EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" + fi + ;; +esac + +# The extra LDFLAGS for each particular library. The libpcre2*_version values +# are m4 variables, assigned above. + +EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre2_8_version" + +EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre2_16_version" + +EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre2_32_version" + +EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre2_posix_version" + +AC_SUBST(EXTRA_LIBPCRE2_8_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE2_16_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE2_32_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE2_POSIX_LDFLAGS) + +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre2-16 --enable-pcre2-32 --enable-jit --enable-utf" +AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) + +# Check that, if --enable-pcre2grep-libz or --enable-pcre2grep-libbz2 is +# specified, the relevant library is available. + +if test "$enable_pcre2grep_libz" = "yes"; then + if test "$HAVE_ZLIB_H" != "1"; then + echo "** Cannot --enable-pcre2grep-libz because zlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBZ" != "1"; then + echo "** Cannot --enable-pcre2grep-libz because libz was not found" + exit 1 + fi + LIBZ="-lz" +fi +AC_SUBST(LIBZ) + +if test "$enable_pcre2grep_libbz2" = "yes"; then + if test "$HAVE_BZLIB_H" != "1"; then + echo "** Cannot --enable-pcre2grep-libbz2 because bzlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBBZ2" != "1"; then + echo "** Cannot --enable-pcre2grep-libbz2 because libbz2 was not found" + exit 1 + fi + LIBBZ2="-lbz2" +fi +AC_SUBST(LIBBZ2) + +# Similarly for --enable-pcre2test-readline + +if test "$enable_pcre2test_libedit" = "yes"; then + if test "$enable_pcre2test_libreadline" = "yes"; then + echo "** Cannot use both --enable-pcre2test-libedit and --enable-pcre2test-readline" + exit 1 + fi + if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ + "$HAVE_READLINE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcre2test-libedit because neither editline/readline.h" + echo "** nor readline/readline.h was found." + exit 1 + fi + if test -z "$LIBEDIT"; then + echo "** Cannot --enable-pcre2test-libedit because libedit library was not found." + exit 1 + fi +fi + +if test "$enable_pcre2test_libreadline" = "yes"; then + if test "$HAVE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcre2test-readline because readline/readline.h was not found." + exit 1 + fi + if test "$HAVE_HISTORY_H" != "1"; then + echo "** Cannot --enable-pcre2test-readline because readline/history.h was not found." + exit 1 + fi + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcre2test-readline because readline library was not found." + exit 1 + fi +fi + +# Handle valgrind support + +if test "$enable_valgrind" = "yes"; then + m4_ifdef([PKG_CHECK_MODULES], + [PKG_CHECK_MODULES([VALGRIND],[valgrind])], + [AC_MSG_ERROR([pkg-config not supported])]) +fi + +# Handle code coverage reporting support +if test "$enable_coverage" = "yes"; then + if test "x$GCC" != "xyes"; then + AC_MSG_ERROR([Code coverage reports can only be generated when using GCC]) + fi + + # ccache is incompatible with gcov + AC_PATH_PROG([SHTOOL],[shtool],[false]) + case `$SHTOOL path $CC` in + *ccache*) cc_ccache=yes;; + *) cc_ccache=no;; + esac + + if test "$cc_ccache" = "yes"; then + if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then + AC_MSG_ERROR([must export CCACHE_DISABLE=1 to disable ccache for code coverage]) + fi + fi + + AC_ARG_VAR([LCOV],[the ltp lcov program]) + AC_PATH_PROG([LCOV],[lcov],[false]) + if test "x$LCOV" = "xfalse"; then + AC_MSG_ERROR([lcov not found]) + fi + + AC_ARG_VAR([GENHTML],[the ltp genhtml program]) + AC_PATH_PROG([GENHTML],[genhtml],[false]) + if test "x$GENHTML" = "xfalse"; then + AC_MSG_ERROR([genhtml not found]) + fi + + # Set flags needed for gcov + GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_LIBS="-lgcov" + AC_SUBST([GCOV_CFLAGS]) + AC_SUBST([GCOV_CXXFLAGS]) + AC_SUBST([GCOV_LIBS]) +fi # enable_coverage + +AM_CONDITIONAL([WITH_GCOV],[test "x$enable_coverage" = "xyes"]) + +# Produce these files, in addition to config.h. +AC_CONFIG_FILES( + Makefile + libpcre2-8.pc + libpcre2-16.pc + libpcre2-32.pc + libpcre2-posix.pc + pcre2-config + src/pcre2.h +) + +# Make the generated script files executable. +AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre2-config]) + +# Make sure that pcre2_chartables.c is removed in case the method for +# creating it was changed by reconfiguration. +AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre2_chartables.c]) + +AC_OUTPUT + +# Print out a nice little message after configure is run displaying the +# chosen options. + +ebcdic_nl_code=n/a +if test "$enable_ebcdic_nl25" = "yes"; then + ebcdic_nl_code=0x25 +elif test "$enable_ebcdic" = "yes"; then + ebcdic_nl_code=0x15 +fi + +cat <. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/pcre2/install-sh b/pcre2/install-sh new file mode 100755 index 000000000..0b0fdcbba --- /dev/null +++ b/pcre2/install-sh @@ -0,0 +1,501 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2013-12-25.23; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/pcre2/libpcre2-16.pc.in b/pcre2/libpcre2-16.pc.in new file mode 100644 index 000000000..978040dfe --- /dev/null +++ b/pcre2/libpcre2-16.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre2-16 +Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 16 bit character support +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre2-16 +Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ +Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-32.pc.in b/pcre2/libpcre2-32.pc.in new file mode 100644 index 000000000..d8fb18713 --- /dev/null +++ b/pcre2/libpcre2-32.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre2-32 +Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 32 bit character support +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre2-32 +Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ +Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-8.pc.in b/pcre2/libpcre2-8.pc.in new file mode 100644 index 000000000..5c872d0b3 --- /dev/null +++ b/pcre2/libpcre2-8.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre2-8 +Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 8 bit character support +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre2-8 +Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ +Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-posix.pc.in b/pcre2/libpcre2-posix.pc.in new file mode 100644 index 000000000..96415558e --- /dev/null +++ b/pcre2/libpcre2-posix.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre2-posix +Description: Posix compatible interface to libpcre2-8 +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre2-posix +Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ +Requires.private: libpcre2-8 diff --git a/pcre2/ltmain.sh b/pcre2/ltmain.sh new file mode 100644 index 000000000..0f0a2da3f --- /dev/null +++ b/pcre2/ltmain.sh @@ -0,0 +1,11147 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.6 +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/pcre2/m4/ax_pthread.m4 b/pcre2/m4/ax_pthread.m4 new file mode 100644 index 000000000..d90de34d1 --- /dev/null +++ b/pcre2/m4/ax_pthread.m4 @@ -0,0 +1,309 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 18 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/pcre2/m4/libtool.m4 b/pcre2/m4/libtool.m4 new file mode 100644 index 000000000..a3bc337b7 --- /dev/null +++ b/pcre2/m4/libtool.m4 @@ -0,0 +1,8369 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/pcre2/m4/ltoptions.m4 b/pcre2/m4/ltoptions.m4 new file mode 100644 index 000000000..94b082976 --- /dev/null +++ b/pcre2/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/pcre2/m4/ltsugar.m4 b/pcre2/m4/ltsugar.m4 new file mode 100644 index 000000000..48bc9344a --- /dev/null +++ b/pcre2/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/pcre2/m4/ltversion.m4 b/pcre2/m4/ltversion.m4 new file mode 100644 index 000000000..fa04b52a3 --- /dev/null +++ b/pcre2/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/pcre2/m4/lt~obsolete.m4 b/pcre2/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c6b26f88f --- /dev/null +++ b/pcre2/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/pcre2/m4/pcre2_visibility.m4 b/pcre2/m4/pcre2_visibility.m4 new file mode 100644 index 000000000..480f2eefe --- /dev/null +++ b/pcre2/m4/pcre2_visibility.m4 @@ -0,0 +1,87 @@ +# visibility.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +dnl Modified to fit with PCRE build environment by Cristian Rodríguez. +dnl Adjusted for PCRE2 by PH + +AC_DEFUN([PCRE2_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + VISIBILITY_CFLAGS= + VISIBILITY_CXXFLAGS= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_MSG_CHECKING([whether the -Werror option is usable]) + AC_CACHE_VAL([pcre2_cv_cc_vis_werror], [ + pcre2_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [pcre2_cv_cc_vis_werror=yes], + [pcre2_cv_cc_vis_werror=no]) + CFLAGS="$pcre2_save_CFLAGS"]) + AC_MSG_RESULT([$pcre2_cv_cc_vis_werror]) + dnl Now check whether visibility declarations are supported. + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([pcre2_cv_cc_visibility], [ + pcre2_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $pcre2_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + ]], + [[]])], + [pcre2_cv_cc_visibility=yes], + [pcre2_cv_cc_visibility=no]) + CFLAGS="$pcre2_save_CFLAGS"]) + AC_MSG_RESULT([$pcre2_cv_cc_visibility]) + if test $pcre2_cv_cc_visibility = yes; then + VISIBILITY_CFLAGS="-fvisibility=hidden" + VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" + HAVE_VISIBILITY=1 + AC_DEFINE(PCRE2_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRE2_EXP_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRE2POSIX_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRE2POSIX_EXP_DEFN, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + fi + fi + AC_SUBST([VISIBILITY_CFLAGS]) + AC_SUBST([VISIBILITY_CXXFLAGS]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 if the compiler supports simple visibility declarations.]) +]) diff --git a/pcre2/missing b/pcre2/missing new file mode 100755 index 000000000..f62bbae30 --- /dev/null +++ b/pcre2/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/pcre2/pcre2-config.in b/pcre2/pcre2-config.in new file mode 100644 index 000000000..932160ef5 --- /dev/null +++ b/pcre2/pcre2-config.in @@ -0,0 +1,121 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +cflags="[--cflags]" +libs= + +if test @enable_pcre2_16@ = yes ; then + libs="[--libs16] $libs" +fi + +if test @enable_pcre2_32@ = yes ; then + libs="[--libs32] $libs" +fi + +if test @enable_pcre2_8@ = yes ; then + libs="[--libs8] [--libs-posix] $libs" + cflags="$cflags [--cflags-posix]" +fi + +usage="Usage: pcre2-config [--prefix] [--exec-prefix] [--version] $libs $cflags" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +libR= +case `uname -s` in + *SunOS*) + libR=" -R@libdir@" + ;; + *BSD*) + libR=" -Wl,-R@libdir@" + ;; +esac + +libS= +if test @libdir@ != /usr/lib ; then + libS=-L@libdir@ +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @PACKAGE_VERSION@ + ;; + --cflags) + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes @PCRE2_STATIC_CFLAG@ + ;; + --cflags-posix) + if test @enable_pcre2_8@ = yes ; then + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes @PCRE2_STATIC_CFLAG@ + else + echo "${usage}" 1>&2 + fi + ;; + --libs-posix) + if test @enable_pcre2_8@ = yes ; then + echo $libS$libR -lpcre2posix -lpcre2-8 + else + echo "${usage}" 1>&2 + fi + ;; + --libs8) + if test @enable_pcre2_8@ = yes ; then + echo $libS$libR -lpcre2-8 + else + echo "${usage}" 1>&2 + fi + ;; + --libs16) + if test @enable_pcre2_16@ = yes ; then + echo $libS$libR -lpcre2-16 + else + echo "${usage}" 1>&2 + fi + ;; + --libs32) + if test @enable_pcre2_32@ = yes ; then + echo $libS$libR -lpcre2-32 + else + echo "${usage}" 1>&2 + fi + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/pcre2/perltest.sh b/pcre2/perltest.sh new file mode 100755 index 000000000..9cf7b17f7 --- /dev/null +++ b/pcre2/perltest.sh @@ -0,0 +1,297 @@ +#! /bin/sh + +# Script for testing regular expressions with perl to check that PCRE2 handles +# them the same. The Perl code has to have "use utf8" and "require Encode" at +# the start when running UTF-8 tests, but *not* for non-utf8 tests. (The +# "require" would actually be OK for non-utf8-tests, but is not always +# installed, so this way the script will always run for these tests.) +# +# The desired effect is achieved by making this a shell script that passes the +# Perl script to Perl through a pipe. If the first argument is "-utf8", a +# suitable prefix is set up. +# +# The remaining arguments, if any, are passed to Perl. They are an input file +# and an output file. If there is one argument, the output is written to +# STDOUT. If Perl receives no arguments, it opens /dev/tty as input, and writes +# output to STDOUT. (I haven't found a way of getting it to use STDIN, because +# of the contorted piping input.) + +perl=perl +prefix='' +if [ $# -gt 0 -a "$1" = "-utf8" ] ; then + prefix="use utf8; require Encode;" + shift +fi + + +# The Perl script that follows has a similar specification to pcre2test, and so +# can be given identical input, except that input patterns can be followed only +# by Perl's lower case modifiers and certain other pcre2test modifiers that are +# either handled or ignored: +# +# aftertext interpreted as "print $' afterwards" +# afteralltext ignored +# dupnames ignored (Perl always allows) +# mark ignored +# no_auto_possess ignored +# no_start_optimize ignored +# ucp sets Perl's /u modifier +# utf invoke UTF-8 functionality +# +# The data lines must not have any pcre2test modifiers. They are processed as +# Perl double-quoted strings, so if they contain " $ or @ characters, these +# have to be escaped. For this reason, all such characters in the +# Perl-compatible testinput1 and testinput4 files are escaped so that they can +# be used for perltest as well as for pcre2test. The output from this script +# should be same as from pcre2test, apart from the initial identifying banner. +# +# The other testinput files are not suitable for feeding to perltest.sh, +# because they make use of the special modifiers that pcre2test uses for +# testing features of PCRE2. Some of these files also contain malformed regular +# expressions, in order to check that PCRE2 diagnoses them correctly. + +(echo "$prefix" ; cat <<'PERLEND' + +# Function for turning a string into a string of printing chars. + +sub pchars { +my($t) = ""; +if ($utf8) + { + @p = unpack('U*', $_[0]); + foreach $c (@p) + { + if ($c >= 32 && $c < 127) { $t .= chr $c; } + else { $t .= sprintf("\\x{%02x}", $c); + } + } + } +else + { + foreach $c (split(//, $_[0])) + { + if (ord $c >= 32 && ord $c < 127) { $t .= $c; } + else { $t .= sprintf("\\x%02x", ord $c); } + } + } +$t; +} + + +# Read lines from a named file or stdin and write to a named file or stdout; +# lines consist of a regular expression, in delimiters and optionally followed +# by options, followed by a set of test data, terminated by an empty line. + +# Sort out the input and output files + +if (@ARGV > 0) + { + open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; + $infile = "INFILE"; + $interact = 0; + } +else + { + open(INFILE, " 1) + { + open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; + $outfile = "OUTFILE"; + } +else { $outfile = "STDOUT"; } + +printf($outfile "Perl $] Regular Expressions\n\n"); + +# Main loop + +NEXT_RE: +for (;;) + { + printf " re> " if $interact; + last if ! ($_ = <$infile>); + printf $outfile "$_" if ! $interact; + next if ($_ =~ /^\s*$/ || $_ =~ /^#/); + + $pattern = $_; + + while ($pattern !~ /^\s*(.).*\1/s) + { + printf " > " if $interact; + last if ! ($_ = <$infile>); + printf $outfile "$_" if ! $interact; + $pattern .= $_; + } + + chomp($pattern); + $pattern =~ s/\s+$//; + + # Split the pattern from the modifiers and adjust them as necessary. + + $pattern =~ /^\s*((.).*\2)(.*)$/s; + $pat = $1; + $mod = $3; + + # The private "aftertext" modifier means "print $' afterwards". + + $showrest = ($mod =~ s/aftertext,?//); + + # "allaftertext" is used by pcre2test to print remainders after captures + + $mod =~ s/allaftertext,?//; + + # Detect utf + + $utf8 = $mod =~ s/utf,?//; + + # Remove "dupnames". + + $mod =~ s/dupnames,?//; + + # Remove "mark" (asks pcre2test to check MARK data) */ + + $mod =~ s/mark,?//; + + # "ucp" asks pcre2test to set PCRE2_UCP; change this to /u for Perl + + $mod =~ s/ucp,?/u/; + + # Remove "no_auto_possess" and "no_start_optimize" (disable PCRE2 optimizations) + + $mod =~ s/no_auto_possess,?//; + $mod =~ s/no_start_optimize,?//; + + # Add back retained modifiers and check that the pattern is valid. + + $mod =~ s/,//g; + $pattern = "$pat$mod"; + eval "\$_ =~ ${pattern}"; + if ($@) + { + printf $outfile "Error: $@"; + if (! $interact) + { + for (;;) + { + last if ! ($_ = <$infile>); + last if $_ =~ /^\s*$/; + } + } + next NEXT_RE; + } + + # If the /g modifier is present, we want to put a loop round the matching; + # otherwise just a single "if". + + $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; + + # If the pattern is actually the null string, Perl uses the most recently + # executed (and successfully compiled) regex is used instead. This is a + # nasty trap for the unwary! The PCRE2 test suite does contain null strings + # in places - if they are allowed through here all sorts of weird and + # unexpected effects happen. To avoid this, we replace such patterns with + # a non-null pattern that has the same effect. + + $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); + + # Read data lines and test them + + for (;;) + { + printf "data> " if $interact; + last NEXT_RE if ! ($_ = <$infile>); + chomp; + printf $outfile "%s", "$_\n" if ! $interact; + + s/\s+$//; # Remove trailing space + s/^\s+//; # Remove leading space + + last if ($_ eq ""); + next if $_ =~ /^\\=(?:\s|$)/; # Comment line + + $x = eval "\"$_\""; # To get escapes processed + + # Empty array for holding results, ensure $REGERROR and $REGMARK are + # unset, then do the matching. + + @subs = (); + + $pushes = "push \@subs,\$&;" . + "push \@subs,\$1;" . + "push \@subs,\$2;" . + "push \@subs,\$3;" . + "push \@subs,\$4;" . + "push \@subs,\$5;" . + "push \@subs,\$6;" . + "push \@subs,\$7;" . + "push \@subs,\$8;" . + "push \@subs,\$9;" . + "push \@subs,\$10;" . + "push \@subs,\$11;" . + "push \@subs,\$12;" . + "push \@subs,\$13;" . + "push \@subs,\$14;" . + "push \@subs,\$15;" . + "push \@subs,\$16;" . + "push \@subs,\$'; }"; + + undef $REGERROR; + undef $REGMARK; + + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + + if ($@) + { + printf $outfile "Error: $@\n"; + next NEXT_RE; + } + elsif (scalar(@subs) == 0) + { + printf $outfile "No match"; + if (defined $REGERROR && $REGERROR != 1) + { printf $outfile (", mark = %s", &pchars($REGERROR)); } + printf $outfile "\n"; + } + else + { + while (scalar(@subs) != 0) + { + printf $outfile (" 0: %s\n", &pchars($subs[0])); + printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; + $last_printed = 0; + for ($i = 1; $i <= 16; $i++) + { + if (defined $subs[$i]) + { + while ($last_printed++ < $i-1) + { printf $outfile ("%2d: \n", $last_printed); } + printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); + $last_printed = $i; + } + } + splice(@subs, 0, 18); + } + + # It seems that $REGMARK is not marked as UTF-8 even when use utf8 is + # set and the input pattern was a UTF-8 string. We can, however, force + # it to be so marked. + + if (defined $REGMARK && $REGMARK != 1) + { + $xx = $REGMARK; + $xx = Encode::decode_utf8($xx) if $utf8; + printf $outfile ("MK: %s\n", &pchars($xx)); + } + } + } + } + +# printf $outfile "\n"; + +PERLEND +) | $perl - $@ + +# End diff --git a/pcre2/src/config.h.generic b/pcre2/src/config.h.generic new file mode 100644 index 000000000..744f19898 --- /dev/null +++ b/pcre2/src/config.h.generic @@ -0,0 +1,306 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* PCRE2 is written in Standard C, but there are a few non-standard things it +can cope with, allowing it to run on SunOS4 and other "close to standard" +systems. + +In environments that support the GNU autotools, config.h.in is converted into +config.h by the "configure" script. In environments that use CMake, +config-cmake.in is converted into config.h. If you are going to build PCRE2 "by +hand" without using "configure" or CMake, you should copy the distributed +config.h.generic to config.h, and edit the macro definitions to be the way you +need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, +so that config.h is included at the start of every source. + +Alternatively, you can avoid editing by using -D on the compiler command line +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, +but if you do, default values will be taken from config.h for non-boolean +macros that are not defined on the command line. + +Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be defined +(conventionally to 1) for TRUE, and not defined at all for FALSE. All such +macros are listed as a commented #undef in config.h.generic. Macros such as +MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are +surrounded by #ifndef/#endif lines so that the value can be overridden by -D. + +PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if +HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make +sure both macros are undefined; an emulation function will then be used. */ + +/* By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE2 at runtime. + */ +/* #undef BSR_ANYCRLF */ + +/* If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. When EBCDIC is set, PCRE2 + assumes that all input strings are in EBCDIC. If you do not define this + macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It + is not possible to build a version of PCRE2 that supports both EBCDIC and + UTF-8/16/32. */ +/* #undef EBCDIC */ + +/* In an EBCDIC environment, define this macro to any value to arrange for the + NL character to be 0x25 instead of the default 0x15. NL plays the role that + LF does in an ASCII/Unicode environment. */ +/* #undef EBCDIC_NL25 */ + +/* Define to 1 if you have the `bcopy' function. */ +/* #undef HAVE_BCOPY */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BZLIB_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DIRENT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDIT_READLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIMITS_H */ + +/* Define to 1 if you have the `memmove' function. */ +/* #undef HAVE_MEMMOVE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef HAVE_PTHREAD */ + +/* Have PTHREAD_PRIO_INHERIT. */ +/* #undef HAVE_PTHREAD_PRIO_INHERIT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ + +/* Define to 1 if you have the `strerror' function. */ +/* #undef HAVE_STRERROR */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define to 1 if the compiler supports simple visibility declarations. */ +/* #undef HAVE_VISIBILITY */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ZLIB_H */ + +/* PCRE2 uses recursive function calls to handle backtracking while matching. + This can sometimes be a problem on systems that have stacks of limited + size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't + use recursion in the match() function; instead it creates its own stack by + steam using memory from the heap. For more detail, see the comments and + other stuff just above the match() function. */ +/* #undef HEAP_MATCH_RECURSE */ + +/* The value of LINK_SIZE determines the number of bytes used to store links + as offsets within the compiled regex. The default is 2, which allows for + compiled patterns up to 64K long. This covers the vast majority of cases. + However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This + allows for longer patterns in extreme cases. */ +#ifndef LINK_SIZE +#define LINK_SIZE 2 +#endif + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* This is ignored unless you are using libtool. */ +#ifndef LT_OBJDIR +#define LT_OBJDIR ".libs/" +#endif + +/* The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre2_match(). There is a runtime interface for setting a different limit. + The limit exists in order to catch runaway regular expressions that take + for ever to determine that they do not match. The default is set very large + so that it does not accidentally catch legitimate cases. */ +#ifndef MATCH_LIMIT +#define MATCH_LIMIT 10000000 +#endif + +/* The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable to limit + the depth of recursive calls of match() more strictly, in order to restrict + the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined) + that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive + calls of match(). To have any useful effect, it must be less than the value + of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There + is a runtime method for setting a different limit. */ +#ifndef MATCH_LIMIT_RECURSION +#define MATCH_LIMIT_RECURSION MATCH_LIMIT +#endif + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#ifndef MAX_NAME_COUNT +#define MAX_NAME_COUNT 10000 +#endif + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#ifndef MAX_NAME_SIZE +#define MAX_NAME_SIZE 32 +#endif + +/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */ +/* #undef NEVER_BACKSLASH_C */ + +/* The value of NEWLINE_DEFAULT determines the default newline character + sequence. PCRE2 client programs can override this by selecting other values + at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5 + (ANYCRLF). */ +#ifndef NEWLINE_DEFAULT +#define NEWLINE_DEFAULT 2 +#endif + +/* Name of package */ +#define PACKAGE "pcre2" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "PCRE2" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "PCRE2 10.21" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "pcre2" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "10.21" + +/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern. */ +#ifndef PARENS_NEST_LIMIT +#define PARENS_NEST_LIMIT 250 +#endif + +/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by + pcre2grep to hold parts of the file it is searching. This is also the + minimum value. The actual amount of memory used by pcre2grep is three times + this number, because it allows for the buffering of "before" and "after" + lines. */ +#ifndef PCRE2GREP_BUFSIZE +#define PCRE2GREP_BUFSIZE 20480 +#endif + +/* Define to any value to include debugging code. */ +/* #undef PCRE2_DEBUG */ + +/* If you are compiling for a system other than a Unix-like system or + Win32, and it needs some magic to be inserted before the definition + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +/* #undef PCRE2_EXP_DEFN */ + +/* Define to any value if linking statically (TODO: make nice with Libtool) */ +/* #undef PCRE2_STATIC */ + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +/* Define to any value to enable support for Just-In-Time compiling. */ +/* #undef SUPPORT_JIT */ + +/* Define to any value to allow pcre2grep to be linked with libbz2, so that it + is able to handle .bz2 files. */ +/* #undef SUPPORT_LIBBZ2 */ + +/* Define to any value to allow pcre2test to be linked with libedit. */ +/* #undef SUPPORT_LIBEDIT */ + +/* Define to any value to allow pcre2test to be linked with libreadline. */ +/* #undef SUPPORT_LIBREADLINE */ + +/* Define to any value to allow pcre2grep to be linked with libz, so that it + is able to handle .gz files. */ +/* #undef SUPPORT_LIBZ */ + +/* Define to any value to enable JIT support in pcre2grep. */ +/* #undef SUPPORT_PCRE2GREP_JIT */ + +/* Define to any value to enable the 16 bit PCRE2 library. */ +/* #undef SUPPORT_PCRE2_16 */ + +/* Define to any value to enable the 32 bit PCRE2 library. */ +/* #undef SUPPORT_PCRE2_32 */ + +/* Define to any value to enable the 8 bit PCRE2 library. */ +/* #undef SUPPORT_PCRE2_8 */ + +/* Define to any value to enable support for Unicode and UTF encoding. This + will work even in an EBCDIC environment, but it is incompatible with the + EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or* + ASCII/Unicode, but not both at once. */ +/* #undef SUPPORT_UNICODE */ + +/* Define to any value for valgrind support to find invalid memory reads. */ +/* #undef SUPPORT_VALGRIND */ + +/* Version number of package */ +#define VERSION "10.21" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef int64_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/pcre2/src/config.h.in b/pcre2/src/config.h.in new file mode 100644 index 000000000..e55d0a048 --- /dev/null +++ b/pcre2/src/config.h.in @@ -0,0 +1,297 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + + +/* PCRE2 is written in Standard C, but there are a few non-standard things it +can cope with, allowing it to run on SunOS4 and other "close to standard" +systems. + +In environments that support the GNU autotools, config.h.in is converted into +config.h by the "configure" script. In environments that use CMake, +config-cmake.in is converted into config.h. If you are going to build PCRE2 "by +hand" without using "configure" or CMake, you should copy the distributed +config.h.generic to config.h, and edit the macro definitions to be the way you +need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, +so that config.h is included at the start of every source. + +Alternatively, you can avoid editing by using -D on the compiler command line +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, +but if you do, default values will be taken from config.h for non-boolean +macros that are not defined on the command line. + +Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be defined +(conventionally to 1) for TRUE, and not defined at all for FALSE. All such +macros are listed as a commented #undef in config.h.generic. Macros such as +MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are +surrounded by #ifndef/#endif lines so that the value can be overridden by -D. + +PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if +HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make +sure both macros are undefined; an emulation function will then be used. */ + +/* By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE2 at runtime. + */ +#undef BSR_ANYCRLF + +/* If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. When EBCDIC is set, PCRE2 + assumes that all input strings are in EBCDIC. If you do not define this + macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It + is not possible to build a version of PCRE2 that supports both EBCDIC and + UTF-8/16/32. */ +#undef EBCDIC + +/* In an EBCDIC environment, define this macro to any value to arrange for the + NL character to be 0x25 instead of the default 0x15. NL plays the role that + LF does in an ASCII/Unicode environment. */ +#undef EBCDIC_NL25 + +/* Define to 1 if you have the `bcopy' function. */ +#undef HAVE_BCOPY + +/* Define to 1 if you have the header file. */ +#undef HAVE_BZLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EDITLINE_READLINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EDIT_READLINE_READLINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Have PTHREAD_PRIO_INHERIT. */ +#undef HAVE_PTHREAD_PRIO_INHERIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_HISTORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the compiler supports simple visibility declarations. */ +#undef HAVE_VISIBILITY + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ZLIB_H + +/* PCRE2 uses recursive function calls to handle backtracking while matching. + This can sometimes be a problem on systems that have stacks of limited + size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't + use recursion in the match() function; instead it creates its own stack by + steam using memory from the heap. For more detail, see the comments and + other stuff just above the match() function. */ +#undef HEAP_MATCH_RECURSE + +/* The value of LINK_SIZE determines the number of bytes used to store links + as offsets within the compiled regex. The default is 2, which allows for + compiled patterns up to 64K long. This covers the vast majority of cases. + However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This + allows for longer patterns in extreme cases. */ +#undef LINK_SIZE + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre2_match(). There is a runtime interface for setting a different limit. + The limit exists in order to catch runaway regular expressions that take + for ever to determine that they do not match. The default is set very large + so that it does not accidentally catch legitimate cases. */ +#undef MATCH_LIMIT + +/* The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable to limit + the depth of recursive calls of match() more strictly, in order to restrict + the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined) + that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive + calls of match(). To have any useful effect, it must be less than the value + of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There + is a runtime method for setting a different limit. */ +#undef MATCH_LIMIT_RECURSION + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#undef MAX_NAME_COUNT + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#undef MAX_NAME_SIZE + +/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */ +#undef NEVER_BACKSLASH_C + +/* The value of NEWLINE_DEFAULT determines the default newline character + sequence. PCRE2 client programs can override this by selecting other values + at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5 + (ANYCRLF). */ +#undef NEWLINE_DEFAULT + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern. */ +#undef PARENS_NEST_LIMIT + +/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by + pcre2grep to hold parts of the file it is searching. This is also the + minimum value. The actual amount of memory used by pcre2grep is three times + this number, because it allows for the buffering of "before" and "after" + lines. */ +#undef PCRE2GREP_BUFSIZE + +/* to make a symbol visible */ +#undef PCRE2POSIX_EXP_DECL + +/* to make a symbol visible */ +#undef PCRE2POSIX_EXP_DEFN + +/* Define to any value to include debugging code. */ +#undef PCRE2_DEBUG + +/* to make a symbol visible */ +#undef PCRE2_EXP_DECL + + +/* If you are compiling for a system other than a Unix-like system or + Win32, and it needs some magic to be inserted before the definition + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +#undef PCRE2_EXP_DEFN + +/* Define to any value if linking statically (TODO: make nice with Libtool) */ +#undef PCRE2_STATIC + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to any value to enable support for Just-In-Time compiling. */ +#undef SUPPORT_JIT + +/* Define to any value to allow pcre2grep to be linked with libbz2, so that it + is able to handle .bz2 files. */ +#undef SUPPORT_LIBBZ2 + +/* Define to any value to allow pcre2test to be linked with libedit. */ +#undef SUPPORT_LIBEDIT + +/* Define to any value to allow pcre2test to be linked with libreadline. */ +#undef SUPPORT_LIBREADLINE + +/* Define to any value to allow pcre2grep to be linked with libz, so that it + is able to handle .gz files. */ +#undef SUPPORT_LIBZ + +/* Define to any value to enable JIT support in pcre2grep. */ +#undef SUPPORT_PCRE2GREP_JIT + +/* Define to any value to enable the 16 bit PCRE2 library. */ +#undef SUPPORT_PCRE2_16 + +/* Define to any value to enable the 32 bit PCRE2 library. */ +#undef SUPPORT_PCRE2_32 + +/* Define to any value to enable the 8 bit PCRE2 library. */ +#undef SUPPORT_PCRE2_8 + +/* Define to any value to enable support for Unicode and UTF encoding. This + will work even in an EBCDIC environment, but it is incompatible with the + EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or* + ASCII/Unicode, but not both at once. */ +#undef SUPPORT_UNICODE + +/* Define to any value for valgrind support to find invalid memory reads. */ +#undef SUPPORT_VALGRIND + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/pcre2/src/dftables.c b/pcre2/src/dftables.c new file mode 100644 index 000000000..dfb90b594 --- /dev/null +++ b/pcre2/src/dftables.c @@ -0,0 +1,214 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This is a freestanding support program to generate a file containing +character tables for PCRE2. The tables are built according to the current +locale using the pcre2_maketables() function, which is part of the PCRE2 API. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#define PCRE2_CODE_UNIT_WIDTH 0 /* Must be set, but not relevant here */ +#include "pcre2_internal.h" + +#define DFTABLES /* pcre2_maketables.c notices this */ +#include "pcre2_maketables.c" + +int main(int argc, char **argv) +{ +FILE *f; +int i = 1; +const unsigned char *tables; +const unsigned char *base_of_tables; + +/* By default, the default C locale is used rather than what the building user +happens to have set. However, if the -L option is given, set the locale from +the LC_xxx environment variables. */ + +if (argc > 1 && strcmp(argv[1], "-L") == 0) + { + setlocale(LC_ALL, ""); /* Set from environment variables */ + i++; + } + +if (argc < i + 1) + { + fprintf(stderr, "dftables: one filename argument is required\n"); + return 1; + } + +tables = maketables(); +base_of_tables = tables; + +f = fopen(argv[i], "wb"); +if (f == NULL) + { + fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); + return 1; + } + +/* There are several fprintf() calls here, because gcc in pedantic mode +complains about the very long string otherwise. */ + +fprintf(f, + "/*************************************************\n" + "* Perl-Compatible Regular Expressions *\n" + "*************************************************/\n\n" + "/* This file was automatically written by the dftables auxiliary\n" + "program. It contains character tables that are used when no external\n" + "tables are passed to PCRE2 by the application that calls it. The tables\n" + "are used only for characters whose code values are less than 256. */\n\n"); + +/* Force config.h in z/OS */ + +#if defined NATIVE_ZOS +fprintf(f, + "/* For z/OS, config.h is forced */\n" + "#ifndef HAVE_CONFIG_H\n" + "#define HAVE_CONFIG_H 1\n" + "#endif\n\n"); +#endif + +fprintf(f, + "/* The following #includes are present because without them gcc 4.x may remove\n" + "the array definition from the final binary if PCRE2 is built into a static\n" + "library and dead code stripping is activated. This leads to link errors.\n" + "Pulling in the header ensures that the array gets flagged as \"someone\n" + "outside this compilation unit might reference this\" and so it will always\n" + "be supplied to the linker. */\n\n"); + +fprintf(f, + "#ifdef HAVE_CONFIG_H\n" + "#include \"config.h\"\n" + "#endif\n\n" + "#include \"pcre2_internal.h\"\n\n"); + +fprintf(f, + "const uint8_t PRIV(default_tables)[] = {\n\n" + "/* This table is a lower casing table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, "/* This table is a case flipping table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table contains bit maps for various character classes.\n" + "Each map is 32 bytes long and the bits run from the least\n" + "significant end of each byte. The classes that have their own\n" + "maps are: space, xdigit, digit, upper, lower, word, graph\n" + "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < cbit_length; i++) + { + if ((i & 7) == 0 && i != 0) + { + if ((i & 31) == 0) fprintf(f, "\n"); + fprintf(f, "\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != cbit_length - 1) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table identifies various classes of character by individual bits:\n" + " 0x%02x white space character\n" + " 0x%02x letter\n" + " 0x%02x decimal digit\n" + " 0x%02x hexadecimal digit\n" + " 0x%02x alphanumeric or '_'\n" + " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", + ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, + ctype_meta); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) + { + fprintf(f, " /* "); + if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); + if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); + fprintf(f, " */\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != 255) fprintf(f, ","); + } + +fprintf(f, "};/* "); +if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); +if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); +fprintf(f, " */\n\n/* End of pcre2_chartables.c */\n"); + +fclose(f); +free((void *)base_of_tables); +return 0; +} + +/* End of dftables.c */ diff --git a/pcre2/src/pcre2.h.generic b/pcre2/src/pcre2.h.generic new file mode 100644 index 000000000..7f9ba4f19 --- /dev/null +++ b/pcre2/src/pcre2.h.generic @@ -0,0 +1,722 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This is the public header file for the PCRE library, second API, to be +#included by applications that call PCRE2 functions. + + Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE2_H +#define _PCRE2_H + +/* The current PCRE version information. */ + +#define PCRE2_MAJOR 10 +#define PCRE2_MINOR 21 +#define PCRE2_PRERELEASE +#define PCRE2_DATE 2016-01-12 + +/* When an application links to a PCRE DLL in Windows, the symbols that are +imported have to be identified as such. When building PCRE2, the appropriate +export setting is defined in pcre2_internal.h, which includes this file. So we +don't change existing definitions of PCRE2_EXP_DECL. */ + +#if defined(_WIN32) && !defined(PCRE2_STATIC) +# ifndef PCRE2_EXP_DECL +# define PCRE2_EXP_DECL extern __declspec(dllimport) +# endif +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE2_EXP_DECL +# ifdef __cplusplus +# define PCRE2_EXP_DECL extern "C" +# else +# define PCRE2_EXP_DECL extern +# endif +#endif + +/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and +uint8_t, UCHAR_MAX, etc are defined. */ + +#include +#include +#include + +/* Allow for C++ users compiling this directly. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following option bits can be passed to pcre2_compile(), pcre2_match(), +or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it +is passed. Put these bits at the most significant end of the options word so +others can be added next to them */ + +#define PCRE2_ANCHORED 0x80000000u +#define PCRE2_NO_UTF_CHECK 0x40000000u + +/* The following option bits can be passed only to pcre2_compile(). However, +they may affect compilation, JIT compilation, and/or interpretive execution. +The following tags indicate which: + +C alters what is compiled by pcre2_compile() +J alters what is compiled by pcre2_jit_compile() +M is inspected during pcre2_match() execution +D is inspected during pcre2_dfa_match() execution +*/ + +#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */ +#define PCRE2_ALT_BSUX 0x00000002u /* C */ +#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */ +#define PCRE2_CASELESS 0x00000008u /* C */ +#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */ +#define PCRE2_DOTALL 0x00000020u /* C */ +#define PCRE2_DUPNAMES 0x00000040u /* C */ +#define PCRE2_EXTENDED 0x00000080u /* C */ +#define PCRE2_FIRSTLINE 0x00000100u /* J M D */ +#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */ +#define PCRE2_MULTILINE 0x00000400u /* C */ +#define PCRE2_NEVER_UCP 0x00000800u /* C */ +#define PCRE2_NEVER_UTF 0x00001000u /* C */ +#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */ +#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */ +#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */ +#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */ +#define PCRE2_UCP 0x00020000u /* C J M D */ +#define PCRE2_UNGREEDY 0x00040000u /* C */ +#define PCRE2_UTF 0x00080000u /* C J M D */ +#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */ +#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */ +#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */ +#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */ + +/* These are for pcre2_jit_compile(). */ + +#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */ +#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u +#define PCRE2_JIT_PARTIAL_HARD 0x00000004u + +/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note +that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these +functions (though pcre2_jit_match() ignores the latter since it bypasses all +sanity checks). */ + +#define PCRE2_NOTBOL 0x00000001u +#define PCRE2_NOTEOL 0x00000002u +#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ +#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ +#define PCRE2_PARTIAL_SOFT 0x00000010u +#define PCRE2_PARTIAL_HARD 0x00000020u + +/* These are additional options for pcre2_dfa_match(). */ + +#define PCRE2_DFA_RESTART 0x00000040u +#define PCRE2_DFA_SHORTEST 0x00000080u + +/* These are additional options for pcre2_substitute(). */ + +#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u +#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u +#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u +#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u +#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u + +/* Newline and \R settings, for use in compile contexts. The newline values +must be kept in step with values set in config.h and both sets must all be +greater than zero. */ + +#define PCRE2_NEWLINE_CR 1 +#define PCRE2_NEWLINE_LF 2 +#define PCRE2_NEWLINE_CRLF 3 +#define PCRE2_NEWLINE_ANY 4 +#define PCRE2_NEWLINE_ANYCRLF 5 + +#define PCRE2_BSR_UNICODE 1 +#define PCRE2_BSR_ANYCRLF 2 + +/* Error codes: no match and partial match are "expected" errors. */ + +#define PCRE2_ERROR_NOMATCH (-1) +#define PCRE2_ERROR_PARTIAL (-2) + +/* Error codes for UTF-8 validity checks */ + +#define PCRE2_ERROR_UTF8_ERR1 (-3) +#define PCRE2_ERROR_UTF8_ERR2 (-4) +#define PCRE2_ERROR_UTF8_ERR3 (-5) +#define PCRE2_ERROR_UTF8_ERR4 (-6) +#define PCRE2_ERROR_UTF8_ERR5 (-7) +#define PCRE2_ERROR_UTF8_ERR6 (-8) +#define PCRE2_ERROR_UTF8_ERR7 (-9) +#define PCRE2_ERROR_UTF8_ERR8 (-10) +#define PCRE2_ERROR_UTF8_ERR9 (-11) +#define PCRE2_ERROR_UTF8_ERR10 (-12) +#define PCRE2_ERROR_UTF8_ERR11 (-13) +#define PCRE2_ERROR_UTF8_ERR12 (-14) +#define PCRE2_ERROR_UTF8_ERR13 (-15) +#define PCRE2_ERROR_UTF8_ERR14 (-16) +#define PCRE2_ERROR_UTF8_ERR15 (-17) +#define PCRE2_ERROR_UTF8_ERR16 (-18) +#define PCRE2_ERROR_UTF8_ERR17 (-19) +#define PCRE2_ERROR_UTF8_ERR18 (-20) +#define PCRE2_ERROR_UTF8_ERR19 (-21) +#define PCRE2_ERROR_UTF8_ERR20 (-22) +#define PCRE2_ERROR_UTF8_ERR21 (-23) + +/* Error codes for UTF-16 validity checks */ + +#define PCRE2_ERROR_UTF16_ERR1 (-24) +#define PCRE2_ERROR_UTF16_ERR2 (-25) +#define PCRE2_ERROR_UTF16_ERR3 (-26) + +/* Error codes for UTF-32 validity checks */ + +#define PCRE2_ERROR_UTF32_ERR1 (-27) +#define PCRE2_ERROR_UTF32_ERR2 (-28) + +/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context +functions, and serializing functions. They are in numerical order. Originally +they were in alphabetical order too, but now that PCRE2 is released, the +numbers must not be changed. */ + +#define PCRE2_ERROR_BADDATA (-29) +#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */ +#define PCRE2_ERROR_BADMAGIC (-31) +#define PCRE2_ERROR_BADMODE (-32) +#define PCRE2_ERROR_BADOFFSET (-33) +#define PCRE2_ERROR_BADOPTION (-34) +#define PCRE2_ERROR_BADREPLACEMENT (-35) +#define PCRE2_ERROR_BADUTFOFFSET (-36) +#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */ +#define PCRE2_ERROR_DFA_BADRESTART (-38) +#define PCRE2_ERROR_DFA_RECURSE (-39) +#define PCRE2_ERROR_DFA_UCOND (-40) +#define PCRE2_ERROR_DFA_UFUNC (-41) +#define PCRE2_ERROR_DFA_UITEM (-42) +#define PCRE2_ERROR_DFA_WSSIZE (-43) +#define PCRE2_ERROR_INTERNAL (-44) +#define PCRE2_ERROR_JIT_BADOPTION (-45) +#define PCRE2_ERROR_JIT_STACKLIMIT (-46) +#define PCRE2_ERROR_MATCHLIMIT (-47) +#define PCRE2_ERROR_NOMEMORY (-48) +#define PCRE2_ERROR_NOSUBSTRING (-49) +#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) +#define PCRE2_ERROR_NULL (-51) +#define PCRE2_ERROR_RECURSELOOP (-52) +#define PCRE2_ERROR_RECURSIONLIMIT (-53) +#define PCRE2_ERROR_UNAVAILABLE (-54) +#define PCRE2_ERROR_UNSET (-55) +#define PCRE2_ERROR_BADOFFSETLIMIT (-56) +#define PCRE2_ERROR_BADREPESCAPE (-57) +#define PCRE2_ERROR_REPMISSINGBRACE (-58) +#define PCRE2_ERROR_BADSUBSTITUTION (-59) +#define PCRE2_ERROR_BADSUBSPATTERN (-60) +#define PCRE2_ERROR_TOOMANYREPLACE (-61) + +/* Request types for pcre2_pattern_info() */ + +#define PCRE2_INFO_ALLOPTIONS 0 +#define PCRE2_INFO_ARGOPTIONS 1 +#define PCRE2_INFO_BACKREFMAX 2 +#define PCRE2_INFO_BSR 3 +#define PCRE2_INFO_CAPTURECOUNT 4 +#define PCRE2_INFO_FIRSTCODEUNIT 5 +#define PCRE2_INFO_FIRSTCODETYPE 6 +#define PCRE2_INFO_FIRSTBITMAP 7 +#define PCRE2_INFO_HASCRORLF 8 +#define PCRE2_INFO_JCHANGED 9 +#define PCRE2_INFO_JITSIZE 10 +#define PCRE2_INFO_LASTCODEUNIT 11 +#define PCRE2_INFO_LASTCODETYPE 12 +#define PCRE2_INFO_MATCHEMPTY 13 +#define PCRE2_INFO_MATCHLIMIT 14 +#define PCRE2_INFO_MAXLOOKBEHIND 15 +#define PCRE2_INFO_MINLENGTH 16 +#define PCRE2_INFO_NAMECOUNT 17 +#define PCRE2_INFO_NAMEENTRYSIZE 18 +#define PCRE2_INFO_NAMETABLE 19 +#define PCRE2_INFO_NEWLINE 20 +#define PCRE2_INFO_RECURSIONLIMIT 21 +#define PCRE2_INFO_SIZE 22 +#define PCRE2_INFO_HASBACKSLASHC 23 + +/* Request types for pcre2_config(). */ + +#define PCRE2_CONFIG_BSR 0 +#define PCRE2_CONFIG_JIT 1 +#define PCRE2_CONFIG_JITTARGET 2 +#define PCRE2_CONFIG_LINKSIZE 3 +#define PCRE2_CONFIG_MATCHLIMIT 4 +#define PCRE2_CONFIG_NEWLINE 5 +#define PCRE2_CONFIG_PARENSLIMIT 6 +#define PCRE2_CONFIG_RECURSIONLIMIT 7 +#define PCRE2_CONFIG_STACKRECURSE 8 +#define PCRE2_CONFIG_UNICODE 9 +#define PCRE2_CONFIG_UNICODE_VERSION 10 +#define PCRE2_CONFIG_VERSION 11 + +/* Types for code units in patterns and subject strings. */ + +typedef uint8_t PCRE2_UCHAR8; +typedef uint16_t PCRE2_UCHAR16; +typedef uint32_t PCRE2_UCHAR32; + +typedef const PCRE2_UCHAR8 *PCRE2_SPTR8; +typedef const PCRE2_UCHAR16 *PCRE2_SPTR16; +typedef const PCRE2_UCHAR32 *PCRE2_SPTR32; + +/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2, +including pattern offsets for errors and subject offsets after a match. We +define special values to indicate zero-terminated strings and unset offsets in +the offset vector (ovector). */ + +#define PCRE2_SIZE size_t +#define PCRE2_SIZE_MAX SIZE_MAX +#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0) +#define PCRE2_UNSET (~(PCRE2_SIZE)0) + +/* Generic types for opaque structures and JIT callback functions. These +declarations are defined in a macro that is expanded for each width later. */ + +#define PCRE2_TYPES_LIST \ +struct pcre2_real_general_context; \ +typedef struct pcre2_real_general_context pcre2_general_context; \ +\ +struct pcre2_real_compile_context; \ +typedef struct pcre2_real_compile_context pcre2_compile_context; \ +\ +struct pcre2_real_match_context; \ +typedef struct pcre2_real_match_context pcre2_match_context; \ +\ +struct pcre2_real_code; \ +typedef struct pcre2_real_code pcre2_code; \ +\ +struct pcre2_real_match_data; \ +typedef struct pcre2_real_match_data pcre2_match_data; \ +\ +struct pcre2_real_jit_stack; \ +typedef struct pcre2_real_jit_stack pcre2_jit_stack; \ +\ +typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *); + + +/* The structure for passing out data via the pcre_callout_function. We use a +structure so that new fields can be added on the end in future versions, +without changing the API of the function, thereby allowing old clients to work +without modification. Define the generic version in a macro; the width-specific +versions are generated from this macro below. */ + +#define PCRE2_STRUCTURE_LIST \ +typedef struct pcre2_callout_block { \ + uint32_t version; /* Identifies version of block */ \ + /* ------------------------ Version 0 ------------------------------- */ \ + uint32_t callout_number; /* Number compiled into pattern */ \ + uint32_t capture_top; /* Max current capture */ \ + uint32_t capture_last; /* Most recently closed capture */ \ + PCRE2_SIZE *offset_vector; /* The offset vector */ \ + PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \ + PCRE2_SPTR subject; /* The subject being matched */ \ + PCRE2_SIZE subject_length; /* The length of the subject */ \ + PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \ + PCRE2_SIZE current_position; /* Where we currently are in the subject */ \ + PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ + PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ + /* ------------------- Added for Version 1 -------------------------- */ \ + PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ + PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ + PCRE2_SPTR callout_string; /* String compiled into pattern */ \ + /* ------------------------------------------------------------------ */ \ +} pcre2_callout_block; \ +\ +typedef struct pcre2_callout_enumerate_block { \ + uint32_t version; /* Identifies version of block */ \ + /* ------------------------ Version 0 ------------------------------- */ \ + PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ + PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ + uint32_t callout_number; /* Number compiled into pattern */ \ + PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ + PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ + PCRE2_SPTR callout_string; /* String compiled into pattern */ \ + /* ------------------------------------------------------------------ */ \ +} pcre2_callout_enumerate_block; + + +/* List the generic forms of all other functions in macros, which will be +expanded for each width below. Start with functions that give general +information. */ + +#define PCRE2_GENERAL_INFO_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_config(uint32_t, void *); + + +/* Functions for manipulating contexts. */ + +#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_general_context *pcre2_general_context_create( \ + void *(*)(PCRE2_SIZE, void *), \ + void (*)(void *, void *), void *); \ +PCRE2_EXP_DECL void pcre2_general_context_free(pcre2_general_context *); + +#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \ +PCRE2_EXP_DECL \ + pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\ +PCRE2_EXP_DECL void pcre2_compile_context_free(pcre2_compile_context *); \ +PCRE2_EXP_DECL int pcre2_set_bsr(pcre2_compile_context *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_character_tables(pcre2_compile_context *, \ + const unsigned char *); \ +PCRE2_EXP_DECL int pcre2_set_max_pattern_length(pcre2_compile_context *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_set_newline(pcre2_compile_context *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_parens_nest_limit(pcre2_compile_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_compile_recursion_guard(\ + pcre2_compile_context *, int (*)(uint32_t, void *), \ + void *); + +#define PCRE2_MATCH_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_match_context *pcre2_match_context_copy(pcre2_match_context *); \ +PCRE2_EXP_DECL \ + pcre2_match_context *pcre2_match_context_create(pcre2_general_context *); \ +PCRE2_EXP_DECL void pcre2_match_context_free(pcre2_match_context *); \ +PCRE2_EXP_DECL int pcre2_set_callout(pcre2_match_context *, \ + int (*)(pcre2_callout_block *, void *), void *); \ +PCRE2_EXP_DECL int pcre2_set_match_limit(pcre2_match_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_offset_limit(pcre2_match_context *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_set_recursion_limit(pcre2_match_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ + pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \ + void (*)(void *, void *), void *); + + +/* Functions concerned with compiling a pattern to PCRE internal code. */ + +#define PCRE2_COMPILE_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ + int *, PCRE2_SIZE *, pcre2_compile_context *); \ +PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); + + +/* Functions that give information about a compiled pattern. */ + +#define PCRE2_PATTERN_INFO_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_pattern_info(const pcre2_code *, uint32_t, \ + void *); \ +PCRE2_EXP_DECL int pcre2_callout_enumerate(const pcre2_code *, \ + int (*)(pcre2_callout_enumerate_block *, void *), \ + void *); + + +/* Functions for running a match and inspecting the result. */ + +#define PCRE2_MATCH_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_match_data *pcre2_match_data_create(uint32_t, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_match_data *pcre2_match_data_create_from_pattern(\ + const pcre2_code *, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL int pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \ + PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *, int *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_match(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *); \ +PCRE2_EXP_DECL void pcre2_match_data_free(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SPTR pcre2_get_mark(pcre2_match_data *); \ +PCRE2_EXP_DECL uint32_t pcre2_get_ovector_count(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE pcre2_get_startchar(pcre2_match_data *); + + +/* Convenience functions for handling matched substrings. */ + +#define PCRE2_SUBSTRING_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_substring_copy_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_copy_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \ +PCRE2_EXP_DECL void pcre2_substring_free(PCRE2_UCHAR *); \ +PCRE2_EXP_DECL int pcre2_substring_get_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_get_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_length_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_length_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_nametable_scan(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \ +PCRE2_EXP_DECL int pcre2_substring_number_from_name(\ + const pcre2_code *, PCRE2_SPTR); \ +PCRE2_EXP_DECL void pcre2_substring_list_free(PCRE2_SPTR *); \ +PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \ + PCRE2_UCHAR ***, PCRE2_SIZE **); + +/* Functions for serializing / deserializing compiled patterns. */ + +#define PCRE2_SERIALIZE_FUNCTIONS \ +PCRE2_EXP_DECL int32_t pcre2_serialize_encode(const pcre2_code **, \ + int32_t, uint8_t **, PCRE2_SIZE *, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL int32_t pcre2_serialize_decode(pcre2_code **, int32_t, \ + const uint8_t *, pcre2_general_context *); \ +PCRE2_EXP_DECL int32_t pcre2_serialize_get_number_of_codes(const uint8_t *); \ +PCRE2_EXP_DECL void pcre2_serialize_free(uint8_t *); + + +/* Convenience function for match + substitute. */ + +#define PCRE2_SUBSTITUTE_FUNCTION \ +PCRE2_EXP_DECL int pcre2_substitute(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \ + PCRE2_SIZE *); + + +/* Functions for JIT processing */ + +#define PCRE2_JIT_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *); \ +PCRE2_EXP_DECL void pcre2_jit_free_unused_memory(pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_jit_stack *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL void pcre2_jit_stack_assign(pcre2_match_context *, \ + pcre2_jit_callback, void *); \ +PCRE2_EXP_DECL void pcre2_jit_stack_free(pcre2_jit_stack *); + + +/* Other miscellaneous functions. */ + +#define PCRE2_OTHER_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \ +PCRE2_EXP_DECL \ + const uint8_t *pcre2_maketables(pcre2_general_context *); \ + + +/* Define macros that generate width-specific names from generic versions. The +three-level macro scheme is necessary to get the macros expanded when we want +them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for +generating three versions of everything below. After that, PCRE2_SUFFIX will be +re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as +pcre2_compile are called by application code. */ + +#define PCRE2_JOIN(a,b) a ## b +#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b) +#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH) + + +/* Data types */ + +#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR) +#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR) + +#define pcre2_code PCRE2_SUFFIX(pcre2_code_) +#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_) +#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_) + +#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_) +#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_) +#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_) +#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_) +#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_) +#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_) + + +/* Data blocks */ + +#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_) +#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_) +#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_) +#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_) +#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_) +#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_) + + +/* Functions: the complete list in alphabetical order */ + +#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) +#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) +#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) +#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) +#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_) +#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_) +#define pcre2_config PCRE2_SUFFIX(pcre2_config_) +#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_) +#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_) +#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_) +#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) +#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) +#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) +#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) +#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) +#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_) +#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_) +#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_) +#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_) +#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_) +#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_) +#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_) +#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_) +#define pcre2_match PCRE2_SUFFIX(pcre2_match_) +#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_) +#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_) +#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_) +#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_) +#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_) +#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_) +#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_) +#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_) +#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_) +#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_) +#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_) +#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_) +#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) +#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) +#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) +#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) +#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) +#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) +#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) +#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) +#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_) +#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_) +#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) +#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) +#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) +#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_) +#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_) +#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_) +#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_) +#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_) +#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_) +#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_) +#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) +#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) + + +/* Now generate all three sets of width-specific structures and function +prototypes. */ + +#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \ +PCRE2_TYPES_LIST \ +PCRE2_STRUCTURE_LIST \ +PCRE2_GENERAL_INFO_FUNCTIONS \ +PCRE2_GENERAL_CONTEXT_FUNCTIONS \ +PCRE2_COMPILE_CONTEXT_FUNCTIONS \ +PCRE2_MATCH_CONTEXT_FUNCTIONS \ +PCRE2_COMPILE_FUNCTIONS \ +PCRE2_PATTERN_INFO_FUNCTIONS \ +PCRE2_MATCH_FUNCTIONS \ +PCRE2_SUBSTRING_FUNCTIONS \ +PCRE2_SERIALIZE_FUNCTIONS \ +PCRE2_SUBSTITUTE_FUNCTION \ +PCRE2_JIT_FUNCTIONS \ +PCRE2_OTHER_FUNCTIONS + +#define PCRE2_LOCAL_WIDTH 8 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +#define PCRE2_LOCAL_WIDTH 16 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +#define PCRE2_LOCAL_WIDTH 32 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +/* Undefine the list macros; they are no longer needed. */ + +#undef PCRE2_TYPES_LIST +#undef PCRE2_STRUCTURE_LIST +#undef PCRE2_GENERAL_INFO_FUNCTIONS +#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS +#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS +#undef PCRE2_MATCH_CONTEXT_FUNCTIONS +#undef PCRE2_COMPILE_FUNCTIONS +#undef PCRE2_PATTERN_INFO_FUNCTIONS +#undef PCRE2_MATCH_FUNCTIONS +#undef PCRE2_SUBSTRING_FUNCTIONS +#undef PCRE2_SERIALIZE_FUNCTIONS +#undef PCRE2_SUBSTITUTE_FUNCTION +#undef PCRE2_JIT_FUNCTIONS +#undef PCRE2_OTHER_FUNCTIONS +#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS + +/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine +PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make +PCRE2_SUFFIX a no-op. Otherwise, generate an error. */ + +#undef PCRE2_SUFFIX +#ifndef PCRE2_CODE_UNIT_WIDTH +#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h. +#error Use 8, 16, or 32; or 0 for a multi-width application. +#else /* PCRE2_CODE_UNIT_WIDTH is defined */ +#if PCRE2_CODE_UNIT_WIDTH == 8 || \ + PCRE2_CODE_UNIT_WIDTH == 16 || \ + PCRE2_CODE_UNIT_WIDTH == 32 +#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH) +#elif PCRE2_CODE_UNIT_WIDTH == 0 +#undef PCRE2_JOIN +#undef PCRE2_GLUE +#define PCRE2_SUFFIX(a) a +#else +#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32. +#endif +#endif /* PCRE2_CODE_UNIT_WIDTH is defined */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre2.h */ diff --git a/pcre2/src/pcre2.h.in b/pcre2/src/pcre2.h.in new file mode 100644 index 000000000..49f190965 --- /dev/null +++ b/pcre2/src/pcre2.h.in @@ -0,0 +1,722 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This is the public header file for the PCRE library, second API, to be +#included by applications that call PCRE2 functions. + + Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE2_H +#define _PCRE2_H + +/* The current PCRE version information. */ + +#define PCRE2_MAJOR @PCRE2_MAJOR@ +#define PCRE2_MINOR @PCRE2_MINOR@ +#define PCRE2_PRERELEASE @PCRE2_PRERELEASE@ +#define PCRE2_DATE @PCRE2_DATE@ + +/* When an application links to a PCRE DLL in Windows, the symbols that are +imported have to be identified as such. When building PCRE2, the appropriate +export setting is defined in pcre2_internal.h, which includes this file. So we +don't change existing definitions of PCRE2_EXP_DECL. */ + +#if defined(_WIN32) && !defined(PCRE2_STATIC) +# ifndef PCRE2_EXP_DECL +# define PCRE2_EXP_DECL extern __declspec(dllimport) +# endif +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE2_EXP_DECL +# ifdef __cplusplus +# define PCRE2_EXP_DECL extern "C" +# else +# define PCRE2_EXP_DECL extern +# endif +#endif + +/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and +uint8_t, UCHAR_MAX, etc are defined. */ + +#include +#include +#include + +/* Allow for C++ users compiling this directly. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following option bits can be passed to pcre2_compile(), pcre2_match(), +or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it +is passed. Put these bits at the most significant end of the options word so +others can be added next to them */ + +#define PCRE2_ANCHORED 0x80000000u +#define PCRE2_NO_UTF_CHECK 0x40000000u + +/* The following option bits can be passed only to pcre2_compile(). However, +they may affect compilation, JIT compilation, and/or interpretive execution. +The following tags indicate which: + +C alters what is compiled by pcre2_compile() +J alters what is compiled by pcre2_jit_compile() +M is inspected during pcre2_match() execution +D is inspected during pcre2_dfa_match() execution +*/ + +#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */ +#define PCRE2_ALT_BSUX 0x00000002u /* C */ +#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */ +#define PCRE2_CASELESS 0x00000008u /* C */ +#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */ +#define PCRE2_DOTALL 0x00000020u /* C */ +#define PCRE2_DUPNAMES 0x00000040u /* C */ +#define PCRE2_EXTENDED 0x00000080u /* C */ +#define PCRE2_FIRSTLINE 0x00000100u /* J M D */ +#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */ +#define PCRE2_MULTILINE 0x00000400u /* C */ +#define PCRE2_NEVER_UCP 0x00000800u /* C */ +#define PCRE2_NEVER_UTF 0x00001000u /* C */ +#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */ +#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */ +#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */ +#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */ +#define PCRE2_UCP 0x00020000u /* C J M D */ +#define PCRE2_UNGREEDY 0x00040000u /* C */ +#define PCRE2_UTF 0x00080000u /* C J M D */ +#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */ +#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */ +#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */ +#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */ + +/* These are for pcre2_jit_compile(). */ + +#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */ +#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u +#define PCRE2_JIT_PARTIAL_HARD 0x00000004u + +/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note +that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these +functions (though pcre2_jit_match() ignores the latter since it bypasses all +sanity checks). */ + +#define PCRE2_NOTBOL 0x00000001u +#define PCRE2_NOTEOL 0x00000002u +#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ +#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ +#define PCRE2_PARTIAL_SOFT 0x00000010u +#define PCRE2_PARTIAL_HARD 0x00000020u + +/* These are additional options for pcre2_dfa_match(). */ + +#define PCRE2_DFA_RESTART 0x00000040u +#define PCRE2_DFA_SHORTEST 0x00000080u + +/* These are additional options for pcre2_substitute(). */ + +#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u +#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u +#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u +#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u +#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u + +/* Newline and \R settings, for use in compile contexts. The newline values +must be kept in step with values set in config.h and both sets must all be +greater than zero. */ + +#define PCRE2_NEWLINE_CR 1 +#define PCRE2_NEWLINE_LF 2 +#define PCRE2_NEWLINE_CRLF 3 +#define PCRE2_NEWLINE_ANY 4 +#define PCRE2_NEWLINE_ANYCRLF 5 + +#define PCRE2_BSR_UNICODE 1 +#define PCRE2_BSR_ANYCRLF 2 + +/* Error codes: no match and partial match are "expected" errors. */ + +#define PCRE2_ERROR_NOMATCH (-1) +#define PCRE2_ERROR_PARTIAL (-2) + +/* Error codes for UTF-8 validity checks */ + +#define PCRE2_ERROR_UTF8_ERR1 (-3) +#define PCRE2_ERROR_UTF8_ERR2 (-4) +#define PCRE2_ERROR_UTF8_ERR3 (-5) +#define PCRE2_ERROR_UTF8_ERR4 (-6) +#define PCRE2_ERROR_UTF8_ERR5 (-7) +#define PCRE2_ERROR_UTF8_ERR6 (-8) +#define PCRE2_ERROR_UTF8_ERR7 (-9) +#define PCRE2_ERROR_UTF8_ERR8 (-10) +#define PCRE2_ERROR_UTF8_ERR9 (-11) +#define PCRE2_ERROR_UTF8_ERR10 (-12) +#define PCRE2_ERROR_UTF8_ERR11 (-13) +#define PCRE2_ERROR_UTF8_ERR12 (-14) +#define PCRE2_ERROR_UTF8_ERR13 (-15) +#define PCRE2_ERROR_UTF8_ERR14 (-16) +#define PCRE2_ERROR_UTF8_ERR15 (-17) +#define PCRE2_ERROR_UTF8_ERR16 (-18) +#define PCRE2_ERROR_UTF8_ERR17 (-19) +#define PCRE2_ERROR_UTF8_ERR18 (-20) +#define PCRE2_ERROR_UTF8_ERR19 (-21) +#define PCRE2_ERROR_UTF8_ERR20 (-22) +#define PCRE2_ERROR_UTF8_ERR21 (-23) + +/* Error codes for UTF-16 validity checks */ + +#define PCRE2_ERROR_UTF16_ERR1 (-24) +#define PCRE2_ERROR_UTF16_ERR2 (-25) +#define PCRE2_ERROR_UTF16_ERR3 (-26) + +/* Error codes for UTF-32 validity checks */ + +#define PCRE2_ERROR_UTF32_ERR1 (-27) +#define PCRE2_ERROR_UTF32_ERR2 (-28) + +/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context +functions, and serializing functions. They are in numerical order. Originally +they were in alphabetical order too, but now that PCRE2 is released, the +numbers must not be changed. */ + +#define PCRE2_ERROR_BADDATA (-29) +#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */ +#define PCRE2_ERROR_BADMAGIC (-31) +#define PCRE2_ERROR_BADMODE (-32) +#define PCRE2_ERROR_BADOFFSET (-33) +#define PCRE2_ERROR_BADOPTION (-34) +#define PCRE2_ERROR_BADREPLACEMENT (-35) +#define PCRE2_ERROR_BADUTFOFFSET (-36) +#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */ +#define PCRE2_ERROR_DFA_BADRESTART (-38) +#define PCRE2_ERROR_DFA_RECURSE (-39) +#define PCRE2_ERROR_DFA_UCOND (-40) +#define PCRE2_ERROR_DFA_UFUNC (-41) +#define PCRE2_ERROR_DFA_UITEM (-42) +#define PCRE2_ERROR_DFA_WSSIZE (-43) +#define PCRE2_ERROR_INTERNAL (-44) +#define PCRE2_ERROR_JIT_BADOPTION (-45) +#define PCRE2_ERROR_JIT_STACKLIMIT (-46) +#define PCRE2_ERROR_MATCHLIMIT (-47) +#define PCRE2_ERROR_NOMEMORY (-48) +#define PCRE2_ERROR_NOSUBSTRING (-49) +#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) +#define PCRE2_ERROR_NULL (-51) +#define PCRE2_ERROR_RECURSELOOP (-52) +#define PCRE2_ERROR_RECURSIONLIMIT (-53) +#define PCRE2_ERROR_UNAVAILABLE (-54) +#define PCRE2_ERROR_UNSET (-55) +#define PCRE2_ERROR_BADOFFSETLIMIT (-56) +#define PCRE2_ERROR_BADREPESCAPE (-57) +#define PCRE2_ERROR_REPMISSINGBRACE (-58) +#define PCRE2_ERROR_BADSUBSTITUTION (-59) +#define PCRE2_ERROR_BADSUBSPATTERN (-60) +#define PCRE2_ERROR_TOOMANYREPLACE (-61) + +/* Request types for pcre2_pattern_info() */ + +#define PCRE2_INFO_ALLOPTIONS 0 +#define PCRE2_INFO_ARGOPTIONS 1 +#define PCRE2_INFO_BACKREFMAX 2 +#define PCRE2_INFO_BSR 3 +#define PCRE2_INFO_CAPTURECOUNT 4 +#define PCRE2_INFO_FIRSTCODEUNIT 5 +#define PCRE2_INFO_FIRSTCODETYPE 6 +#define PCRE2_INFO_FIRSTBITMAP 7 +#define PCRE2_INFO_HASCRORLF 8 +#define PCRE2_INFO_JCHANGED 9 +#define PCRE2_INFO_JITSIZE 10 +#define PCRE2_INFO_LASTCODEUNIT 11 +#define PCRE2_INFO_LASTCODETYPE 12 +#define PCRE2_INFO_MATCHEMPTY 13 +#define PCRE2_INFO_MATCHLIMIT 14 +#define PCRE2_INFO_MAXLOOKBEHIND 15 +#define PCRE2_INFO_MINLENGTH 16 +#define PCRE2_INFO_NAMECOUNT 17 +#define PCRE2_INFO_NAMEENTRYSIZE 18 +#define PCRE2_INFO_NAMETABLE 19 +#define PCRE2_INFO_NEWLINE 20 +#define PCRE2_INFO_RECURSIONLIMIT 21 +#define PCRE2_INFO_SIZE 22 +#define PCRE2_INFO_HASBACKSLASHC 23 + +/* Request types for pcre2_config(). */ + +#define PCRE2_CONFIG_BSR 0 +#define PCRE2_CONFIG_JIT 1 +#define PCRE2_CONFIG_JITTARGET 2 +#define PCRE2_CONFIG_LINKSIZE 3 +#define PCRE2_CONFIG_MATCHLIMIT 4 +#define PCRE2_CONFIG_NEWLINE 5 +#define PCRE2_CONFIG_PARENSLIMIT 6 +#define PCRE2_CONFIG_RECURSIONLIMIT 7 +#define PCRE2_CONFIG_STACKRECURSE 8 +#define PCRE2_CONFIG_UNICODE 9 +#define PCRE2_CONFIG_UNICODE_VERSION 10 +#define PCRE2_CONFIG_VERSION 11 + +/* Types for code units in patterns and subject strings. */ + +typedef uint8_t PCRE2_UCHAR8; +typedef uint16_t PCRE2_UCHAR16; +typedef uint32_t PCRE2_UCHAR32; + +typedef const PCRE2_UCHAR8 *PCRE2_SPTR8; +typedef const PCRE2_UCHAR16 *PCRE2_SPTR16; +typedef const PCRE2_UCHAR32 *PCRE2_SPTR32; + +/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2, +including pattern offsets for errors and subject offsets after a match. We +define special values to indicate zero-terminated strings and unset offsets in +the offset vector (ovector). */ + +#define PCRE2_SIZE size_t +#define PCRE2_SIZE_MAX SIZE_MAX +#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0) +#define PCRE2_UNSET (~(PCRE2_SIZE)0) + +/* Generic types for opaque structures and JIT callback functions. These +declarations are defined in a macro that is expanded for each width later. */ + +#define PCRE2_TYPES_LIST \ +struct pcre2_real_general_context; \ +typedef struct pcre2_real_general_context pcre2_general_context; \ +\ +struct pcre2_real_compile_context; \ +typedef struct pcre2_real_compile_context pcre2_compile_context; \ +\ +struct pcre2_real_match_context; \ +typedef struct pcre2_real_match_context pcre2_match_context; \ +\ +struct pcre2_real_code; \ +typedef struct pcre2_real_code pcre2_code; \ +\ +struct pcre2_real_match_data; \ +typedef struct pcre2_real_match_data pcre2_match_data; \ +\ +struct pcre2_real_jit_stack; \ +typedef struct pcre2_real_jit_stack pcre2_jit_stack; \ +\ +typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *); + + +/* The structure for passing out data via the pcre_callout_function. We use a +structure so that new fields can be added on the end in future versions, +without changing the API of the function, thereby allowing old clients to work +without modification. Define the generic version in a macro; the width-specific +versions are generated from this macro below. */ + +#define PCRE2_STRUCTURE_LIST \ +typedef struct pcre2_callout_block { \ + uint32_t version; /* Identifies version of block */ \ + /* ------------------------ Version 0 ------------------------------- */ \ + uint32_t callout_number; /* Number compiled into pattern */ \ + uint32_t capture_top; /* Max current capture */ \ + uint32_t capture_last; /* Most recently closed capture */ \ + PCRE2_SIZE *offset_vector; /* The offset vector */ \ + PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \ + PCRE2_SPTR subject; /* The subject being matched */ \ + PCRE2_SIZE subject_length; /* The length of the subject */ \ + PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \ + PCRE2_SIZE current_position; /* Where we currently are in the subject */ \ + PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ + PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ + /* ------------------- Added for Version 1 -------------------------- */ \ + PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ + PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ + PCRE2_SPTR callout_string; /* String compiled into pattern */ \ + /* ------------------------------------------------------------------ */ \ +} pcre2_callout_block; \ +\ +typedef struct pcre2_callout_enumerate_block { \ + uint32_t version; /* Identifies version of block */ \ + /* ------------------------ Version 0 ------------------------------- */ \ + PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ + PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ + uint32_t callout_number; /* Number compiled into pattern */ \ + PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ + PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ + PCRE2_SPTR callout_string; /* String compiled into pattern */ \ + /* ------------------------------------------------------------------ */ \ +} pcre2_callout_enumerate_block; + + +/* List the generic forms of all other functions in macros, which will be +expanded for each width below. Start with functions that give general +information. */ + +#define PCRE2_GENERAL_INFO_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_config(uint32_t, void *); + + +/* Functions for manipulating contexts. */ + +#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_general_context *pcre2_general_context_create( \ + void *(*)(PCRE2_SIZE, void *), \ + void (*)(void *, void *), void *); \ +PCRE2_EXP_DECL void pcre2_general_context_free(pcre2_general_context *); + +#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \ +PCRE2_EXP_DECL \ + pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\ +PCRE2_EXP_DECL void pcre2_compile_context_free(pcre2_compile_context *); \ +PCRE2_EXP_DECL int pcre2_set_bsr(pcre2_compile_context *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_character_tables(pcre2_compile_context *, \ + const unsigned char *); \ +PCRE2_EXP_DECL int pcre2_set_max_pattern_length(pcre2_compile_context *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_set_newline(pcre2_compile_context *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_parens_nest_limit(pcre2_compile_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_compile_recursion_guard(\ + pcre2_compile_context *, int (*)(uint32_t, void *), \ + void *); + +#define PCRE2_MATCH_CONTEXT_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_match_context *pcre2_match_context_copy(pcre2_match_context *); \ +PCRE2_EXP_DECL \ + pcre2_match_context *pcre2_match_context_create(pcre2_general_context *); \ +PCRE2_EXP_DECL void pcre2_match_context_free(pcre2_match_context *); \ +PCRE2_EXP_DECL int pcre2_set_callout(pcre2_match_context *, \ + int (*)(pcre2_callout_block *, void *), void *); \ +PCRE2_EXP_DECL int pcre2_set_match_limit(pcre2_match_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_offset_limit(pcre2_match_context *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_set_recursion_limit(pcre2_match_context *, \ + uint32_t); \ +PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ + pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \ + void (*)(void *, void *), void *); + + +/* Functions concerned with compiling a pattern to PCRE internal code. */ + +#define PCRE2_COMPILE_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ + int *, PCRE2_SIZE *, pcre2_compile_context *); \ +PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); + + +/* Functions that give information about a compiled pattern. */ + +#define PCRE2_PATTERN_INFO_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_pattern_info(const pcre2_code *, uint32_t, \ + void *); \ +PCRE2_EXP_DECL int pcre2_callout_enumerate(const pcre2_code *, \ + int (*)(pcre2_callout_enumerate_block *, void *), \ + void *); + + +/* Functions for running a match and inspecting the result. */ + +#define PCRE2_MATCH_FUNCTIONS \ +PCRE2_EXP_DECL \ + pcre2_match_data *pcre2_match_data_create(uint32_t, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_match_data *pcre2_match_data_create_from_pattern(\ + const pcre2_code *, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL int pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \ + PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *, int *, \ + PCRE2_SIZE); \ +PCRE2_EXP_DECL int pcre2_match(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *); \ +PCRE2_EXP_DECL void pcre2_match_data_free(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SPTR pcre2_get_mark(pcre2_match_data *); \ +PCRE2_EXP_DECL uint32_t pcre2_get_ovector_count(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE pcre2_get_startchar(pcre2_match_data *); + + +/* Convenience functions for handling matched substrings. */ + +#define PCRE2_SUBSTRING_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_substring_copy_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_copy_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \ +PCRE2_EXP_DECL void pcre2_substring_free(PCRE2_UCHAR *); \ +PCRE2_EXP_DECL int pcre2_substring_get_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_get_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_length_byname(pcre2_match_data *, \ + PCRE2_SPTR, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_length_bynumber(pcre2_match_data *, \ + uint32_t, PCRE2_SIZE *); \ +PCRE2_EXP_DECL int pcre2_substring_nametable_scan(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \ +PCRE2_EXP_DECL int pcre2_substring_number_from_name(\ + const pcre2_code *, PCRE2_SPTR); \ +PCRE2_EXP_DECL void pcre2_substring_list_free(PCRE2_SPTR *); \ +PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \ + PCRE2_UCHAR ***, PCRE2_SIZE **); + +/* Functions for serializing / deserializing compiled patterns. */ + +#define PCRE2_SERIALIZE_FUNCTIONS \ +PCRE2_EXP_DECL int32_t pcre2_serialize_encode(const pcre2_code **, \ + int32_t, uint8_t **, PCRE2_SIZE *, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL int32_t pcre2_serialize_decode(pcre2_code **, int32_t, \ + const uint8_t *, pcre2_general_context *); \ +PCRE2_EXP_DECL int32_t pcre2_serialize_get_number_of_codes(const uint8_t *); \ +PCRE2_EXP_DECL void pcre2_serialize_free(uint8_t *); + + +/* Convenience function for match + substitute. */ + +#define PCRE2_SUBSTITUTE_FUNCTION \ +PCRE2_EXP_DECL int pcre2_substitute(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \ + PCRE2_SIZE *); + + +/* Functions for JIT processing */ + +#define PCRE2_JIT_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t); \ +PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ + PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ + pcre2_match_data *, pcre2_match_context *); \ +PCRE2_EXP_DECL void pcre2_jit_free_unused_memory(pcre2_general_context *); \ +PCRE2_EXP_DECL \ + pcre2_jit_stack *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \ + pcre2_general_context *); \ +PCRE2_EXP_DECL void pcre2_jit_stack_assign(pcre2_match_context *, \ + pcre2_jit_callback, void *); \ +PCRE2_EXP_DECL void pcre2_jit_stack_free(pcre2_jit_stack *); + + +/* Other miscellaneous functions. */ + +#define PCRE2_OTHER_FUNCTIONS \ +PCRE2_EXP_DECL int pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \ +PCRE2_EXP_DECL \ + const uint8_t *pcre2_maketables(pcre2_general_context *); \ + + +/* Define macros that generate width-specific names from generic versions. The +three-level macro scheme is necessary to get the macros expanded when we want +them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for +generating three versions of everything below. After that, PCRE2_SUFFIX will be +re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as +pcre2_compile are called by application code. */ + +#define PCRE2_JOIN(a,b) a ## b +#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b) +#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH) + + +/* Data types */ + +#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR) +#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR) + +#define pcre2_code PCRE2_SUFFIX(pcre2_code_) +#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_) +#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_) + +#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_) +#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_) +#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_) +#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_) +#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_) +#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_) + + +/* Data blocks */ + +#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_) +#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_) +#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_) +#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_) +#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_) +#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_) + + +/* Functions: the complete list in alphabetical order */ + +#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) +#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) +#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) +#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) +#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_) +#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_) +#define pcre2_config PCRE2_SUFFIX(pcre2_config_) +#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_) +#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_) +#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_) +#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) +#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) +#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) +#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) +#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) +#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_) +#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_) +#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_) +#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_) +#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_) +#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_) +#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_) +#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_) +#define pcre2_match PCRE2_SUFFIX(pcre2_match_) +#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_) +#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_) +#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_) +#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_) +#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_) +#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_) +#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_) +#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_) +#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_) +#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_) +#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_) +#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_) +#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) +#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) +#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) +#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) +#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) +#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) +#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) +#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) +#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_) +#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_) +#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) +#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) +#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) +#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_) +#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_) +#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_) +#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_) +#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_) +#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_) +#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_) +#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) +#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) + + +/* Now generate all three sets of width-specific structures and function +prototypes. */ + +#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \ +PCRE2_TYPES_LIST \ +PCRE2_STRUCTURE_LIST \ +PCRE2_GENERAL_INFO_FUNCTIONS \ +PCRE2_GENERAL_CONTEXT_FUNCTIONS \ +PCRE2_COMPILE_CONTEXT_FUNCTIONS \ +PCRE2_MATCH_CONTEXT_FUNCTIONS \ +PCRE2_COMPILE_FUNCTIONS \ +PCRE2_PATTERN_INFO_FUNCTIONS \ +PCRE2_MATCH_FUNCTIONS \ +PCRE2_SUBSTRING_FUNCTIONS \ +PCRE2_SERIALIZE_FUNCTIONS \ +PCRE2_SUBSTITUTE_FUNCTION \ +PCRE2_JIT_FUNCTIONS \ +PCRE2_OTHER_FUNCTIONS + +#define PCRE2_LOCAL_WIDTH 8 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +#define PCRE2_LOCAL_WIDTH 16 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +#define PCRE2_LOCAL_WIDTH 32 +PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS +#undef PCRE2_LOCAL_WIDTH + +/* Undefine the list macros; they are no longer needed. */ + +#undef PCRE2_TYPES_LIST +#undef PCRE2_STRUCTURE_LIST +#undef PCRE2_GENERAL_INFO_FUNCTIONS +#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS +#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS +#undef PCRE2_MATCH_CONTEXT_FUNCTIONS +#undef PCRE2_COMPILE_FUNCTIONS +#undef PCRE2_PATTERN_INFO_FUNCTIONS +#undef PCRE2_MATCH_FUNCTIONS +#undef PCRE2_SUBSTRING_FUNCTIONS +#undef PCRE2_SERIALIZE_FUNCTIONS +#undef PCRE2_SUBSTITUTE_FUNCTION +#undef PCRE2_JIT_FUNCTIONS +#undef PCRE2_OTHER_FUNCTIONS +#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS + +/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine +PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make +PCRE2_SUFFIX a no-op. Otherwise, generate an error. */ + +#undef PCRE2_SUFFIX +#ifndef PCRE2_CODE_UNIT_WIDTH +#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h. +#error Use 8, 16, or 32; or 0 for a multi-width application. +#else /* PCRE2_CODE_UNIT_WIDTH is defined */ +#if PCRE2_CODE_UNIT_WIDTH == 8 || \ + PCRE2_CODE_UNIT_WIDTH == 16 || \ + PCRE2_CODE_UNIT_WIDTH == 32 +#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH) +#elif PCRE2_CODE_UNIT_WIDTH == 0 +#undef PCRE2_JOIN +#undef PCRE2_GLUE +#define PCRE2_SUFFIX(a) a +#else +#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32. +#endif +#endif /* PCRE2_CODE_UNIT_WIDTH is defined */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre2.h */ diff --git a/pcre2/src/pcre2_auto_possess.c b/pcre2/src/pcre2_auto_possess.c new file mode 100644 index 000000000..d4d2334d8 --- /dev/null +++ b/pcre2/src/pcre2_auto_possess.c @@ -0,0 +1,1287 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains functions that scan a compiled pattern and change +repeats into possessive repeats where possible. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "pcre2_internal.h" + + +/************************************************* +* Tables for auto-possessification * +*************************************************/ + +/* This table is used to check whether auto-possessification is possible +between adjacent character-type opcodes. The left-hand (repeated) opcode is +used to select the row, and the right-hand opcode is use to select the column. +A value of 1 means that auto-possessification is OK. For example, the second +value in the first row means that \D+\d can be turned into \D++\d. + +The Unicode property types (\P and \p) have to be present to fill out the table +because of what their opcode values are, but the table values should always be +zero because property types are handled separately in the code. The last four +columns apply to items that cannot be repeated, so there is no need to have +rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is +*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + +#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1) +#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1) + +static const uint8_t autoposstab[APTROWS][APTCOLS] = { +/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */ + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */ + { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */ + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */ + { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */ + { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */ + { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */ +}; + +/* This table is used to check whether auto-possessification is possible +between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The +left-hand (repeated) opcode is used to select the row, and the right-hand +opcode is used to select the column. The values are as follows: + + 0 Always return FALSE (never auto-possessify) + 1 Character groups are distinct (possessify if both are OP_PROP) + 2 Check character categories in the same group (general or particular) + 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP) + + 4 Check left general category vs right particular category + 5 Check right general category vs left particular category + + 6 Left alphanum vs right general category + 7 Left space vs right general category + 8 Left word vs right general category + + 9 Right alphanum vs left general category + 10 Right space vs left general category + 11 Right word vs left general category + + 12 Left alphanum vs right particular category + 13 Left space vs right particular category + 14 Left word vs right particular category + + 15 Right alphanum vs left particular category + 16 Right space vs left particular category + 17 Right word vs left particular category +*/ + +static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = { +/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */ + { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */ + { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */ + { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */ + { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ + { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */ + { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */ + { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */ + { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */ +}; + +/* This table is used to check whether auto-possessification is possible +between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one +specifies a general category and the other specifies a particular category. The +row is selected by the general category and the column by the particular +category. The value is 1 if the particular category is not part of the general +category. */ + +static const uint8_t catposstab[7][30] = { +/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */ + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* C */ + { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 } /* Z */ +}; + +/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against +a general or particular category. The properties in each row are those +that apply to the character set in question. Duplication means that a little +unnecessary work is done when checking, but this keeps things much simpler +because they can all use the same code. For more details see the comment where +this table is used. + +Note: SPACE and PXSPACE used to be different because Perl excluded VT from +"space", but from Perl 5.18 it's included, so both categories are treated the +same here. */ + +static const uint8_t posspropstab[3][4] = { + { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */ + { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */ + { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */ +}; + + + +#ifdef SUPPORT_UNICODE +/************************************************* +* Check a character and a property * +*************************************************/ + +/* This function is called by compare_opcodes() when a property item is +adjacent to a fixed character. + +Arguments: + c the character + ptype the property type + pdata the data for the type + negated TRUE if it's a negated property (\P or \p{^) + +Returns: TRUE if auto-possessifying is OK +*/ + +static BOOL +check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata, + BOOL negated) +{ +const uint32_t *p; +const ucd_record *prop = GET_UCD(c); + +switch(ptype) + { + case PT_LAMP: + return (prop->chartype == ucp_Lu || + prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == negated; + + case PT_GC: + return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; + + case PT_PC: + return (pdata == prop->chartype) == negated; + + case PT_SC: + return (pdata == prop->script) == negated; + + /* These are specials */ + + case PT_ALNUM: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, which + means that Perl space and POSIX space are now identical. PCRE was changed + at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + return negated; + + default: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; + } + break; /* Control never reaches here */ + + case PT_WORD: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE) == negated; + + case PT_CLIST: + p = PRIV(ucd_caseless_sets) + prop->caseset; + for (;;) + { + if (c < *p) return !negated; + if (c == *p++) return negated; + } + break; /* Control never reaches here */ + } + +return FALSE; +} +#endif /* SUPPORT_UNICODE */ + + + +/************************************************* +* Base opcode of repeated opcodes * +*************************************************/ + +/* Returns the base opcode for repeated single character type opcodes. If the +opcode is not a repeated character type, it returns with the original value. + +Arguments: c opcode +Returns: base opcode for the type +*/ + +static PCRE2_UCHAR +get_repeat_base(PCRE2_UCHAR c) +{ +return (c > OP_TYPEPOSUPTO)? c : + (c >= OP_TYPESTAR)? OP_TYPESTAR : + (c >= OP_NOTSTARI)? OP_NOTSTARI : + (c >= OP_NOTSTAR)? OP_NOTSTAR : + (c >= OP_STARI)? OP_STARI : + OP_STAR; +} + + +/************************************************* +* Fill the character property list * +*************************************************/ + +/* Checks whether the code points to an opcode that can take part in auto- +possessification, and if so, fills a list with its properties. + +Arguments: + code points to start of expression + utf TRUE if in UTF mode + fcc points to the case-flipping table + list points to output list + list[0] will be filled with the opcode + list[1] will be non-zero if this opcode + can match an empty character string + list[2..7] depends on the opcode + +Returns: points to the start of the next opcode if *code is accepted + NULL if *code is not accepted +*/ + +static PCRE2_SPTR +get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc, + uint32_t *list) +{ +PCRE2_UCHAR c = *code; +PCRE2_UCHAR base; +PCRE2_SPTR end; +uint32_t chr; + +#ifdef SUPPORT_UNICODE +uint32_t *clist_dest; +const uint32_t *clist_src; +#else +(void)utf; /* Suppress "unused parameter" compiler warning */ +#endif + +list[0] = c; +list[1] = FALSE; +code++; + +if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) + { + base = get_repeat_base(c); + c -= (base - OP_STAR); + + if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO) + code += IMM2_SIZE; + + list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT && + c != OP_POSPLUS); + + switch(base) + { + case OP_STAR: + list[0] = OP_CHAR; + break; + + case OP_STARI: + list[0] = OP_CHARI; + break; + + case OP_NOTSTAR: + list[0] = OP_NOT; + break; + + case OP_NOTSTARI: + list[0] = OP_NOTI; + break; + + case OP_TYPESTAR: + list[0] = *code; + code++; + break; + } + c = list[0]; + } + +switch(c) + { + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_DOLL: + case OP_DOLLM: + return code; + + case OP_CHAR: + case OP_NOT: + GETCHARINCTEST(chr, code); + list[2] = chr; + list[3] = NOTACHAR; + return code; + + case OP_CHARI: + case OP_NOTI: + list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT; + GETCHARINCTEST(chr, code); + list[2] = chr; + +#ifdef SUPPORT_UNICODE + if (chr < 128 || (chr < 256 && !utf)) + list[3] = fcc[chr]; + else + list[3] = UCD_OTHERCASE(chr); +#elif defined SUPPORT_WIDE_CHARS + list[3] = (chr < 256) ? fcc[chr] : chr; +#else + list[3] = fcc[chr]; +#endif + + /* The othercase might be the same value. */ + + if (chr == list[3]) + list[3] = NOTACHAR; + else + list[4] = NOTACHAR; + return code; + +#ifdef SUPPORT_UNICODE + case OP_PROP: + case OP_NOTPROP: + if (code[0] != PT_CLIST) + { + list[2] = code[0]; + list[3] = code[1]; + return code + 2; + } + + /* Convert only if we have enough space. */ + + clist_src = PRIV(ucd_caseless_sets) + code[1]; + clist_dest = list + 2; + code += 2; + + do { + if (clist_dest >= list + 8) + { + /* Early return if there is not enough space. This should never + happen, since all clists are shorter than 5 character now. */ + list[2] = code[0]; + list[3] = code[1]; + return code; + } + *clist_dest++ = *clist_src; + } + while(*clist_src++ != NOTACHAR); + + /* All characters are stored. The terminating NOTACHAR is copied from the + clist itself. */ + + list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT; + return code; +#endif + + case OP_NCLASS: + case OP_CLASS: +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + if (c == OP_XCLASS) + end = code + GET(code, 0) - 1; + else +#endif + end = code + 32 / sizeof(PCRE2_UCHAR); + + switch(*end) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + list[1] = TRUE; + end++; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + end++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + list[1] = (GET2(end, 1) == 0); + end += 1 + 2 * IMM2_SIZE; + break; + } + list[2] = (uint32_t)(end - code); + return end; + } +return NULL; /* Opcode not accepted */ +} + + + +/************************************************* +* Scan further character sets for match * +*************************************************/ + +/* Checks whether the base and the current opcode have a common character, in +which case the base cannot be possessified. + +Arguments: + code points to the byte code + utf TRUE in UTF mode + cb compile data block + base_list the data list of the base opcode + base_end the end of the data list + rec_limit points to recursion depth counter + +Returns: TRUE if the auto-possessification is possible +*/ + +static BOOL +compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb, + const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit) +{ +PCRE2_UCHAR c; +uint32_t list[8]; +const uint32_t *chr_ptr; +const uint32_t *ochr_ptr; +const uint32_t *list_ptr; +PCRE2_SPTR next_code; +#ifdef SUPPORT_WIDE_CHARS +PCRE2_SPTR xclass_flags; +#endif +const uint8_t *class_bitset; +const uint8_t *set1, *set2, *set_end; +uint32_t chr; +BOOL accepted, invert_bits; +BOOL entered_a_group = FALSE; + +if (--(*rec_limit) <= 0) return FALSE; /* Recursion has gone too deep */ + +/* Note: the base_list[1] contains whether the current opcode has a greedy +(represented by a non-zero value) quantifier. This is a different from +other character type lists, which store here that the character iterator +matches to an empty string (also represented by a non-zero value). */ + +for(;;) + { + /* All operations move the code pointer forward. + Therefore infinite recursions are not possible. */ + + c = *code; + + /* Skip over callouts */ + + if (c == OP_CALLOUT) + { + code += PRIV(OP_lengths)[c]; + continue; + } + + if (c == OP_CALLOUT_STR) + { + code += GET(code, 1 + 2*LINK_SIZE); + continue; + } + + if (c == OP_ALT) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + } + + switch(c) + { + case OP_END: + case OP_KETRPOS: + /* TRUE only in greedy case. The non-greedy case could be replaced by + an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT + uses more memory, which we cannot get at this stage.) */ + + return base_list[1] != 0; + + case OP_KET: + /* If the bracket is capturing, and referenced by an OP_RECURSE, or + it is an atomic sub-pattern (assert, once, etc.) the non-greedy case + cannot be converted to a possessive form. */ + + if (base_list[1] == 0) return FALSE; + + switch(*(code - GET(code, 1))) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + /* Atomic sub-patterns and assertions can always auto-possessify their + last iterator. However, if the group was entered as a result of checking + a previous iterator, this is not possible. */ + + return !entered_a_group; + } + + code += PRIV(OP_lengths)[c]; + continue; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + next_code = code + GET(code, 1); + code += PRIV(OP_lengths)[c]; + + while (*next_code == OP_ALT) + { + if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit)) + return FALSE; + code = next_code + 1 + LINK_SIZE; + next_code += GET(next_code, 1); + } + + entered_a_group = TRUE; + continue; + + case OP_BRAZERO: + case OP_BRAMINZERO: + + next_code = code + 1; + if (*next_code != OP_BRA && *next_code != OP_CBRA + && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE; + + do next_code += GET(next_code, 1); while (*next_code == OP_ALT); + + /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */ + + next_code += 1 + LINK_SIZE; + if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit)) + return FALSE; + + code += PRIV(OP_lengths)[c]; + continue; + + default: + break; + } + + /* Check for a supported opcode, and load its properties. */ + + code = get_chr_property_list(code, utf, cb->fcc, list); + if (code == NULL) return FALSE; /* Unsupported */ + + /* If either opcode is a small character list, set pointers for comparing + characters from that list with another list, or with a property. */ + + if (base_list[0] == OP_CHAR) + { + chr_ptr = base_list + 2; + list_ptr = list; + } + else if (list[0] == OP_CHAR) + { + chr_ptr = list + 2; + list_ptr = base_list; + } + + /* Character bitsets can also be compared to certain opcodes. */ + + else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS +#if PCRE2_CODE_UNIT_WIDTH == 8 + /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */ + || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS)) +#endif + ) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS)) +#else + if (base_list[0] == OP_CLASS) +#endif + { + set1 = (uint8_t *)(base_end - base_list[2]); + list_ptr = list; + } + else + { + set1 = (uint8_t *)(code - list[2]); + list_ptr = base_list; + } + + invert_bits = FALSE; + switch(list_ptr[0]) + { + case OP_CLASS: + case OP_NCLASS: + set2 = (uint8_t *) + ((list_ptr == list ? code : base_end) - list_ptr[2]); + break; + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE; + if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE; + if ((*xclass_flags & XCL_MAP) == 0) + { + /* No bits are set for characters < 256. */ + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + set2 = (uint8_t *)(xclass_flags + 1); + break; +#endif + + case OP_NOT_DIGIT: + invert_bits = TRUE; + /* Fall through */ + case OP_DIGIT: + set2 = (uint8_t *)(cb->cbits + cbit_digit); + break; + + case OP_NOT_WHITESPACE: + invert_bits = TRUE; + /* Fall through */ + case OP_WHITESPACE: + set2 = (uint8_t *)(cb->cbits + cbit_space); + break; + + case OP_NOT_WORDCHAR: + invert_bits = TRUE; + /* Fall through */ + case OP_WORDCHAR: + set2 = (uint8_t *)(cb->cbits + cbit_word); + break; + + default: + return FALSE; + } + + /* Because the bit sets are unaligned bytes, we need to perform byte + comparison here. */ + + set_end = set1 + 32; + if (invert_bits) + { + do + { + if ((*set1++ & ~(*set2++)) != 0) return FALSE; + } + while (set1 < set_end); + } + else + { + do + { + if ((*set1++ & *set2++) != 0) return FALSE; + } + while (set1 < set_end); + } + + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + + /* Some property combinations also acceptable. Unicode property opcodes are + processed specially; the rest can be handled with a lookup table. */ + + else + { + uint32_t leftop, rightop; + + leftop = base_list[0]; + rightop = list[0]; + +#ifdef SUPPORT_UNICODE + accepted = FALSE; /* Always set in non-unicode case. */ + if (leftop == OP_PROP || leftop == OP_NOTPROP) + { + if (rightop == OP_EOD) + accepted = TRUE; + else if (rightop == OP_PROP || rightop == OP_NOTPROP) + { + int n; + const uint8_t *p; + BOOL same = leftop == rightop; + BOOL lisprop = leftop == OP_PROP; + BOOL risprop = rightop == OP_PROP; + BOOL bothprop = lisprop && risprop; + + /* There's a table that specifies how each combination is to be + processed: + 0 Always return FALSE (never auto-possessify) + 1 Character groups are distinct (possessify if both are OP_PROP) + 2 Check character categories in the same group (general or particular) + 3 Return TRUE if the two opcodes are not the same + ... see comments below + */ + + n = propposstab[base_list[2]][list[2]]; + switch(n) + { + case 0: break; + case 1: accepted = bothprop; break; + case 2: accepted = (base_list[3] == list[3]) != same; break; + case 3: accepted = !same; break; + + case 4: /* Left general category, right particular category */ + accepted = risprop && catposstab[base_list[3]][list[3]] == same; + break; + + case 5: /* Right general category, left particular category */ + accepted = lisprop && catposstab[list[3]][base_list[3]] == same; + break; + + /* This code is logically tricky. Think hard before fiddling with it. + The posspropstab table has four entries per row. Each row relates to + one of PCRE's special properties such as ALNUM or SPACE or WORD. + Only WORD actually needs all four entries, but using repeats for the + others means they can all use the same code below. + + The first two entries in each row are Unicode general categories, and + apply always, because all the characters they include are part of the + PCRE character set. The third and fourth entries are a general and a + particular category, respectively, that include one or more relevant + characters. One or the other is used, depending on whether the check + is for a general or a particular category. However, in both cases the + category contains more characters than the specials that are defined + for the property being tested against. Therefore, it cannot be used + in a NOTPROP case. + + Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po. + Underscore is covered by ucp_P or ucp_Po. */ + + case 6: /* Left alphanum vs right general category */ + case 7: /* Left space vs right general category */ + case 8: /* Left word vs right general category */ + p = posspropstab[n-6]; + accepted = risprop && lisprop == + (list[3] != p[0] && + list[3] != p[1] && + (list[3] != p[2] || !lisprop)); + break; + + case 9: /* Right alphanum vs left general category */ + case 10: /* Right space vs left general category */ + case 11: /* Right word vs left general category */ + p = posspropstab[n-9]; + accepted = lisprop && risprop == + (base_list[3] != p[0] && + base_list[3] != p[1] && + (base_list[3] != p[2] || !risprop)); + break; + + case 12: /* Left alphanum vs right particular category */ + case 13: /* Left space vs right particular category */ + case 14: /* Left word vs right particular category */ + p = posspropstab[n-12]; + accepted = risprop && lisprop == + (catposstab[p[0]][list[3]] && + catposstab[p[1]][list[3]] && + (list[3] != p[3] || !lisprop)); + break; + + case 15: /* Right alphanum vs left particular category */ + case 16: /* Right space vs left particular category */ + case 17: /* Right word vs left particular category */ + p = posspropstab[n-15]; + accepted = lisprop && risprop == + (catposstab[p[0]][base_list[3]] && + catposstab[p[1]][base_list[3]] && + (base_list[3] != p[3] || !risprop)); + break; + } + } + } + + else +#endif /* SUPPORT_UNICODE */ + + accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP && + rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP && + autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP]; + + if (!accepted) return FALSE; + + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + + /* Control reaches here only if one of the items is a small character list. + All characters are checked against the other side. */ + + do + { + chr = *chr_ptr; + + switch(list_ptr[0]) + { + case OP_CHAR: + ochr_ptr = list_ptr + 2; + do + { + if (chr == *ochr_ptr) return FALSE; + ochr_ptr++; + } + while(*ochr_ptr != NOTACHAR); + break; + + case OP_NOT: + ochr_ptr = list_ptr + 2; + do + { + if (chr == *ochr_ptr) + break; + ochr_ptr++; + } + while(*ochr_ptr != NOTACHAR); + if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */ + break; + + /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not* + set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + + case OP_DIGIT: + if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE; + break; + + case OP_NOT_DIGIT: + if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE; + break; + + case OP_WHITESPACE: + if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE; + break; + + case OP_NOT_WHITESPACE: + if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE; + break; + + case OP_WORDCHAR: + if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE; + break; + + case OP_NOT_WORDCHAR: + if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE; + break; + + case OP_HSPACE: + switch(chr) + { + HSPACE_CASES: return FALSE; + default: break; + } + break; + + case OP_NOT_HSPACE: + switch(chr) + { + HSPACE_CASES: break; + default: return FALSE; + } + break; + + case OP_ANYNL: + case OP_VSPACE: + switch(chr) + { + VSPACE_CASES: return FALSE; + default: break; + } + break; + + case OP_NOT_VSPACE: + switch(chr) + { + VSPACE_CASES: break; + default: return FALSE; + } + break; + + case OP_DOLL: + case OP_EODN: + switch (chr) + { + case CHAR_CR: + case CHAR_LF: + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + return FALSE; + } + break; + + case OP_EOD: /* Can always possessify before \z */ + break; + +#ifdef SUPPORT_UNICODE + case OP_PROP: + case OP_NOTPROP: + if (!check_char_prop(chr, list_ptr[2], list_ptr[3], + list_ptr[0] == OP_NOTPROP)) + return FALSE; + break; +#endif + + case OP_NCLASS: + if (chr > 255) return FALSE; + /* Fall through */ + + case OP_CLASS: + if (chr > 255) break; + class_bitset = (uint8_t *) + ((list_ptr == list ? code : base_end) - list_ptr[2]); + if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE; + break; + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) - + list_ptr[2] + LINK_SIZE, utf)) return FALSE; + break; +#endif + + default: + return FALSE; + } + + chr_ptr++; + } + while(*chr_ptr != NOTACHAR); + + /* At least one character must be matched from this opcode. */ + + if (list[1] == 0) return TRUE; + } + +/* Control never reaches here. There used to be a fail-save return FALSE; here, +but some compilers complain about an unreachable statement. */ +} + + + +/************************************************* +* Scan compiled regex for auto-possession * +*************************************************/ + +/* Replaces single character iterations with their possessive alternatives +if appropriate. This function modifies the compiled opcode! Hitting a +non-existant opcode may indicate a bug in PCRE2, but it can also be caused if a +bad UTF string was compiled with PCRE2_NO_UTF_CHECK. + +Arguments: + code points to start of the byte code + utf TRUE in UTF mode + cb compile data block + +Returns: 0 for success + -1 if a non-existant opcode is encountered +*/ + +int +PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb) +{ +register PCRE2_UCHAR c; +PCRE2_SPTR end; +PCRE2_UCHAR *repeat_opcode; +uint32_t list[8]; +int rec_limit; + +for (;;) + { + c = *code; + + if (c > OP_TABLE_LENGTH) return -1; /* Something gone wrong */ + + if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) + { + c -= get_repeat_base(c) - OP_STAR; + end = (c <= OP_MINUPTO) ? + get_chr_property_list(code, utf, cb->fcc, list) : NULL; + list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO; + + rec_limit = 1000; + if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit)) + { + switch(c) + { + case OP_STAR: + *code += OP_POSSTAR - OP_STAR; + break; + + case OP_MINSTAR: + *code += OP_POSSTAR - OP_MINSTAR; + break; + + case OP_PLUS: + *code += OP_POSPLUS - OP_PLUS; + break; + + case OP_MINPLUS: + *code += OP_POSPLUS - OP_MINPLUS; + break; + + case OP_QUERY: + *code += OP_POSQUERY - OP_QUERY; + break; + + case OP_MINQUERY: + *code += OP_POSQUERY - OP_MINQUERY; + break; + + case OP_UPTO: + *code += OP_POSUPTO - OP_UPTO; + break; + + case OP_MINUPTO: + *code += OP_POSUPTO - OP_MINUPTO; + break; + } + } + c = *code; + } + else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS) + { +#ifdef SUPPORT_WIDE_CHARS + if (c == OP_XCLASS) + repeat_opcode = code + GET(code, 1); + else +#endif + repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); + + c = *repeat_opcode; + if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) + { + /* end must not be NULL. */ + end = get_chr_property_list(code, utf, cb->fcc, list); + + list[1] = (c & 1) == 0; + + rec_limit = 1000; + if (compare_opcodes(end, utf, cb, list, end, &rec_limit)) + { + switch (c) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + *repeat_opcode = OP_CRPOSSTAR; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + *repeat_opcode = OP_CRPOSPLUS; + break; + + case OP_CRQUERY: + case OP_CRMINQUERY: + *repeat_opcode = OP_CRPOSQUERY; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + *repeat_opcode = OP_CRPOSRANGE; + break; + } + } + } + c = *code; + } + + switch(c) + { + case OP_END: + return 0; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + case OP_CALLOUT_STR: + code += GET(code, 1 + 2*LINK_SIZE); + break; + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + code += GET(code, 1); + break; +#endif + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be + followed by a multi-byte character. The length in the table is a minimum, so + we have to arrange to skip the extra code units. */ + +#ifdef MAYBE_UTF_MULTI + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif /* SUPPORT_WIDE_CHARS */ + } +} + +/* End of pcre2_auto_possess.c */ diff --git a/pcre2/src/pcre2_chartables.c.dist b/pcre2/src/pcre2_chartables.c.dist new file mode 100644 index 000000000..203cb1a4a --- /dev/null +++ b/pcre2/src/pcre2_chartables.c.dist @@ -0,0 +1,198 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This file contains character tables that are used when no external tables +are passed to PCRE2 by the application that calls it. The tables are used only +for characters whose code values are less than 256. + +This is a default version of the tables that assumes ASCII encoding. A program +called dftables (which is distributed with PCRE2) can be used to build +alternative versions of this file. This is necessary if you are running in an +EBCDIC environment, or if you want to default to a different encoding, for +example ISO-8859-1. When dftables is run, it creates these tables in the +current locale. If PCRE2 is configured with --enable-rebuild-chartables, this +happens automatically. + +The following #includes are present because without them gcc 4.x may remove the +array definition from the final binary if PCRE2 is built into a static library +and dead code stripping is activated. This leads to link errors. Pulling in the +header ensures that the array gets flagged as "someone outside this compilation +unit might reference this" and so it will always be supplied to the linker. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + +const uint8_t PRIV(default_tables)[] = { + +/* This table is a lower casing table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table is a case flipping table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table contains bit maps for various character classes. Each map is 32 +bytes long and the bits run from the least significant end of each byte. The +classes that have their own maps are: space, xdigit, digit, upper, lower, word, +graph, print, punct, and cntrl. Other classes are built from combinations. */ + + 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, + 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +/* This table identifies various classes of character by individual bits: + 0x01 white space character + 0x02 letter + 0x04 decimal digit + 0x08 hexadecimal digit + 0x10 alphanumeric or '_' + 0x80 regular expression metacharacter or binary zero +*/ + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ + 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +/* End of pcre2_chartables.c */ diff --git a/pcre2/src/pcre2_compile.c b/pcre2/src/pcre2_compile.c new file mode 100644 index 000000000..876109036 --- /dev/null +++ b/pcre2/src/pcre2_compile.c @@ -0,0 +1,9018 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK cb /* Block containing newline information */ +#define PSSTART start_pattern /* Field containing processed string start */ +#define PSEND end_pattern /* Field containing processed string end */ + +#include "pcre2_internal.h" + +/* In rare error cases debugging might require calling pcre2_printint(). */ + +#if 0 +#ifdef EBCDIC +#define PRINTABLE(c) ((c) >= 64 && (c) < 255) +#else +#define PRINTABLE(c) ((c) >= 32 && (c) < 127) +#endif +#include "pcre2_printint.c" +#define CALL_PRINTINT +#endif + +/* There are a few things that vary with different code unit sizes. Handle them +by defining macros in order to minimize #if usage. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define STRING_UTFn_RIGHTPAR STRING_UTF8_RIGHTPAR, 5 +#define XDIGIT(c) xdigitab[c] + +#else /* Either 16-bit or 32-bit */ +#define XDIGIT(c) (MAX_255(c)? xdigitab[c] : 0xff) + +#if PCRE2_CODE_UNIT_WIDTH == 16 +#define STRING_UTFn_RIGHTPAR STRING_UTF16_RIGHTPAR, 6 + +#else /* 32-bit */ +#define STRING_UTFn_RIGHTPAR STRING_UTF32_RIGHTPAR, 6 +#endif +#endif + +/* Function definitions to allow mutual recursion */ + +static int + add_list_to_class(uint8_t *, PCRE2_UCHAR **, uint32_t, compile_block *, + const uint32_t *, unsigned int); + +static BOOL + compile_regex(uint32_t, PCRE2_UCHAR **, PCRE2_SPTR *, int *, BOOL, BOOL, + uint32_t, int, uint32_t *, int32_t *, uint32_t *, int32_t *, + branch_chain *, compile_block *, size_t *); + + + +/************************************************* +* Code parameters and static tables * +*************************************************/ + +/* This value specifies the size of stack workspace, which is used in different +ways in the different pattern scans. The group-identifying pre-scan uses it to +handle nesting, and needs it to be 16-bit aligned. + +During the first compiling phase, when determining how much memory is required, +the regex is partly compiled into this space, but the compiled parts are +discarded as soon as they can be, so that hopefully there will never be an +overrun. The code does, however, check for an overrun, which can occur for +pathological patterns. The size of the workspace depends on LINK_SIZE because +the length of compiled items varies with this. + +In the real compile phase, the workspace is used for remembering data about +numbered groups, provided there are not too many of them (if there are, extra +memory is acquired). For this phase the memory must be 32-bit aligned. Having +defined the size in code units, we set up C32_WORK_SIZE as the number of +elements in the 32-bit vector. */ + +#define COMPILE_WORK_SIZE (2048*LINK_SIZE) /* Size in code units */ + +#define C32_WORK_SIZE \ + ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint32_t)) + +/* The overrun tests check for a slightly smaller size so that they detect the +overrun before it actually does run off the end of the data block. */ + +#define WORK_SIZE_SAFETY_MARGIN (100) + +/* This value determines the size of the initial vector that is used for +remembering named groups during the pre-compile. It is allocated on the stack, +but if it is too small, it is expanded, in a similar way to the workspace. The +value is the number of slots in the list. */ + +#define NAMED_GROUP_LIST_SIZE 20 + +/* The original PCRE required patterns to be zero-terminated, and it simplifies +the compiling code if it is guaranteed that there is a zero code unit at the +end of the pattern, because this means that tests for coding sequences such as +(*SKIP) or even just (?<= can check a sequence of code units without having to +keep checking for the end of the pattern. The new PCRE2 API allows zero code +units within patterns if a positive length is given, but in order to keep most +of the compiling code as it was, we copy such patterns and add a zero on the +end. This value determines the size of space on the stack that is used if the +pattern fits; if not, heap memory is used. */ + +#define COPIED_PATTERN_SIZE 1024 + +/* Maximum length value to check against when making sure that the variable +that holds the compiled pattern length does not overflow. We make it a bit less +than INT_MAX to allow for adding in group terminating bytes, so that we don't +have to check them every time. */ + +#define OFLOW_MAX (INT_MAX - 20) + +/* Macro for setting individual bits in class bitmaps. */ + +#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7)) + +/* Private flags added to firstcu and reqcu. */ + +#define REQ_CASELESS (1 << 0) /* Indicates caselessness */ +#define REQ_VARY (1 << 1) /* reqcu followed non-literal item */ +/* Negative values for the firstcu and reqcu flags */ +#define REQ_UNSET (-2) /* Not yet found anything */ +#define REQ_NONE (-1) /* Found not fixed char */ + +/* These flags are used in the groupinfo vector. */ + +#define GI_SET_COULD_BE_EMPTY 0x80000000u +#define GI_COULD_BE_EMPTY 0x40000000u +#define GI_NOT_FIXED_LENGTH 0x20000000u +#define GI_SET_FIXED_LENGTH 0x10000000u +#define GI_FIXED_LENGTH_MASK 0x0000ffffu + +/* This bit (which is greater than any UTF value) is used to indicate that a +variable contains a number of code units instead of an actual code point. */ + +#define UTF_LENGTH 0x10000000l + +/* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC +and is fast (a good compiler can turn it into a subtraction and unsigned +comparison). */ + +#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9) + +/* Table to identify hex digits. The tables in chartables are dependent on the +locale, and may mark arbitrary characters as digits. We want to recognize only +0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It +costs 256 bytes, but it is a lot faster than doing character value tests (at +least in some simple cases I timed), and in some applications one wants PCRE to +compile efficiently as well as match efficiently. The value in the table is +the binary hex digit value, or 0xff for non-hex digits. */ + +/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in +UTF-8 mode. */ + +#ifndef EBCDIC +static const uint8_t xdigitab[] = + { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - ' */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ( - / */ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 */ + 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /* 8 - ? */ + 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* @ - G */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H - O */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* P - W */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* X - _ */ + 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* ` - g */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h - o */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* p - w */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* x -127 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */ + +#else + +/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ + +static const uint8_t xdigitab[] = + { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 10 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 32- 39 20 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 40- 47 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 48- 55 30 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 56- 63 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - 71 40 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 72- | */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* & - 87 50 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 88- 95 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - -103 60 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ? */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- " */ + 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g 80 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h -143 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p 90 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* q -159 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x A0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* y -175 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ^ -183 B0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */ + 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* { - G C0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H -207 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* } - P D0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Q -223 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* \ - X E0 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Y -239 */ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 F0 */ + 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/* 8 -255 */ +#endif /* EBCDIC */ + + +/* Table for handling alphanumeric escaped characters. Positive returns are +simple data values; negative values are for special things like \d and so on. +Zero means further processing is needed (for things like \x), or the escape is +invalid. */ + +/* This is the "normal" table for ASCII systems or for EBCDIC systems running +in UTF-8 mode. It runs from '0' to 'z'. */ + +#ifndef EBCDIC +#define ESCAPES_FIRST CHAR_0 +#define ESCAPES_LAST CHAR_z +#define UPPER_CASE(c) (c-32) + +static const short int escapes[] = { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + CHAR_COLON, CHAR_SEMICOLON, + CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, + CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK, + CHAR_COMMERCIAL_AT, -ESC_A, + -ESC_B, -ESC_C, + -ESC_D, -ESC_E, + 0, -ESC_G, + -ESC_H, 0, + 0, -ESC_K, + 0, 0, + -ESC_N, 0, + -ESC_P, -ESC_Q, + -ESC_R, -ESC_S, + 0, 0, + -ESC_V, -ESC_W, + -ESC_X, 0, + -ESC_Z, CHAR_LEFT_SQUARE_BRACKET, + CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET, + CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE, + CHAR_GRAVE_ACCENT, ESC_a, + -ESC_b, 0, + -ESC_d, ESC_e, + ESC_f, 0, + -ESC_h, 0, + 0, -ESC_k, + 0, 0, + ESC_n, 0, + -ESC_p, 0, + ESC_r, -ESC_s, + ESC_tee, 0, + -ESC_v, -ESC_w, + 0, 0, + -ESC_z +}; + +#else + +/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. +It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code +is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a +because it is defined as 'a', which of course picks up the ASCII value. */ + +#if 'a' == 0x81 /* Check for a real EBCDIC environment */ +#define ESCAPES_FIRST CHAR_a +#define ESCAPES_LAST CHAR_9 +#define UPPER_CASE(c) (c+64) +#else /* Testing in an ASCII environment */ +#define ESCAPES_FIRST ((unsigned char)'\x81') /* EBCDIC 'a' */ +#define ESCAPES_LAST ((unsigned char)'\xf9') /* EBCDIC '9' */ +#define UPPER_CASE(c) (c-32) +#endif + +static const short int escapes[] = { +/* 80 */ ESC_a, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, +/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0, +/* 90 */ 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p, +/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, +/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0, +/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, +/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', +/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, +/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0, +/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P, +/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0, +/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X, +/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, +/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* F8 */ 0, 0 +}; + +/* We also need a table of characters that may follow \c in an EBCDIC +environment for characters 0-31. */ + +static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; + +#endif /* EBCDIC */ + + +/* Table of special "verbs" like (*PRUNE). This is a short table, so it is +searched linearly. Put all the names into a single string, in order to reduce +the number of relocations when a shared library is dynamically linked. The +string is built from string macros so that it works in UTF-8 mode on EBCDIC +platforms. */ + +typedef struct verbitem { + int len; /* Length of verb name */ + int op; /* Op when no arg, or -1 if arg mandatory */ + int op_arg; /* Op when arg present, or -1 if not allowed */ +} verbitem; + +static const char verbnames[] = + "\0" /* Empty name is a shorthand for MARK */ + STRING_MARK0 + STRING_ACCEPT0 + STRING_COMMIT0 + STRING_F0 + STRING_FAIL0 + STRING_PRUNE0 + STRING_SKIP0 + STRING_THEN; + +static const verbitem verbs[] = { + { 0, -1, OP_MARK }, + { 4, -1, OP_MARK }, + { 6, OP_ACCEPT, -1 }, + { 6, OP_COMMIT, -1 }, + { 1, OP_FAIL, -1 }, + { 4, OP_FAIL, -1 }, + { 5, OP_PRUNE, OP_PRUNE_ARG }, + { 4, OP_SKIP, OP_SKIP_ARG }, + { 4, OP_THEN, OP_THEN_ARG } +}; + +static const int verbcount = sizeof(verbs)/sizeof(verbitem); + + +/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in +another regex library. */ + +static const PCRE2_UCHAR sub_start_of_word[] = { + CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, + CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' }; + +static const PCRE2_UCHAR sub_end_of_word[] = { + CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, + CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, + CHAR_RIGHT_PARENTHESIS, '\0' }; + + +/* Tables of names of POSIX character classes and their lengths. The names are +now all in a single string, to reduce the number of relocations when a shared +library is dynamically loaded. The list of lengths is terminated by a zero +length entry. The first three must be alpha, lower, upper, as this is assumed +for handling case independence. The indices for graph, print, and punct are +needed, so identify them. */ + +static const char posix_names[] = + STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 + STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0 + STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 + STRING_word0 STRING_xdigit; + +static const uint8_t posix_name_lengths[] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; + +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 + + +/* Table of class bit maps for each POSIX class. Each class is formed from a +base map, with an optional addition or removal of another map. Then, for some +classes, there is some additional tweaking: for [:blank:] the vertical space +characters are removed, and for [:alpha:] and [:alnum:] the underscore +character is removed. The triples in the table consist of the base map offset, +second map offset or -1 if no second map, and a non-negative value for map +addition or a negative value for map subtraction (if there are two maps). The +absolute value of the third field has these meanings: 0 => no tweaking, 1 => +remove vertical space characters, 2 => remove underscore. */ + +static const int posix_class_maps[] = { + cbit_word, cbit_digit, -2, /* alpha */ + cbit_lower, -1, 0, /* lower */ + cbit_upper, -1, 0, /* upper */ + cbit_word, -1, 2, /* alnum - word without underscore */ + cbit_print, cbit_cntrl, 0, /* ascii */ + cbit_space, -1, 1, /* blank - a GNU extension */ + cbit_cntrl, -1, 0, /* cntrl */ + cbit_digit, -1, 0, /* digit */ + cbit_graph, -1, 0, /* graph */ + cbit_print, -1, 0, /* print */ + cbit_punct, -1, 0, /* punct */ + cbit_space, -1, 0, /* space */ + cbit_word, -1, 0, /* word - a Perl extension */ + cbit_xdigit,-1, 0 /* xdigit */ +}; + +/* Table of substitutes for \d etc when PCRE2_UCP is set. They are replaced by +Unicode property escapes. */ + +#ifdef SUPPORT_UNICODE +static const PCRE2_UCHAR string_PNd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pNd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PXsp[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pXsp[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PXwd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pXwd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static PCRE2_SPTR substitutes[] = { + string_PNd, /* \D */ + string_pNd, /* \d */ + string_PXsp, /* \S */ /* Xsp is Perl space, but from 8.34, Perl */ + string_pXsp, /* \s */ /* space and POSIX space are the same. */ + string_PXwd, /* \W */ + string_pXwd /* \w */ +}; + +/* The POSIX class substitutes must be in the order of the POSIX class names, +defined above, and there are both positive and negative cases. NULL means no +general substitute of a Unicode property escape (\p or \P). However, for some +POSIX classes (e.g. graph, print, punct) a special property code is compiled +directly. */ + +static const PCRE2_UCHAR string_pCc[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pL[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pLl[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pLu[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_pXan[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_h[] = { + CHAR_BACKSLASH, CHAR_h, '\0' }; +static const PCRE2_UCHAR string_pXps[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PCc[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PL[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PLl[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PLu[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_PXan[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const PCRE2_UCHAR string_H[] = { + CHAR_BACKSLASH, CHAR_H, '\0' }; +static const PCRE2_UCHAR string_PXps[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static PCRE2_SPTR posix_substitutes[] = { + string_pL, /* alpha */ + string_pLl, /* lower */ + string_pLu, /* upper */ + string_pXan, /* alnum */ + NULL, /* ascii */ + string_h, /* blank */ + string_pCc, /* cntrl */ + string_pNd, /* digit */ + NULL, /* graph */ + NULL, /* print */ + NULL, /* punct */ + string_pXps, /* space */ /* Xps is POSIX space, but from 8.34 */ + string_pXwd, /* word */ /* Perl and POSIX space are the same */ + NULL, /* xdigit */ + /* Negated cases */ + string_PL, /* ^alpha */ + string_PLl, /* ^lower */ + string_PLu, /* ^upper */ + string_PXan, /* ^alnum */ + NULL, /* ^ascii */ + string_H, /* ^blank */ + string_PCc, /* ^cntrl */ + string_PNd, /* ^digit */ + NULL, /* ^graph */ + NULL, /* ^print */ + NULL, /* ^punct */ + string_PXps, /* ^space */ /* Xps is POSIX space, but from 8.34 */ + string_PXwd, /* ^word */ /* Perl and POSIX space are the same */ + NULL /* ^xdigit */ +}; +#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(PCRE2_UCHAR *)) +#endif /* SUPPORT_UNICODE */ + +/* Masks for checking option settings. */ + +#define PUBLIC_COMPILE_OPTIONS \ + (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \ + PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \ + PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \ + PCRE2_MATCH_UNSET_BACKREF|PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C| \ + PCRE2_NEVER_UCP|PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE| \ + PCRE2_NO_AUTO_POSSESS|PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_NO_START_OPTIMIZE| \ + PCRE2_NO_UTF_CHECK|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_USE_OFFSET_LIMIT| \ + PCRE2_UTF) + +/* Compile time error code numbers. They are given names so that they can more +easily be tracked. When a new number is added, the tables called eint1 and +eint2 in pcre2posix.c may need to be updated, and a new error text must be +added to compile_error_texts in pcre2_error.c. */ + +enum { ERR0 = COMPILE_ERROR_BASE, + ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, + ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, + ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, + ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, + ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, + ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, + ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, + ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, + ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88 }; + +/* Error codes that correspond to negative error codes returned by +find_fixedlength(). */ + +static int fixed_length_errors[] = + { + ERR0, /* Not an error */ + ERR0, /* Not an error; -1 is used for "process later" */ + ERR25, /* Lookbehind is not fixed length */ + ERR36, /* \C in lookbehind is not allowed */ + ERR87, /* Lookbehind is too long */ + ERR86, /* Pattern too complicated */ + ERR70 /* Internal error: unknown opcode encountered */ + }; + +/* This is a table of start-of-pattern options such as (*UTF) and settings such +as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward +compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is +generic and always supported. */ + +enum { PSO_OPT, /* Value is an option bit */ + PSO_FLG, /* Value is a flag bit */ + PSO_NL, /* Value is a newline type */ + PSO_BSR, /* Value is a \R type */ + PSO_LIMM, /* Read integer value for match limit */ + PSO_LIMR }; /* Read integer value for recursion limit */ + +typedef struct pso { + const uint8_t *name; + uint16_t length; + uint16_t type; + uint32_t value; +} pso; + +/* NB: STRING_UTFn_RIGHTPAR contains the length as well */ + +static pso pso_list[] = { + { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, + { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, + { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, + { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, + { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, + { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS }, + { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR }, + { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, + { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE }, + { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, + { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMR, 0 }, + { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, + { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, + { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, + { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, + { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, + { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, + { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } +}; + +/* This table is used when converting repeating opcodes into possessified +versions as a result of an explicit possessive quantifier such as ++. A zero +value means there is no possessified version - in those cases the item in +question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT +because all relevant opcodes are less than that. */ + +static const uint8_t opcode_possessify[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */ + + 0, /* NOTI */ + OP_POSSTAR, 0, /* STAR, MINSTAR */ + OP_POSPLUS, 0, /* PLUS, MINPLUS */ + OP_POSQUERY, 0, /* QUERY, MINQUERY */ + OP_POSUPTO, 0, /* UPTO, MINUPTO */ + 0, /* EXACT */ + 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */ + + OP_POSSTARI, 0, /* STARI, MINSTARI */ + OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */ + OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */ + OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */ + 0, /* EXACTI */ + 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */ + + OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */ + OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */ + OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */ + OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */ + 0, /* NOTEXACT */ + 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */ + + OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */ + OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */ + OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */ + OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */ + 0, /* NOTEXACTI */ + 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */ + + OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */ + OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */ + OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */ + OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */ + 0, /* TYPEEXACT */ + 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */ + + OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */ + OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */ + OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */ + OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */ + 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */ + + 0, 0, 0, /* CLASS, NCLASS, XCLASS */ + 0, 0, /* REF, REFI */ + 0, 0, /* DNREF, DNREFI */ + 0, 0 /* RECURSE, CALLOUT */ +}; + + + +/************************************************* +* Free compiled code * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_code_free(pcre2_code *code) +{ +PCRE2_SIZE* ref_count; + +if (code != NULL) + { + if (code->executable_jit != NULL) + PRIV(jit_free)(code->executable_jit, &code->memctl); + + if ((code->flags & PCRE2_DEREF_TABLES) != 0) + { + /* Decoded tables belong to the codes after deserialization, and they must + be freed when there are no more reference to them. The *ref_count should + always be > 0. */ + + ref_count = (PCRE2_SIZE *)(code->tables + tables_length); + if (*ref_count > 0) + { + (*ref_count)--; + if (*ref_count == 0) + code->memctl.free((void *)code->tables, code->memctl.memory_data); + } + } + + code->memctl.free(code, code->memctl.memory_data); + } +} + + + +/************************************************* +* Insert an automatic callout point * +*************************************************/ + +/* This function is called when the PCRE2_AUTO_CALLOUT option is set, to insert +callout points before each pattern item. + +Arguments: + code current code pointer + ptr current pattern pointer + cb general compile-time data + +Returns: new code pointer +*/ + +static PCRE2_UCHAR * +auto_callout(PCRE2_UCHAR *code, PCRE2_SPTR ptr, compile_block *cb) +{ +code[0] = OP_CALLOUT; +PUT(code, 1, ptr - cb->start_pattern); /* Pattern offset */ +PUT(code, 1 + LINK_SIZE, 0); /* Default length */ +code[1 + 2*LINK_SIZE] = 255; +return code + PRIV(OP_lengths)[OP_CALLOUT]; +} + + + +/************************************************* +* Complete a callout item * +*************************************************/ + +/* A callout item contains the length of the next item in the pattern, which +we can't fill in till after we have reached the relevant point. This is used +for both automatic and manual callouts. + +Arguments: + previous_callout points to previous callout item + ptr current pattern pointer + cb general compile-time data + +Returns: nothing +*/ + +static void +complete_callout(PCRE2_UCHAR *previous_callout, PCRE2_SPTR ptr, + compile_block *cb) +{ +size_t length = ptr - cb->start_pattern - GET(previous_callout, 1); +PUT(previous_callout, 1 + LINK_SIZE, length); +} + + + +/************************************************* +* Find the fixed length of a branch * +*************************************************/ + +/* Scan a branch and compute the fixed length of subject that will match it, if +the length is fixed. This is needed for dealing with lookbehind assertions. In +UTF mode, the result is in code units rather than bytes. The branch is +temporarily terminated with OP_END when this function is called. + +This function is called when a lookbehind assertion is encountered, so that if +it fails, the error message can point to the correct place in the pattern. +However, we cannot do this when the assertion contains subroutine calls, +because they can be forward references. We solve this by remembering this case +and doing the check at the end; a flag specifies which mode we are running in. + +Lookbehind lengths are held in 16-bit fields and the maximum value is defined +as LOOKBEHIND_MAX. + +Arguments: + code points to the start of the pattern (the bracket) + utf TRUE in UTF mode + atend TRUE if called when the pattern is complete + cb the "compile data" structure + recurses chain of recurse_check to catch mutual recursion + countptr pointer to counter, to catch over-complexity + +Returns: if non-negative, the fixed length, + or -1 if an OP_RECURSE item was encountered and atend is FALSE + or -2 if there is no fixed length, + or -3 if \C was encountered (in UTF-8 mode only) + or -4 length is too long + or -5 if an unknown opcode was encountered (internal error) +*/ + +#define FFL_LATER (-1) +#define FFL_NOTFIXED (-2) +#define FFL_BACKSLASHC (-3) +#define FFL_TOOLONG (-4) +#define FFL_TOOCOMPLICATED (-5) +#define FFL_UNKNOWNOP (-6) + +static int +find_fixedlength(PCRE2_UCHAR *code, BOOL utf, BOOL atend, compile_block *cb, + recurse_check *recurses, int *countptr) +{ +int length = -1; +uint32_t group = 0; +uint32_t groupinfo = 0; +recurse_check this_recurse; +register int branchlength = 0; +register PCRE2_UCHAR *cc = code + 1 + LINK_SIZE; + +/* If this is a capturing group, we may have the answer cached, but we can only +use this information if there are no (?| groups in the pattern, because +otherwise group numbers are not unique. */ + +if (*code == OP_CBRA || *code == OP_CBRAPOS || *code == OP_SCBRA || + *code == OP_SCBRAPOS) + { + group = GET2(cc, 0); + cc += IMM2_SIZE; + groupinfo = cb->groupinfo[group]; + if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0) + { + if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return FFL_NOTFIXED; + if ((groupinfo & GI_SET_FIXED_LENGTH) != 0) + return groupinfo & GI_FIXED_LENGTH_MASK; + } + } + +/* A large and/or complex regex can take too long to process. This can happen +more often when (?| groups are present in the pattern. */ + +if ((*countptr)++ > 2000) return FFL_TOOCOMPLICATED; + +/* Scan along the opcodes for this branch. If we get to the end of the +branch, check the length against that of the other branches. */ + +for (;;) + { + int d; + PCRE2_UCHAR *ce, *cs; + register PCRE2_UCHAR op = *cc; + + if (branchlength > LOOKBEHIND_MAX) return FFL_TOOLONG; + + switch (op) + { + /* We only need to continue for OP_CBRA (normal capturing bracket) and + OP_BRA (normal non-capturing bracket) because the other variants of these + opcodes are all concerned with unlimited repeated groups, which of course + are not of fixed length. */ + + case OP_CBRA: + case OP_BRA: + case OP_ONCE: + case OP_ONCE_NC: + case OP_COND: + d = find_fixedlength(cc, utf, atend, cb, recurses, countptr); + if (d < 0) return d; + branchlength += d; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* Reached end of a branch; if it's a ket it is the end of a nested call. + If it's ALT it is an alternation in a nested call. An ACCEPT is effectively + an ALT. If it is END it's the end of the outer call. All can be handled by + the same code. Note that we must not include the OP_KETRxxx opcodes here, + because they all imply an unlimited repeat. */ + + case OP_ALT: + case OP_KET: + case OP_END: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + if (length < 0) length = branchlength; + else if (length != branchlength) goto ISNOTFIXED; + if (*cc != OP_ALT) + { + if (group > 0) + { + groupinfo |= (GI_SET_FIXED_LENGTH | length); + cb->groupinfo[group] = groupinfo; + } + return length; + } + cc += 1 + LINK_SIZE; + branchlength = 0; + break; + + /* A true recursion implies not fixed length, but a subroutine call may + be OK. If the subroutine is a forward reference, we can't deal with + it until the end of the pattern, so return FFL_LATER. */ + + case OP_RECURSE: + if (!atend) return FFL_LATER; + cs = ce = (PCRE2_UCHAR *)cb->start_code + GET(cc, 1); /* Start subpattern */ + do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ + if (cc > cs && cc < ce) goto ISNOTFIXED; /* Recursion */ + else /* Check for mutual recursion */ + { + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) goto ISNOTFIXED; /* Mutual recursion */ + } + this_recurse.prev = recurses; + this_recurse.group = cs; + d = find_fixedlength(cs, utf, atend, cb, &this_recurse, countptr); + if (d < 0) return d; + branchlength += d; + cc += 1 + LINK_SIZE; + break; + + /* Skip over assertive subpatterns. Note that we must increment cc by + 1 + LINK_SIZE at the end, not by OP_length[*cc] because in a recursive + situation this assertion may be the one that is ultimately being checked + for having a fixed length, in which case its terminating OP_KET will have + been temporarily replaced by OP_END. */ + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* Skip over things that don't match chars */ + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += cc[1] + PRIV(OP_lengths)[*cc]; + break; + + case OP_CALLOUT: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: + case OP_CREF: + case OP_FALSE: + case OP_TRUE: + case OP_DNCREF: + case OP_DNRREF: + case OP_DOLL: + case OP_DOLLM: + case OP_EOD: + case OP_EODN: + case OP_FAIL: + case OP_NOT_WORD_BOUNDARY: + case OP_PRUNE: + case OP_REVERSE: + case OP_RREF: + case OP_SET_SOM: + case OP_SKIP: + case OP_SOD: + case OP_SOM: + case OP_THEN: + case OP_WORD_BOUNDARY: + cc += PRIV(OP_lengths)[*cc]; + break; + + case OP_CALLOUT_STR: + cc += GET(cc, 1 + 2*LINK_SIZE); + break; + + /* Handle literal characters */ + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + branchlength++; + cc += 2; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + /* Handle exact repetitions. The count is already in characters, but we + need to skip over a multibyte character in UTF8 mode. */ + + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + branchlength += (int)GET2(cc,1); + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + case OP_TYPEEXACT: + branchlength += GET2(cc,1); + if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) + cc += 2; + cc += 1 + IMM2_SIZE + 1; + break; + + /* Handle single-char matchers */ + + case OP_PROP: + case OP_NOTPROP: + cc += 2; + /* Fall through */ + + case OP_HSPACE: + case OP_VSPACE: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + branchlength++; + cc++; + break; + + /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; + otherwise \C is coded as OP_ALLANY. */ + + case OP_ANYBYTE: + return FFL_BACKSLASHC; + + /* Check a class for variable quantification */ + + case OP_CLASS: + case OP_NCLASS: +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + /* The original code caused an unsigned overflow in 64 bit systems, + so now we use a conditional statement. */ + if (op == OP_XCLASS) + cc += GET(cc, 1); + else + cc += PRIV(OP_lengths)[OP_CLASS]; +#else + cc += PRIV(OP_lengths)[OP_CLASS]; +#endif + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + goto ISNOTFIXED; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) goto ISNOTFIXED; + branchlength += (int)GET2(cc,1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + branchlength++; + } + break; + + /* Anything else is variable length */ + + case OP_ANYNL: + case OP_BRAMINZERO: + case OP_BRAPOS: + case OP_BRAPOSZERO: + case OP_BRAZERO: + case OP_CBRAPOS: + case OP_EXTUNI: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_PLUS: + case OP_PLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_QUERY: + case OP_QUERYI: + case OP_REF: + case OP_REFI: + case OP_DNREF: + case OP_DNREFI: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + case OP_SCOND: + case OP_SKIPZERO: + case OP_STAR: + case OP_STARI: + case OP_TYPEMINPLUS: + case OP_TYPEMINQUERY: + case OP_TYPEMINSTAR: + case OP_TYPEMINUPTO: + case OP_TYPEPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSUPTO: + case OP_TYPEQUERY: + case OP_TYPESTAR: + case OP_TYPEUPTO: + case OP_UPTO: + case OP_UPTOI: + goto ISNOTFIXED; + + /* Catch unrecognized opcodes so that when new ones are added they + are not forgotten, as has happened in the past. */ + + default: + return FFL_UNKNOWNOP; + } + } +/* Control never gets here except by goto. */ + +ISNOTFIXED: +if (group > 0) + { + groupinfo |= GI_NOT_FIXED_LENGTH; + cb->groupinfo[group] = groupinfo; + } +return FFL_NOTFIXED; +} + + + +/************************************************* +* Find first significant op code * +*************************************************/ + +/* This is called by several functions that scan a compiled expression looking +for a fixed first character, or an anchoring op code etc. It skips over things +that do not influence this. For some calls, it makes sense to skip negative +forward and all backward assertions, and also the \b assertion; for others it +does not. + +Arguments: + code pointer to the start of the group + skipassert TRUE if certain assertions are to be skipped + +Returns: pointer to the first significant opcode +*/ + +static const PCRE2_UCHAR* +first_significant_code(PCRE2_SPTR code, BOOL skipassert) +{ +for (;;) + { + switch ((int)*code) + { + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + if (!skipassert) return code; + do code += GET(code, 1); while (*code == OP_ALT); + code += PRIV(OP_lengths)[*code]; + break; + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + if (!skipassert) return code; + /* Fall through */ + + case OP_CALLOUT: + case OP_CREF: + case OP_DNCREF: + case OP_RREF: + case OP_DNRREF: + case OP_FALSE: + case OP_TRUE: + code += PRIV(OP_lengths)[*code]; + break; + + case OP_CALLOUT_STR: + code += GET(code, 1 + 2*LINK_SIZE); + break; + + default: + return code; + } + } +/* Control never reaches here */ +} + + + +/************************************************* +* Scan compiled branch for non-emptiness * +*************************************************/ + +/* This function scans through a branch of a compiled pattern to see whether it +can match the empty string. It is called at the end of compiling to check the +entire pattern, and from compile_branch() when checking for an unlimited repeat +of a group that can match nothing. In the latter case it is called only when +doing the real compile, not during the pre-compile that measures the size of +the compiled pattern. + +Note that first_significant_code() skips over backward and negative forward +assertions when its final argument is TRUE. If we hit an unclosed bracket, we +return "empty" - this means we've struck an inner bracket whose current branch +will already have been scanned. + +Arguments: + code points to start of search + endcode points to where to stop + utf TRUE if in UTF mode + cb compile data + atend TRUE if being called to check an entire pattern + recurses chain of recurse_check to catch mutual recursion + countptr pointer to count to catch over-complicated pattern + +Returns: 0 if what is matched cannot be empty + 1 if what is matched could be empty + -1 if the pattern is too complicated +*/ + +#define CBE_NOTEMPTY 0 +#define CBE_EMPTY 1 +#define CBE_TOOCOMPLICATED (-1) + + +static int +could_be_empty_branch(PCRE2_SPTR code, PCRE2_SPTR endcode, BOOL utf, + compile_block *cb, BOOL atend, recurse_check *recurses, int *countptr) +{ +uint32_t group = 0; +uint32_t groupinfo = 0; +register PCRE2_UCHAR c; +recurse_check this_recurse; + +/* If what we are checking has already been set as "could be empty", we know +the answer. */ + +if (*code >= OP_SBRA && *code <= OP_SCOND) return CBE_EMPTY; + +/* If this is a capturing group, we may have the answer cached, but we can only +use this information if there are no (?| groups in the pattern, because +otherwise group numbers are not unique. */ + +if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0 && + (*code == OP_CBRA || *code == OP_CBRAPOS)) + { + group = GET2(code, 1 + LINK_SIZE); + groupinfo = cb->groupinfo[group]; + if ((groupinfo & GI_SET_COULD_BE_EMPTY) != 0) + return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY; + } + +/* A large and/or complex regex can take too long to process. We have to assume +it can match an empty string. This can happen more often when (?| groups are +present in the pattern and the caching is disabled. Setting the cap at 1100 +allows the test for more than 1023 capturing patterns to work. */ + +if ((*countptr)++ > 1100) return CBE_TOOCOMPLICATED; + +/* Scan the opcodes for this branch. */ + +for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); + code < endcode; + code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) + { + PCRE2_SPTR ccode; + + c = *code; + + /* Skip over forward assertions; the other assertions are skipped by + first_significant_code() with a TRUE final argument. */ + + if (c == OP_ASSERT) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + + /* For a recursion/subroutine call we can scan the recursion when this + function is called at the end, to check a complete pattern. Before then, + recursions just have the group number as their argument and in any case may + be forward references. In that situation, we return CBE_EMPTY, just in case. + It means that unlimited repeats of groups that contain recursions are always + treated as "could be empty" - which just adds a bit more processing time + because of the runtime check. */ + + if (c == OP_RECURSE) + { + PCRE2_SPTR scode, endgroup; + BOOL empty_branch; + + if (!atend) goto ISTRUE; + scode = cb->start_code + GET(code, 1); + endgroup = scode; + + /* We need to detect whether this is a recursive call, as otherwise there + will be an infinite loop. If it is a recursion, just skip over it. Simple + recursions are easily detected. For mutual recursions we keep a chain on + the stack. */ + + do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT); + if (code >= scode && code <= endgroup) continue; /* Simple recursion */ + else + { + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) + if (r->group == scode) break; + if (r != NULL) continue; /* Mutual recursion */ + } + + /* Scan the referenced group, remembering it on the stack chain to detect + mutual recursions. */ + + empty_branch = FALSE; + this_recurse.prev = recurses; + this_recurse.group = scode; + + do + { + int rc = could_be_empty_branch(scode, endcode, utf, cb, atend, + &this_recurse, countptr); + if (rc < 0) return rc; + if (rc > 0) + { + empty_branch = TRUE; + break; + } + scode += GET(scode, 1); + } + while (*scode == OP_ALT); + + if (!empty_branch) goto ISFALSE; /* All branches are non-empty */ + continue; + } + + /* Groups with zero repeats can of course be empty; skip them. */ + + if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO || + c == OP_BRAPOSZERO) + { + code += PRIV(OP_lengths)[c]; + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + + /* A nested group that is already marked as "could be empty" can just be + skipped. */ + + if (c == OP_SBRA || c == OP_SBRAPOS || + c == OP_SCBRA || c == OP_SCBRAPOS) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + + /* For other groups, scan the branches. */ + + if (c == OP_BRA || c == OP_BRAPOS || + c == OP_CBRA || c == OP_CBRAPOS || + c == OP_ONCE || c == OP_ONCE_NC || + c == OP_COND || c == OP_SCOND) + { + BOOL empty_branch; + if (GET(code, 1) == 0) goto ISTRUE; /* Hit unclosed bracket */ + + /* If a conditional group has only one branch, there is a second, implied, + empty branch, so just skip over the conditional, because it could be empty. + Otherwise, scan the individual branches of the group. */ + + if (c == OP_COND && code[GET(code, 1)] != OP_ALT) + code += GET(code, 1); + else + { + empty_branch = FALSE; + do + { + if (!empty_branch) + { + int rc = could_be_empty_branch(code, endcode, utf, cb, atend, + recurses, countptr); + if (rc < 0) return rc; + if (rc > 0) empty_branch = TRUE; + } + code += GET(code, 1); + } + while (*code == OP_ALT); + if (!empty_branch) goto ISFALSE; /* All branches are non-empty */ + } + + c = *code; + continue; + } + + /* Handle the other opcodes */ + + switch (c) + { + /* Check for quantifiers after a class. XCLASS is used for classes that + cannot be represented just by a bit map. This includes negated single + high-valued characters. The length in PRIV(OP_lengths)[] is zero; the + actual length is stored in the compiled code, so we must update "code" + here. */ + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + ccode = code += GET(code, 1); + goto CHECK_CLASS_REPEAT; +#endif + + case OP_CLASS: + case OP_NCLASS: + ccode = code + PRIV(OP_lengths)[OP_CLASS]; + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + CHECK_CLASS_REPEAT: +#endif + + switch (*ccode) + { + case OP_CRSTAR: /* These could be empty; continue */ + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + break; + + default: /* Non-repeat => class must match */ + case OP_CRPLUS: /* These repeats aren't empty */ + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + goto ISFALSE; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(ccode, 1) > 0) goto ISFALSE; /* Minimum > 0 */ + break; + } + break; + + /* Opcodes that must match a character */ + + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + + case OP_PROP: + case OP_NOTPROP: + case OP_ANYNL: + + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + + case OP_PLUS: + case OP_PLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEEXACT: + goto ISFALSE; + + /* These are going to continue, as they may be empty, but we have to + fudge the length for the \p and \P cases. */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + /* Same for these */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + /* End of branch */ + + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_ALT: + goto ISTRUE; + + /* In UTF-8 or UTF-16 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, + POSQUERY, UPTO, MINUPTO, and POSUPTO and their caseless and negative + versions may be followed by a multibyte character. */ + +#ifdef MAYBE_UTF_MULTI + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + + case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + + case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); + break; + + case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); + break; +#endif /* MAYBE_UTF_MULTI */ + + /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument + string. */ + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1]; + break; + + /* None of the remaining opcodes are required to match a character. */ + + default: + break; + } + } + +ISTRUE: +groupinfo |= GI_COULD_BE_EMPTY; + +ISFALSE: +if (group > 0) cb->groupinfo[group] = groupinfo | GI_SET_COULD_BE_EMPTY; + +return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY; +} + + + +/************************************************* +* Check for counted repeat * +*************************************************/ + +/* This function is called when a '{' is encountered in a place where it might +start a quantifier. It looks ahead to see if it really is a quantifier, that +is, one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits. + +Argument: pointer to the first char after '{' +Returns: TRUE or FALSE +*/ + +static BOOL +is_counted_repeat(PCRE2_SPTR p) +{ +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (*p++ != CHAR_COMMA) return FALSE; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; + +return (*p == CHAR_RIGHT_CURLY_BRACKET); +} + + + +/************************************************* +* Handle escapes * +*************************************************/ + +/* This function is called when a \ has been encountered. It either returns a +positive value for a simple escape such as \d, or 0 for a data character, which +is placed in chptr. A backreference to group n is returned as negative n. On +entry, ptr is pointing at the \. On exit, it points the final code unit of the +escape sequence. + +This function is also called from pcre2_substitute() to handle escape sequences +in replacement strings. In this case, the cb argument is NULL, and only +sequences that define a data character are recognised. The isclass argument is +not relevant, but the options argument is the final value of the compiled +pattern's options. + +There is one "trick" case: when a sequence such as [[:>:]] or \s in UCP mode is +processed, it is replaced by a nested alternative sequence. If this contains a +backslash (which is usually does), ptrend does not point to its end - it still +points to the end of the whole pattern. However, we can detect this case +because cb->nestptr[0] will be non-NULL. The nested sequences are all zero- +terminated and there are only ever two levels of nesting. + +Arguments: + ptrptr points to the input position pointer + ptrend points to the end of the input + chptr points to a returned data character + errorcodeptr points to the errorcode variable (containing zero) + options the current options bits + isclass TRUE if inside a character class + cb compile data block + +Returns: zero => a data character + positive => a special escape sequence + negative => a back reference + on error, errorcodeptr is set non-zero +*/ + +int +PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, + int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb) +{ +BOOL utf = (options & PCRE2_UTF) != 0; +PCRE2_SPTR ptr = *ptrptr + 1; +register uint32_t c, cc; +int escape = 0; +int i; + +/* Find the end of a nested insert. */ + +if (cb != NULL && cb->nestptr[0] != NULL) + ptrend = ptr + PRIV(strlen)(ptr); + +/* If backslash is at the end of the string, it's an error. */ + +if (ptr >= ptrend) + { + *errorcodeptr = ERR1; + return 0; + } + +GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ +ptr--; /* Set pointer back to the last code unit */ + +/* Non-alphanumerics are literals, so we just leave the value in c. An initial +value test saves a memory lookup for code points outside the alphanumeric +range. Otherwise, do a table lookup. A non-zero result is something that can be +returned immediately. Otherwise further processing is required. */ + +if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {} /* Definitely literal */ + +else if ((i = escapes[c - ESCAPES_FIRST]) != 0) + { + if (i > 0) c = (uint32_t)i; else /* Positive is a data character */ + { + escape = -i; /* Else return a special escape */ + if (escape == ESC_P || escape == ESC_p || escape == ESC_X) + cb->external_flags |= PCRE2_HASBKPORX; /* Note \P, \p, or \X */ + } + } + +/* Escapes that need further processing, including those that are unknown. +When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u +when BSUX is set). */ + +else + { + PCRE2_SPTR oldptr; + BOOL braced, negated, overflow; + unsigned int s; + + /* Filter calls from pcre2_substitute(). */ + + if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x && + (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0)) + { + *errorcodeptr = ERR3; + return 0; + } + + switch (c) + { + /* A number of Perl escapes are not handled by PCRE. We give an explicit + error. */ + + case CHAR_l: + case CHAR_L: + *errorcodeptr = ERR37; + break; + + /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated + specially, \u must be followed by four hex digits. Otherwise it is a + lowercase u letter. */ + + case CHAR_u: + if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else + { + uint32_t xc; + if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ + if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ + cc = (cc << 4) | xc; + if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */ + cc = (cc << 4) | xc; + if ((xc = XDIGIT(ptr[4])) == 0xff) break; /* Not a hex digit */ + c = (cc << 4) | xc; + ptr += 4; + if (utf) + { + if (c > 0x10ffffU) *errorcodeptr = ERR77; + else if (c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77; + } + break; + + case CHAR_U: + /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an + upper case letter. */ + if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; + break; + + /* In a character class, \g is just a literal "g". Outside a character + class, \g must be followed by one of a number of specific things: + + (1) A number, either plain or braced. If positive, it is an absolute + backreference. If negative, it is a relative backreference. This is a Perl + 5.10 feature. + + (2) Perl 5.10 also supports \g{name} as a reference to a named group. This + is part of Perl's movement towards a unified syntax for back references. As + this is synonymous with \k{name}, we fudge it up by pretending it really + was \k. + + (3) For Oniguruma compatibility we also support \g followed by a name or a + number either in angle brackets or in single quotes. However, these are + (possibly recursive) subroutine calls, _not_ backreferences. Just return + the ESC_g code (cf \k). */ + + case CHAR_g: + if (isclass) break; + if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) + { + escape = ESC_g; + break; + } + + /* Handle the Perl-compatible cases */ + + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) + { + PCRE2_SPTR p; + for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++) + if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; + if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET) + { + escape = ESC_k; + break; + } + braced = TRUE; + ptr++; + } + else braced = FALSE; + + if (ptr[1] == CHAR_MINUS) + { + negated = TRUE; + ptr++; + } + else negated = FALSE; + + /* The integer range is limited by the machine's int representation. */ + s = 0; + overflow = FALSE; + while (IS_DIGIT(ptr[1])) + { + if (s > INT_MAX / 10 - 1) /* Integer overflow */ + { + overflow = TRUE; + break; + } + s = s * 10 + (int)(*(++ptr) - CHAR_0); + } + if (overflow) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) ptr++; + *errorcodeptr = ERR61; + break; + } + + if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET) + { + *errorcodeptr = ERR57; + break; + } + + if (s == 0) + { + *errorcodeptr = ERR58; + break; + } + + if (negated) + { + if (s > cb->bracount) + { + *errorcodeptr = ERR15; + break; + } + s = cb->bracount - (s - 1); + } + + escape = -(int)s; + break; + + /* The handling of escape sequences consisting of a string of digits + starting with one that is not zero is not straightforward. Perl has changed + over the years. Nowadays \g{} for backreferences and \o{} for octal are + recommended to avoid the ambiguities in the old syntax. + + Outside a character class, the digits are read as a decimal number. If the + number is less than 10, or if there are that many previous extracting left + brackets, it is a back reference. Otherwise, up to three octal digits are + read to form an escaped character code. Thus \123 is likely to be octal 123 + (cf \0123, which is octal 012 followed by the literal 3). + + Inside a character class, \ followed by a digit is always either a literal + 8 or 9 or an octal number. */ + + case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: + case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: + + if (!isclass) + { + oldptr = ptr; + /* The integer range is limited by the machine's int representation. */ + s = c - CHAR_0; + overflow = FALSE; + while (IS_DIGIT(ptr[1])) + { + if (s > INT_MAX / 10 - 1) /* Integer overflow */ + { + overflow = TRUE; + break; + } + s = s * 10 + (int)(*(++ptr) - CHAR_0); + } + if (overflow) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) ptr++; + *errorcodeptr = ERR61; + break; + } + + /* \1 to \9 are always back references. \8x and \9x are too; \1x to \7x + are octal escapes if there are not that many previous captures. */ + + if (s < 10 || *oldptr >= CHAR_8 || s <= cb->bracount) + { + escape = -(int)s; /* Indicates a back reference */ + break; + } + ptr = oldptr; /* Put the pointer back and fall through */ + } + + /* Handle a digit following \ when the number is not a back reference, or + we are within a character class. If the first digit is 8 or 9, Perl used to + generate a binary zero byte and then treat the digit as a following + literal. At least by Perl 5.18 this changed so as not to insert the binary + zero. */ + + if ((c = *ptr) >= CHAR_8) break; + + /* Fall through with a digit less than 8 */ + + /* \0 always starts an octal number, but we may drop through to here with a + larger first octal digit. The original code used just to take the least + significant 8 bits of octal numbers (I think this is what early Perls used + to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, + but no more than 3 octal digits. */ + + case CHAR_0: + c -= CHAR_0; + while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) + c = c * 8 + *(++ptr) - CHAR_0; +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (!utf && c > 0xff) *errorcodeptr = ERR51; +#endif + break; + + /* \o is a relatively new Perl feature, supporting a more general way of + specifying character codes in octal. The only supported form is \o{ddd}. */ + + case CHAR_o: + if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR55; else + if (ptr[2] == CHAR_RIGHT_CURLY_BRACKET) *errorcodeptr = ERR78; else + { + ptr += 2; + c = 0; + overflow = FALSE; + while (*ptr >= CHAR_0 && *ptr <= CHAR_7) + { + cc = *ptr++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x20000000l) { overflow = TRUE; break; } +#endif + c = (c << 3) + (cc - CHAR_0); +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } +#elif PCRE2_CODE_UNIT_WIDTH == 16 + if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } +#elif PCRE2_CODE_UNIT_WIDTH == 32 + if (utf && c > 0x10ffffU) { overflow = TRUE; break; } +#endif + } + if (overflow) + { + while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; + *errorcodeptr = ERR34; + } + else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + else *errorcodeptr = ERR64; + } + break; + + /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by + two hexadecimal digits. Otherwise it is a lowercase x letter. */ + + case CHAR_x: + if ((options & PCRE2_ALT_BSUX) != 0) + { + uint32_t xc; + if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ + if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ + c = (cc << 4) | xc; + ptr += 2; + } /* End PCRE2_ALT_BSUX handling */ + + /* Handle \x in Perl's style. \x{ddd} is a character number which can be + greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex + digits. If not, { used to be treated as a data character. However, Perl + seems to read hex digits up to the first non-such, and ignore the rest, so + that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE + now gives an error. */ + + else + { + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) + { + ptr += 2; + if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + *errorcodeptr = ERR78; + break; + } + c = 0; + overflow = FALSE; + + while ((cc = XDIGIT(*ptr)) != 0xff) + { + ptr++; + if (c == 0 && cc == 0) continue; /* Leading zeroes */ +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x10000000l) { overflow = TRUE; break; } +#endif + c = (c << 4) | cc; + if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR)) + { + overflow = TRUE; + break; + } + } + + if (overflow) + { + while (XDIGIT(*ptr) != 0xff) ptr++; + *errorcodeptr = ERR34; + } + else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + + /* If the sequence of hex digits does not end with '}', give an error. + We used just to recognize this construct and fall through to the normal + \x handling, but nowadays Perl gives an error, which seems much more + sensible, so we do too. */ + + else *errorcodeptr = ERR67; + } /* End of \x{} processing */ + + /* Read a single-byte hex-defined char (up to two hex digits after \x) */ + + else + { + c = 0; + if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ + ptr++; + c = cc; + if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ + ptr++; + c = (c << 4) | cc; + } /* End of \xdd handling */ + } /* End of Perl-style \x handling */ + break; + + /* The handling of \c is different in ASCII and EBCDIC environments. In an + ASCII (or Unicode) environment, an error is given if the character + following \c is not a printable ASCII character. Otherwise, the following + character is upper-cased if it is a letter, and after that the 0x40 bit is + flipped. The result is the value of the escape. + + In an EBCDIC environment the handling of \c is compatible with the + specification in the perlebcdic document. The following character must be + a letter or one of small number of special characters. These provide a + means of defining the character values 0-31. + + For testing the EBCDIC handling of \c in an ASCII environment, recognize + the EBCDIC value of 'c' explicitly. */ + +#if defined EBCDIC && 'a' != 0x81 + case 0x83: +#else + case CHAR_c: +#endif + + c = *(++ptr); + if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c); + if (c == CHAR_NULL && ptr >= ptrend) + { + *errorcodeptr = ERR2; + break; + } + + /* Handle \c in an ASCII/Unicode environment. */ + +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (c < 32 || c > 126) /* Excludes all non-printable ASCII */ + { + *errorcodeptr = ERR68; + break; + } + c ^= 0x40; + + /* Handle \c in an EBCDIC environment. The special case \c? is converted to + 255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC + encoding. (This is the way Perl indicates that it handles \c?.) The other + valid sequences correspond to a list of specific characters. */ + +#else + if (c == CHAR_QUESTION_MARK) + c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff; + else + { + for (i = 0; i < 32; i++) + { + if (c == ebcdic_escape_c[i]) break; + } + if (i < 32) c = i; else *errorcodeptr = ERR68; + } +#endif /* EBCDIC */ + + break; + + /* Any other alphanumeric following \ is an error. Perl gives an error only + if in warning mode, but PCRE doesn't have a warning mode. */ + + default: + *errorcodeptr = ERR3; + break; + } + } + +/* Perl supports \N{name} for character names, as well as plain \N for "not +newline". PCRE does not support \N{name}. However, it does support +quantification such as \N{2,3}. */ + +if (escape == ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && + !is_counted_repeat(ptr+2)) + *errorcodeptr = ERR37; + +/* If PCRE2_UCP is set, we change the values for \d etc. */ + +if ((options & PCRE2_UCP) != 0 && escape >= ESC_D && escape <= ESC_w) + escape += (ESC_DU - ESC_D); + +/* Set the pointer to the final character before returning. */ + +*ptrptr = ptr; +*chptr = c; +return escape; +} + + + +#ifdef SUPPORT_UNICODE +/************************************************* +* Handle \P and \p * +*************************************************/ + +/* This function is called after \P or \p has been encountered, provided that +PCRE2 is compiled with support for UTF and Unicode properties. On entry, the +contents of ptrptr are pointing at the P or p. On exit, it is left pointing at +the final code unit of the escape sequence. + +Arguments: + ptrptr the pattern position pointer + negptr a boolean that is set TRUE for negation else FALSE + ptypeptr an unsigned int that is set to the type value + pdataptr an unsigned int that is set to the detailed property value + errorcodeptr the error code variable + cb the compile data + +Returns: TRUE if the type value was found, or FALSE for an invalid type +*/ + +static BOOL +get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, unsigned int *ptypeptr, + unsigned int *pdataptr, int *errorcodeptr, compile_block *cb) +{ +register PCRE2_UCHAR c; +int i, bot, top; +PCRE2_SPTR ptr = *ptrptr; +PCRE2_UCHAR name[32]; + +*negptr = FALSE; +c = *(++ptr); + +/* \P or \p can be followed by a name in {}, optionally preceded by ^ for +negation. */ + +if (c == CHAR_LEFT_CURLY_BRACKET) + { + if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT) + { + *negptr = TRUE; + ptr++; + } + for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++) + { + c = *(++ptr); + if (c == CHAR_NULL) goto ERROR_RETURN; + if (c == CHAR_RIGHT_CURLY_BRACKET) break; + name[i] = c; + } + if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; + name[i] = 0; + } + +/* Otherwise there is just one following character, which must be an ASCII +letter. */ + +else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0) + { + name[0] = c; + name[1] = 0; + } +else goto ERROR_RETURN; + +*ptrptr = ptr; + +/* Search for a recognized property name using binary chop. */ + +bot = 0; +top = PRIV(utt_size); + +while (bot < top) + { + int r; + i = (bot + top) >> 1; + r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); + if (r == 0) + { + *ptypeptr = PRIV(utt)[i].type; + *pdataptr = PRIV(utt)[i].value; + return TRUE; + } + if (r > 0) bot = i + 1; else top = i; + } +*errorcodeptr = ERR47; /* Unrecognized name */ +return FALSE; + +ERROR_RETURN: /* Malformed \P or \p */ +*errorcodeptr = ERR46; +*ptrptr = ptr; +return FALSE; +} +#endif + + + +/************************************************* +* Read repeat counts * +*************************************************/ + +/* Read an item of the form {n,m} and return the values. This is called only +after is_counted_repeat() has confirmed that a repeat-count quantifier exists, +so the syntax is guaranteed to be correct, but we need to check the values. + +Arguments: + p pointer to first char after '{' + minp pointer to int for min + maxp pointer to int for max + returned as -1 if no max + errorcodeptr points to error code variable + +Returns: pointer to '}' on success; + current ptr on error, with errorcodeptr set non-zero +*/ + +static PCRE2_SPTR +read_repeat_counts(PCRE2_SPTR p, int *minp, int *maxp, int *errorcodeptr) +{ +int min = 0; +int max = -1; + +while (IS_DIGIT(*p)) + { + min = min * 10 + (int)(*p++ - CHAR_0); + if (min > 65535) + { + *errorcodeptr = ERR5; + return p; + } + } + +if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else + { + if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) + { + max = 0; + while(IS_DIGIT(*p)) + { + max = max * 10 + (int)(*p++ - CHAR_0); + if (max > 65535) + { + *errorcodeptr = ERR5; + return p; + } + } + if (max < min) + { + *errorcodeptr = ERR4; + return p; + } + } + } + +*minp = min; +*maxp = max; +return p; +} + + + +/************************************************* +* Scan compiled regex for recursion reference * +*************************************************/ + +/* This function scans through a compiled pattern until it finds an instance of +OP_RECURSE. + +Arguments: + code points to start of expression + utf TRUE in UTF mode + +Returns: pointer to the opcode for OP_RECURSE, or NULL if not found +*/ + +static PCRE2_SPTR +find_recurse(PCRE2_SPTR code, BOOL utf) +{ +for (;;) + { + register PCRE2_UCHAR c = *code; + if (c == OP_END) return NULL; + if (c == OP_RECURSE) return code; + + /* XCLASS is used for classes that cannot be represented just by a bit map. + This includes negated single high-valued characters. CALLOUT_STR is used for + callouts with string arguments. In both cases the length in the table is + zero; the actual length is stored in the compiled code. */ + + if (c == OP_XCLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + + /* Otherwise, we can get the item's length from the table, except that for + repeated character types, we have to test for \p and \P, which have an extra + two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we + must add in its length. */ + + else + { + switch(c) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEPOSUPTO: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may + be followed by a multi-unit character. The length in the table is a + minimum, so we have to arrange to skip the extra units. */ + +#ifdef MAYBE_UTF_MULTI + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_PLUS: + case OP_PLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif /* MAYBE_UTF_MULTI */ + } + } +} + + + +/************************************************* +* Check for POSIX class syntax * +*************************************************/ + +/* This function is called when the sequence "[:" or "[." or "[=" is +encountered in a character class. It checks whether this is followed by a +sequence of characters terminated by a matching ":]" or ".]" or "=]". If we +reach an unescaped ']' without the special preceding character, return FALSE. + +Originally, this function only recognized a sequence of letters between the +terminators, but it seems that Perl recognizes any sequence of characters, +though of course unknown POSIX names are subsequently rejected. Perl gives an +"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE +didn't consider this to be a POSIX class. Likewise for [:1234:]. + +The problem in trying to be exactly like Perl is in the handling of escapes. We +have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX +class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code +below handles the special cases \\ and \], but does not try to do any other +escape processing. This makes it different from Perl for cases such as +[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does +not recognize "l\ower". This is a lesser evil than not diagnosing bad classes +when Perl does, I think. + +A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. +It seems that the appearance of a nested POSIX class supersedes an apparent +external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or +a digit. This is handled by returning FALSE if the start of a new group with +the same terminator is encountered, since the next closing sequence must close +the nested group, not the outer one. + +In Perl, unescaped square brackets may also appear as part of class names. For +example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for +[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not +seem right at all. PCRE does not allow closing square brackets in POSIX class +names. + +Arguments: + ptr pointer to the initial [ + endptr where to return a pointer to the terminating ':', '.', or '=' + +Returns: TRUE or FALSE +*/ + +static BOOL +check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR *endptr) +{ +PCRE2_UCHAR terminator; /* Don't combine these lines; the Solaris cc */ +terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ + +for (++ptr; *ptr != CHAR_NULL; ptr++) + { + if (*ptr == CHAR_BACKSLASH && + (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH)) + ptr++; + else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) || + *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; + else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + { + *endptr = ptr; + return TRUE; + } + } + +return FALSE; +} + + + +/************************************************* +* Check POSIX class name * +*************************************************/ + +/* This function is called to check the name given in a POSIX-style class entry +such as [:alnum:]. + +Arguments: + ptr points to the first letter + len the length of the name + +Returns: a value representing the name, or -1 if unknown +*/ + +static int +check_posix_name(PCRE2_SPTR ptr, int len) +{ +const char *pn = posix_names; +register int yield = 0; +while (posix_name_lengths[yield] != 0) + { + if (len == posix_name_lengths[yield] && + PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield; + pn += posix_name_lengths[yield] + 1; + yield++; + } +return -1; +} + + + +#ifdef SUPPORT_UNICODE +/************************************************* +* Get othercase range * +*************************************************/ + +/* This function is passed the start and end of a class range in UCT mode. It +searches up the characters, looking for ranges of characters in the "other" +case. Each call returns the next one, updating the start address. A character +with multiple other cases is returned on its own with a special return value. + +Arguments: + cptr points to starting character value; updated + d end value + ocptr where to put start of othercase range + odptr where to put end of othercase range + +Yield: -1 when no more + 0 when a range is returned + >0 the CASESET offset for char with multiple other cases + in this case, ocptr contains the original +*/ + +static int +get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, + uint32_t *odptr) +{ +uint32_t c, othercase, next; +unsigned int co; + +/* Find the first character that has an other case. If it has multiple other +cases, return its case offset value. */ + +for (c = *cptr; c <= d; c++) + { + if ((co = UCD_CASESET(c)) != 0) + { + *ocptr = c++; /* Character that has the set */ + *cptr = c; /* Rest of input range */ + return (int)co; + } + if ((othercase = UCD_OTHERCASE(c)) != c) break; + } + +if (c > d) return -1; /* Reached end of range */ + +/* Found a character that has a single other case. Search for the end of the +range, which is either the end of the input range, or a character that has zero +or more than one other cases. */ + +*ocptr = othercase; +next = othercase + 1; + +for (++c; c <= d; c++) + { + if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break; + next++; + } + +*odptr = next - 1; /* End of othercase range */ +*cptr = c; /* Rest of input range */ +return 0; +} +#endif /* SUPPORT_UNICODE */ + + + +/************************************************* +* Add a character or range to a class * +*************************************************/ + +/* This function packages up the logic of adding a character or range of +characters to a class. The character values in the arguments will be within the +valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is +mutually recursive with the function immediately below. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cb compile data + start start of range character + end end of range character + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, + compile_block *cb, uint32_t start, uint32_t end) +{ +uint32_t c; +uint32_t classbits_end = (end <= 0xff ? end : 0xff); +int n8 = 0; + +/* If caseless matching is required, scan the range and process alternate +cases. In Unicode, there are 8-bit characters that have alternate cases that +are greater than 255 and vice-versa. Sometimes we can just extend the original +range. */ + +if ((options & PCRE2_CASELESS) != 0) + { +#ifdef SUPPORT_UNICODE + if ((options & PCRE2_UTF) != 0) + { + int rc; + uint32_t oc, od; + + options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ + c = start; + + while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) + { + /* Handle a single character that has more than one other case. */ + + if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cb, + PRIV(ucd_caseless_sets) + rc, oc); + + /* Do nothing if the other case range is within the original range. */ + + else if (oc >= start && od <= end) continue; + + /* Extend the original range if there is overlap, noting that if oc < c, we + can't have od > end because a subrange is always shorter than the basic + range. Otherwise, use a recursive call to add the additional range. */ + + else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ + else if (od > end && oc <= end + 1) + { + end = od; /* Extend upwards */ + if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); + } + else n8 += add_to_class(classbits, uchardptr, options, cb, oc, od); + } + } + else +#endif /* SUPPORT_UNICODE */ + + /* Not UTF mode */ + + for (c = start; c <= classbits_end; c++) + { + SETBIT(classbits, cb->fcc[c]); + n8++; + } + } + +/* Now handle the original range. Adjust the final value according to the bit +length - this means that the same lists of (e.g.) horizontal spaces can be used +in all cases. */ + +if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR) + end = MAX_NON_UTF_CHAR; + +/* Use the bitmap for characters < 256. Otherwise use extra data.*/ + +for (c = start; c <= classbits_end; c++) + { + /* Regardless of start, c will always be <= 255. */ + SETBIT(classbits, c); + n8++; + } + +#ifdef SUPPORT_WIDE_CHARS +if (start <= 0xff) start = 0xff + 1; + +if (end >= start) + { + PCRE2_UCHAR *uchardata = *uchardptr; + +#ifdef SUPPORT_UNICODE + if ((options & PCRE2_UTF) != 0) + { + if (start < end) + { + *uchardata++ = XCL_RANGE; + uchardata += PRIV(ord2utf)(start, uchardata); + uchardata += PRIV(ord2utf)(end, uchardata); + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + uchardata += PRIV(ord2utf)(start, uchardata); + } + } + else +#endif /* SUPPORT_UNICODE */ + + /* Without UTF support, character values are constrained by the bit length, + and can only be > 256 for 16-bit and 32-bit libraries. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 + {} +#else + if (start < end) + { + *uchardata++ = XCL_RANGE; + *uchardata++ = start; + *uchardata++ = end; + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + *uchardata++ = start; + } +#endif + *uchardptr = uchardata; /* Updata extra data pointer */ + } +#else + (void)uchardptr; /* Avoid compiler warning */ +#endif /* SUPPORT_WIDE_CHARS */ + +return n8; /* Number of 8-bit characters */ +} + + + +/************************************************* +* Add a list of characters to a class * +*************************************************/ + +/* This function is used for adding a list of case-equivalent characters to a +class, and also for adding a list of horizontal or vertical whitespace. If the +list is in order (which it should be), ranges of characters are detected and +handled appropriately. This function is mutually recursive with the function +above. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + except character to omit; this is used when adding lists of + case-equivalent characters to avoid including the one we + already know about + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, + compile_block *cb, const uint32_t *p, unsigned int except) +{ +int n8 = 0; +while (p[0] < NOTACHAR) + { + int n = 0; + if (p[0] != except) + { + while(p[n+1] == p[0] + n + 1) n++; + n8 += add_to_class(classbits, uchardptr, options, cb, p[0], p[n]); + } + p += n + 1; + } +return n8; +} + + + +/************************************************* +* Add characters not in a list to a class * +*************************************************/ + +/* This function is used for adding the complement of a list of horizontal or +vertical whitespace to a class. The list must be in order. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, + uint32_t options, compile_block *cb, const uint32_t *p) +{ +BOOL utf = (options & PCRE2_UTF) != 0; +int n8 = 0; +if (p[0] > 0) + n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1); +while (p[0] < NOTACHAR) + { + while (p[1] == p[0] + 1) p++; + n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1, + (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); + p++; + } +return n8; +} + + + +/************************************************* +* Process (*VERB) name for escapes * +*************************************************/ + +/* This function is called when the PCRE2_ALT_VERBNAMES option is set, to +process the characters in a verb's name argument. It is called twice, once with +codeptr == NULL, to find out the length of the processed name, and again to put +the name into memory. + +Arguments: + ptrptr pointer to the input pointer + codeptr pointer to the compiled code pointer + errorcodeptr pointer to the error code + options the options bits + utf TRUE if processing UTF + cb compile data block + +Returns: length of the processed name, or < 0 on error +*/ + +static int +process_verb_name(PCRE2_SPTR *ptrptr, PCRE2_UCHAR **codeptr, int *errorcodeptr, + uint32_t options, BOOL utf, compile_block *cb) +{ +int32_t arglen = 0; +BOOL inescq = FALSE; +PCRE2_SPTR ptr = *ptrptr; +PCRE2_UCHAR *code = (codeptr == NULL)? NULL : *codeptr; + +for (; ptr < cb->end_pattern; ptr++) + { + uint32_t x = *ptr; + + /* Skip over literals */ + + if (inescq) + { + if (x == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { + inescq = FALSE; + ptr++;; + continue; + } + } + + else /* Not a literal character */ + { + if (x == CHAR_RIGHT_PARENTHESIS) break; + + /* Skip over comments and whitespace in extended mode. */ + + if ((options & PCRE2_EXTENDED) != 0) + { + PCRE2_SPTR wscptr = ptr; + while (MAX_255(x) && (cb->ctypes[x] & ctype_space) != 0) x = *(++ptr); + if (x == CHAR_NUMBER_SIGN) + { + ptr++; + while (*ptr != CHAR_NULL || ptr < cb->end_pattern) + { + if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cb->nllen. */ + ptr += cb->nllen; + break; + } + ptr++; +#ifdef SUPPORT_UNICODE + if (utf) FORWARDCHAR(ptr); +#endif + } + } + + /* If we have skipped any characters, restart the loop. */ + + if (ptr > wscptr) + { + ptr--; + continue; + } + } + + /* Process escapes */ + + if (x == '\\') + { + int rc; + *errorcodeptr = 0; + rc = PRIV(check_escape)(&ptr, cb->end_pattern, &x, errorcodeptr, options, + FALSE, cb); + *ptrptr = ptr; /* For possible error */ + if (*errorcodeptr != 0) return -1; + if (rc != 0) + { + if (rc == ESC_Q) + { + inescq = TRUE; + continue; + } + if (rc == ESC_E) continue; + *errorcodeptr = ERR40; + return -1; + } + } + } + + /* We have the next character in the name. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + if (code == NULL) /* Just want the length */ + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + int i; + for (i = 0; i < PRIV(utf8_table1_size); i++) + if ((int)x <= PRIV(utf8_table1)[i]) break; + arglen += i; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + if (x > 0xffff) arglen++; +#endif + } + else + { + PCRE2_UCHAR cbuff[8]; + x = PRIV(ord2utf)(x, cbuff); + memcpy(code, cbuff, CU2BYTES(x)); + code += x; + } + } + else +#endif /* SUPPORT_UNICODE */ + + /* Not UTF */ + { + if (code != NULL) *code++ = x; + } + + arglen++; + + if ((unsigned int)arglen > MAX_MARK) + { + *errorcodeptr = ERR76; + *ptrptr = ptr; + return -1; + } + } + +/* Update the pointers before returning. */ + +*ptrptr = ptr; +if (codeptr != NULL) *codeptr = code; +return arglen; +} + + + +/************************************************* +* Macro for the next two functions * +*************************************************/ + +/* Both scan_for_captures() and compile_branch() use this macro to generate a +fragment of code that reads the characters of a name and sets its length +(checking for not being too long). Count the characters dynamically, to avoid +the possibility of integer overflow. The same macro is used for reading *VERB +names. */ + +#define READ_NAME(ctype, errno, errset) \ + namelen = 0; \ + while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0) \ + { \ + ptr++; \ + namelen++; \ + if (namelen > MAX_NAME_SIZE) \ + { \ + errset = errno; \ + goto FAILED; \ + } \ + } + + + +/************************************************* +* Scan regex to identify named groups * +*************************************************/ + +/* This function is called first of all, to scan for named capturing groups so +that information about them is fully available to both the compiling scans. +It skips over everything except parenthesized items. + +Arguments: + ptrptr points to pointer to the start of the pattern + options compiling dynamic options + cb pointer to the compile data block + +Returns: zero on success or a non-zero error code, with pointer updated +*/ + +typedef struct nest_save { + uint16_t nest_depth; + uint16_t reset_group; + uint16_t max_group; + uint16_t flags; +} nest_save; + +#define NSF_RESET 0x0001u +#define NSF_EXTENDED 0x0002u +#define NSF_DUPNAMES 0x0004u + +static uint32_t scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options, + compile_block *cb) +{ +uint32_t c; +uint32_t delimiter; +uint32_t nest_depth = 0; +uint32_t set, unset, *optset; +int errorcode = 0; +int escape; +int namelen; +int i; +BOOL inescq = FALSE; +BOOL isdupname; +BOOL skiptoket = FALSE; +BOOL utf = (options & PCRE2_UTF) != 0; +BOOL negate_class; +PCRE2_SPTR name; +PCRE2_SPTR start; +PCRE2_SPTR ptr = *ptrptr; +named_group *ng; +nest_save *top_nest = NULL; +nest_save *end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size); + +/* The size of the nest_save structure might not be a factor of the size of the +workspace. Therefore we must round down end_nests so as to correctly avoid +creating a nest_save that spans the end of the workspace. */ + +end_nests = (nest_save *)((char *)end_nests - + ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save))); + +/* Now scan the pattern */ + +for (; ptr < cb->end_pattern; ptr++) + { + c = *ptr; + + /* Parenthesized groups set skiptoket when all following characters up to the + next closing parenthesis must be ignored. The parenthesis itself must be + processed (to end the nested parenthesized item). */ + + if (skiptoket) + { + if (c != CHAR_RIGHT_PARENTHESIS) continue; + skiptoket = FALSE; + } + + /* Skip over literals */ + + if (inescq) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { + inescq = FALSE; + ptr++; + } + continue; + } + + /* Skip over comments and whitespace in extended mode. Need a loop to handle + whitespace after a comment. */ + + if ((options & PCRE2_EXTENDED) != 0) + { + for (;;) + { + while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c != CHAR_NUMBER_SIGN) break; + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cb->nllen. */ + ptr += cb->nllen; + break; + } + ptr++; +#ifdef SUPPORT_UNICODE + if (utf) FORWARDCHAR(ptr); +#endif + } + c = *ptr; /* Either NULL or the char after a newline */ + } + } + + /* Process the next pattern item. */ + + switch(c) + { + default: /* Most characters are just skipped */ + break; + + /* Skip escapes except for \Q */ + + case CHAR_BACKSLASH: + errorcode = 0; + escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode, options, + FALSE, cb); + if (errorcode != 0) goto FAILED; + if (escape == ESC_Q) inescq = TRUE; + break; + + /* Skip a character class. The syntax is complicated so we have to + replicate some of what happens when a class is processed for real. */ + + case CHAR_LEFT_SQUARE_BRACKET: + if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0 || + PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) + { + ptr += 6; + break; + } + + /* If the first character is '^', set the negation flag (not actually used + here, except to recognize only one ^) and skip it. If the first few + characters (either before or after ^) are \Q\E or \E we skip them too. This + makes for compatibility with Perl. */ + + negate_class = FALSE; + for (;;) + { + c = *(++ptr); /* First character in class */ + if (c == CHAR_BACKSLASH) + { + if (ptr[1] == CHAR_E) + ptr++; + else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 3; + else + break; + } + else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) + negate_class = TRUE; + else break; + } + + if (c == CHAR_RIGHT_SQUARE_BRACKET && + (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) + break; + + /* Loop for the contents of the class */ + + for (;;) + { + PCRE2_SPTR tempptr; + + if (c == CHAR_NULL && ptr >= cb->end_pattern) + { + errorcode = ERR6; /* Missing terminating ']' */ + goto FAILED; + } + +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(c)) + { /* Braces are required because the */ + GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ + } +#endif + + /* Inside \Q...\E everything is literal except \E */ + + if (inescq) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ + { + inescq = FALSE; /* Reset literal state */ + ptr++; /* Skip the 'E' */ + } + goto CONTINUE_CLASS; + } + + /* Skip POSIX class names. */ + if (c == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) + { + ptr = tempptr + 1; + } + else if (c == CHAR_BACKSLASH) + { + errorcode = 0; + escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode, + options, TRUE, cb); + if (errorcode != 0) goto FAILED; + if (escape == ESC_Q) inescq = TRUE; + } + + CONTINUE_CLASS: + c = *(++ptr); + if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; + } /* End of class-processing loop */ + break; + + /* This is the real work of this function - handling parentheses. */ + + case CHAR_LEFT_PARENTHESIS: + nest_depth++; + + if (ptr[1] != CHAR_QUESTION_MARK) + { + if (ptr[1] != CHAR_ASTERISK) + { + if ((options & PCRE2_NO_AUTO_CAPTURE) == 0) cb->bracount++; + } + + /* (*something) - just skip to closing ket unless PCRE2_ALT_VERBNAMES is + set, in which case we have to process escapes in the string after the + name. */ + + else + { + ptr += 2; + while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0) ptr++; + if (*ptr == CHAR_COLON) + { + ptr++; + if ((options & PCRE2_ALT_VERBNAMES) != 0) + { + if (process_verb_name(&ptr, NULL, &errorcode, options, utf, cb) < 0) + goto FAILED; + } + else + { + while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) + ptr++; + } + } + nest_depth--; + } + } + + /* Handle (?...) groups */ + + else switch(ptr[2]) + { + default: + ptr += 2; + if (ptr[0] == CHAR_R || /* (?R) */ + ptr[0] == CHAR_NUMBER_SIGN || /* (?#) */ + IS_DIGIT(ptr[0]) || /* (?n) */ + (ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1]))) /* (?-n) */ + { + skiptoket = TRUE; + break; + } + + /* Handle (?| and (?imsxJU: which are the only other valid forms. Both + need a new block on the nest stack. */ + + if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace); + else if (++top_nest >= end_nests) + { + errorcode = ERR84; + goto FAILED; + } + top_nest->nest_depth = nest_depth; + top_nest->flags = 0; + if ((options & PCRE2_EXTENDED) != 0) top_nest->flags |= NSF_EXTENDED; + if ((options & PCRE2_DUPNAMES) != 0) top_nest->flags |= NSF_DUPNAMES; + + if (*ptr == CHAR_VERTICAL_LINE) + { + top_nest->reset_group = cb->bracount; + top_nest->max_group = cb->bracount; + top_nest->flags |= NSF_RESET; + cb->external_flags |= PCRE2_DUPCAPUSED; + break; + } + + /* Scan options */ + + top_nest->reset_group = 0; + top_nest->max_group = 0; + + set = unset = 0; + optset = &set; + + /* Need only track (?x: and (?J: at this stage */ + + while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) + { + switch (*ptr++) + { + case CHAR_MINUS: optset = &unset; break; + + case CHAR_x: *optset |= PCRE2_EXTENDED; break; + + case CHAR_J: + *optset |= PCRE2_DUPNAMES; + cb->external_flags |= PCRE2_JCHANGED; + break; + + case CHAR_i: + case CHAR_m: + case CHAR_s: + case CHAR_U: + break; + + default: errorcode = ERR11; + ptr--; /* Correct the offset */ + goto FAILED; + } + } + + options = (options | set) & (~unset); + + /* If the options ended with ')' this is not the start of a nested + group with option changes, so the options change at this level. If the + previous level set up a nest block, discard the one we have just created. + Otherwise adjust it for the previous level. */ + + if (*ptr == CHAR_RIGHT_PARENTHESIS) + { + nest_depth--; + if (top_nest > (nest_save *)(cb->start_workspace) && + (top_nest-1)->nest_depth == nest_depth) top_nest --; + else top_nest->nest_depth = nest_depth; + } + break; + + /* Skip over a numerical or string argument for a callout. */ + + case CHAR_C: + ptr += 2; + if (ptr[1] == CHAR_RIGHT_PARENTHESIS) break; + if (IS_DIGIT(ptr[1])) + { + while (IS_DIGIT(ptr[1])) ptr++; + } + + /* Handle a string argument */ + + else + { + ptr++; + delimiter = 0; + for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) + { + if (*ptr == PRIV(callout_start_delims)[i]) + { + delimiter = PRIV(callout_end_delims)[i]; + break; + } + } + + if (delimiter == 0) + { + errorcode = ERR82; + goto FAILED; + } + + start = ptr; + do + { + if (++ptr >= cb->end_pattern) + { + errorcode = ERR81; + ptr = start; /* To give a more useful message */ + goto FAILED; + } + if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; + } + while (ptr[0] != delimiter); + } + + /* Check terminating ) */ + + if (ptr[1] != CHAR_RIGHT_PARENTHESIS) + { + errorcode = ERR39; + ptr++; + goto FAILED; + } + break; + + /* Conditional group */ + + case CHAR_LEFT_PARENTHESIS: + if (ptr[3] != CHAR_QUESTION_MARK) /* Not assertion or callout */ + { + nest_depth++; + ptr += 2; + break; + } + + /* Must be an assertion or a callout */ + + switch(ptr[4]) + { + case CHAR_LESS_THAN_SIGN: + if (ptr[5] != CHAR_EXCLAMATION_MARK && ptr[5] != CHAR_EQUALS_SIGN) + goto MISSING_ASSERTION; + /* Fall through */ + + case CHAR_C: + case CHAR_EXCLAMATION_MARK: + case CHAR_EQUALS_SIGN: + ptr++; + break; + + default: + MISSING_ASSERTION: + ptr += 3; /* To improve error message */ + errorcode = ERR28; + goto FAILED; + } + break; + + case CHAR_COLON: + case CHAR_GREATER_THAN_SIGN: + case CHAR_EQUALS_SIGN: + case CHAR_EXCLAMATION_MARK: + case CHAR_AMPERSAND: + case CHAR_PLUS: + ptr += 2; + break; + + case CHAR_P: + if (ptr[3] != CHAR_LESS_THAN_SIGN) + { + ptr += 3; + break; + } + ptr++; + c = CHAR_GREATER_THAN_SIGN; /* Terminator */ + goto DEFINE_NAME; + + case CHAR_LESS_THAN_SIGN: + if (ptr[3] == CHAR_EQUALS_SIGN || ptr[3] == CHAR_EXCLAMATION_MARK) + { + ptr += 3; + break; + } + c = CHAR_GREATER_THAN_SIGN; /* Terminator */ + goto DEFINE_NAME; + + case CHAR_APOSTROPHE: + c = CHAR_APOSTROPHE; /* Terminator */ + + DEFINE_NAME: + name = ptr = ptr + 3; + + if (*ptr == c) /* Empty name */ + { + errorcode = ERR62; + goto FAILED; + } + + if (IS_DIGIT(*ptr)) + { + errorcode = ERR44; /* Group name must start with non-digit */ + goto FAILED; + } + + if (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) == 0) + { + errorcode = ERR24; + goto FAILED; + } + + /* Advance ptr, set namelen and check its length. */ + READ_NAME(ctype_word, ERR48, errorcode); + + if (*ptr != c) + { + errorcode = ERR42; + goto FAILED; + } + + if (cb->names_found >= MAX_NAME_COUNT) + { + errorcode = ERR49; + goto FAILED; + } + + if (namelen + IMM2_SIZE + 1 > cb->name_entry_size) + cb->name_entry_size = namelen + IMM2_SIZE + 1; + + /* We have a valid name for this capturing group. */ + + cb->bracount++; + + /* Scan the list to check for duplicates. For duplicate names, if the + number is the same, break the loop, which causes the name to be + discarded; otherwise, if DUPNAMES is not set, give an error. + If it is set, allow the name with a different number, but continue + scanning in case this is a duplicate with the same number. For + non-duplicate names, give an error if the number is duplicated. */ + + isdupname = FALSE; + ng = cb->named_groups; + for (i = 0; i < cb->names_found; i++, ng++) + { + if (namelen == ng->length && + PRIV(strncmp)(name, ng->name, namelen) == 0) + { + if (ng->number == cb->bracount) break; + if ((options & PCRE2_DUPNAMES) == 0) + { + errorcode = ERR43; + goto FAILED; + } + isdupname = ng->isdup = TRUE; /* Mark as a duplicate */ + cb->dupnames = TRUE; /* Duplicate names exist */ + } + else if (ng->number == cb->bracount) + { + errorcode = ERR65; + goto FAILED; + } + } + + if (i < cb->names_found) break; /* Ignore duplicate with same number */ + + /* Increase the list size if necessary */ + + if (cb->names_found >= cb->named_group_list_size) + { + int newsize = cb->named_group_list_size * 2; + named_group *newspace = + cb->cx->memctl.malloc(newsize * sizeof(named_group), + cb->cx->memctl.memory_data); + if (newspace == NULL) + { + errorcode = ERR21; + goto FAILED; + } + + memcpy(newspace, cb->named_groups, + cb->named_group_list_size * sizeof(named_group)); + if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE) + cb->cx->memctl.free((void *)cb->named_groups, + cb->cx->memctl.memory_data); + cb->named_groups = newspace; + cb->named_group_list_size = newsize; + } + + /* Add this name to the list */ + + cb->named_groups[cb->names_found].name = name; + cb->named_groups[cb->names_found].length = namelen; + cb->named_groups[cb->names_found].number = cb->bracount; + cb->named_groups[cb->names_found].isdup = isdupname; + cb->names_found++; + break; + } /* End of (? switch */ + break; /* End of ( handling */ + + /* At an alternation, reset the capture count if we are in a (?| group. */ + + case CHAR_VERTICAL_LINE: + if (top_nest != NULL && top_nest->nest_depth == nest_depth && + (top_nest->flags & NSF_RESET) != 0) + { + if (cb->bracount > top_nest->max_group) + top_nest->max_group = cb->bracount; + cb->bracount = top_nest->reset_group; + } + break; + + /* At a right parenthesis, reset the capture count to the maximum if we + are in a (?| group and/or reset the extended option. */ + + case CHAR_RIGHT_PARENTHESIS: + if (top_nest != NULL && top_nest->nest_depth == nest_depth) + { + if ((top_nest->flags & NSF_RESET) != 0 && + top_nest->max_group > cb->bracount) + cb->bracount = top_nest->max_group; + if ((top_nest->flags & NSF_EXTENDED) != 0) options |= PCRE2_EXTENDED; + else options &= ~PCRE2_EXTENDED; + if ((top_nest->flags & NSF_DUPNAMES) != 0) options |= PCRE2_DUPNAMES; + else options &= ~PCRE2_DUPNAMES; + if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; + else top_nest--; + } + if (nest_depth > 0) nest_depth--; /* Can be 0 for unmatched ) */ + break; + } + } + +cb->final_bracount = cb->bracount; +return 0; + +FAILED: +*ptrptr = ptr; +return errorcode; +} + + + +/************************************************* +* Compile one branch * +*************************************************/ + +/* Scan the pattern, compiling it into the a vector. If the options are +changed during the branch, the pointer is used to change the external options +bits. This function is used during the pre-compile phase when we are trying +to find out the amount of memory needed, as well as during the real compile +phase. The value of lengthptr distinguishes the two phases. + +Arguments: + optionsptr pointer to the option bits + codeptr points to the pointer to the current code point + ptrptr points to the current pattern pointer + errorcodeptr points to error code variable + firstcuptr place to put the first required code unit + firstcuflagsptr place to put the first code unit flags, or a negative number + reqcuptr place to put the last required code unit + reqcuflagsptr place to put the last required code unit flags, or a negative number + bcptr points to current branch chain + cond_depth conditional nesting depth + cb contains pointers to tables etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase + +Returns: TRUE on success + FALSE, with *errorcodeptr set non-zero on error +*/ + +static BOOL +compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, + PCRE2_SPTR *ptrptr, int *errorcodeptr, + uint32_t *firstcuptr, int32_t *firstcuflagsptr, + uint32_t *reqcuptr, int32_t *reqcuflagsptr, + branch_chain *bcptr, int cond_depth, + compile_block *cb, size_t *lengthptr) +{ +int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ +int bravalue = 0; +uint32_t greedy_default, greedy_non_default; +uint32_t repeat_type, op_type; +uint32_t options = *optionsptr; /* May change dynamically */ +uint32_t firstcu, reqcu; +int32_t firstcuflags, reqcuflags; +uint32_t zeroreqcu, zerofirstcu; +int32_t zeroreqcuflags, zerofirstcuflags; +int32_t req_caseopt, reqvary, tempreqvary; +int after_manual_callout = 0; +int escape; +size_t length_prevgroup = 0; +register uint32_t c; +register PCRE2_UCHAR *code = *codeptr; +PCRE2_UCHAR *last_code = code; +PCRE2_UCHAR *orig_code = code; +PCRE2_UCHAR *tempcode; +BOOL inescq = FALSE; +BOOL groupsetfirstcu = FALSE; +PCRE2_SPTR ptr = *ptrptr; +PCRE2_SPTR tempptr; +PCRE2_UCHAR *previous = NULL; +PCRE2_UCHAR *previous_callout = NULL; +uint8_t classbits[32]; + +/* We can fish out the UTF setting once and for all into a BOOL, but we must +not do this for other options (e.g. PCRE2_EXTENDED) because they may change +dynamically as we process the pattern. */ + +#ifdef SUPPORT_UNICODE +BOOL utf = (options & PCRE2_UTF) != 0; +#if PCRE2_CODE_UNIT_WIDTH != 32 +PCRE2_UCHAR utf_units[6]; /* For setting up multi-cu chars */ +#endif + +#else /* No UTF support */ +BOOL utf = FALSE; +#endif + +/* Helper variables for OP_XCLASS opcode (for characters > 255). We define +class_uchardata always so that it can be passed to add_to_class() always, +though it will not be used in non-UTF 8-bit cases. This avoids having to supply +alternative calls for the different cases. */ + +PCRE2_UCHAR *class_uchardata; +#ifdef SUPPORT_WIDE_CHARS +BOOL xclass; +PCRE2_UCHAR *class_uchardata_base; +#endif + +/* Set up the default and non-default settings for greediness */ + +greedy_default = ((options & PCRE2_UNGREEDY) != 0); +greedy_non_default = greedy_default ^ 1; + +/* Initialize no first unit, no required unit. REQ_UNSET means "no char +matching encountered yet". It gets changed to REQ_NONE if we hit something that +matches a non-fixed first unit; reqcu just remains unset if we never find one. + +When we hit a repeat whose minimum is zero, we may have to adjust these values +to take the zero repeat into account. This is implemented by setting them to +zerofirstcu and zeroreqcu when such a repeat is encountered. The individual +item types that can be repeated set these backoff variables appropriately. */ + +firstcu = reqcu = zerofirstcu = zeroreqcu = 0; +firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET; + +/* The variable req_caseopt contains either the REQ_CASELESS value or zero, +according to the current setting of the caseless flag. The REQ_CASELESS value +leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables +to record the case status of the value. This is used only for ASCII characters. +*/ + +req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS:0; + +/* Switch on next character until the end of the branch */ + +for (;; ptr++) + { + BOOL negate_class; + BOOL should_flip_negation; + BOOL match_all_or_no_wide_chars; + BOOL possessive_quantifier; + BOOL is_quantifier; + BOOL is_recurse; + BOOL is_dupname; + BOOL reset_bracount; + int class_has_8bitchar; + int class_one_char; +#ifdef SUPPORT_WIDE_CHARS + BOOL xclass_has_prop; +#endif + int recno; /* Must be signed */ + int refsign; /* Must be signed */ + int terminator; /* Must be signed */ + unsigned int mclength; + unsigned int tempbracount; + uint32_t ec; + uint32_t newoptions; + uint32_t skipunits; + uint32_t subreqcu, subfirstcu; + int32_t subreqcuflags, subfirstcuflags; /* Must be signed */ + PCRE2_UCHAR mcbuffer[8]; + + /* Get next character in the pattern */ + + c = *ptr; + + /* If we are at the end of a nested substitution, revert to the outer level + string. Nesting only happens one or two levels deep, and the inserted string + is always zero terminated. */ + + if (c == CHAR_NULL && cb->nestptr[0] != NULL) + { + ptr = cb->nestptr[0]; + cb->nestptr[0] = cb->nestptr[1]; + cb->nestptr[1] = NULL; + c = *ptr; + } + + /* If we are in the pre-compile phase, accumulate the length used for the + previous cycle of this loop. */ + + if (lengthptr != NULL) + { + if (code > cb->start_workspace + cb->workspace_size - + WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ + { + *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)? + ERR52 : ERR86; + goto FAILED; + } + + /* There is at least one situation where code goes backwards: this is the + case of a zero quantifier after a class (e.g. [ab]{0}). At compile time, + the class is simply eliminated. However, it is created first, so we have to + allow memory for it. Therefore, don't ever reduce the length at this point. + */ + + if (code < last_code) code = last_code; + + /* Paranoid check for integer overflow */ + + if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code)) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += code - last_code; + + /* If "previous" is set and it is not at the start of the work space, move + it back to there, in order to avoid filling up the work space. Otherwise, + if "previous" is NULL, reset the current code pointer to the start. */ + + if (previous != NULL) + { + if (previous > orig_code) + { + memmove(orig_code, previous, CU2BYTES(code - previous)); + code -= previous - orig_code; + previous = orig_code; + } + } + else code = orig_code; + + /* Remember where this code item starts so we can pick up the length + next time round. */ + + last_code = code; + } + + /* Before doing anything else we must handle all the special items that do + nothing, and which may come between an item and its quantifier. Otherwise, + when auto-callouts are enabled, a callout gets incorrectly inserted before + the quantifier is recognized. After recognizing a "do nothing" item, restart + the loop in case another one follows. */ + + /* If c is not NULL we are not at the end of the pattern. If it is NULL, we + may still be in the pattern with a NULL data item. In these cases, if we are + in \Q...\E, check for the \E that ends the literal string; if not, we have a + literal character. If not in \Q...\E, an isolated \E is ignored. */ + + if (c != CHAR_NULL || ptr < cb->end_pattern) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { + inescq = FALSE; + ptr++; + continue; + } + else if (inescq) /* Literal character */ + { + if (previous_callout != NULL) + { + if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ + complete_callout(previous_callout, ptr, cb); + previous_callout = NULL; + } + if ((options & PCRE2_AUTO_CALLOUT) != 0) + { + previous_callout = code; + code = auto_callout(code, ptr, cb); + } + goto NORMAL_CHAR; + } + + /* Check for the start of a \Q...\E sequence. We must do this here rather + than later in case it is immediately followed by \E, which turns it into a + "do nothing" sequence. */ + + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_Q) + { + inescq = TRUE; + ptr++; + continue; + } + } + + /* In extended mode, skip white space and #-comments that end at newline. */ + + if ((options & PCRE2_EXTENDED) != 0) + { + PCRE2_SPTR wscptr = ptr; + while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c == CHAR_NUMBER_SIGN) + { + ptr++; + while (ptr < cb->end_pattern) + { + if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cb->nllen. */ + ptr += cb->nllen; + break; + } + ptr++; +#ifdef SUPPORT_UNICODE + if (utf) FORWARDCHAR(ptr); +#endif + } + } + + /* If we skipped any characters, restart the loop. Otherwise, we didn't see + a comment. */ + + if (ptr > wscptr) + { + ptr--; + continue; + } + } + + /* Skip over (?# comments. */ + + if (c == CHAR_LEFT_PARENTHESIS && ptr[1] == CHAR_QUESTION_MARK && + ptr[2] == CHAR_NUMBER_SIGN) + { + ptr += 3; + while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR18; + goto FAILED; + } + continue; + } + + /* End of processing "do nothing" items. See if the next thing is a + quantifier. */ + + is_quantifier = + c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK || + (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1)); + + /* Fill in length of a previous callout and create an auto callout if + required, except when the next thing is a quantifier or when processing a + property substitution string for \w etc in UCP mode. */ + + if (!is_quantifier && cb->nestptr[0] == NULL) + { + if (previous_callout != NULL && after_manual_callout-- <= 0) + { + if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ + complete_callout(previous_callout, ptr, cb); + previous_callout = NULL; + } + + if ((options & PCRE2_AUTO_CALLOUT) != 0) + { + previous_callout = code; + code = auto_callout(code, ptr, cb); + } + } + + /* Process the next pattern item. */ + + switch(c) + { + /* ===================================================================*/ + /* The branch terminates at string end or | or ) */ + + case CHAR_NULL: + if (ptr < cb->end_pattern) goto NORMAL_CHAR; /* Zero data character */ + /* Fall through */ + + case CHAR_VERTICAL_LINE: + case CHAR_RIGHT_PARENTHESIS: + *firstcuptr = firstcu; + *firstcuflagsptr = firstcuflags; + *reqcuptr = reqcu; + *reqcuflagsptr = reqcuflags; + *codeptr = code; + *ptrptr = ptr; + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code)) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += code - last_code; /* To include callout length */ + } + return TRUE; + + + /* ===================================================================*/ + /* Handle single-character metacharacters. In multiline mode, ^ disables + the setting of any following char as a first character. */ + + case CHAR_CIRCUMFLEX_ACCENT: + previous = NULL; + if ((options & PCRE2_MULTILINE) != 0) + { + if (firstcuflags == REQ_UNSET) + zerofirstcuflags = firstcuflags = REQ_NONE; + *code++ = OP_CIRCM; + } + else *code++ = OP_CIRC; + break; + + case CHAR_DOLLAR_SIGN: + previous = NULL; + *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL; + break; + + /* There can never be a first char if '.' is first, whatever happens about + repeats. The value of reqcu doesn't change either. */ + + case CHAR_DOT: + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + previous = code; + *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY; + break; + + + /* ===================================================================*/ + /* Character classes. If the included characters are all < 256, we build a + 32-byte bitmap of the permitted characters, except in the special case + where there is only one such character. For negated classes, we build the + map as usual, then invert it at the end. However, we use a different opcode + so that data characters > 255 can be handled correctly. + + If the class contains characters outside the 0-255 range, a different + opcode is compiled. It may optionally have a bit map for characters < 256, + but those above are are explicitly listed afterwards. A flag byte tells + whether the bitmap is present, and whether this is a negated class or not. + + An isolated ']' character is not treated specially, so is just another data + character. In earlier versions of PCRE that used the original API there was + a "JavaScript compatibility mode" in which it gave an error. However, + JavaScript itself has changed in this respect so there is no longer any + need for this special handling. + + In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is + used for "start of word" and "end of word". As these are otherwise illegal + sequences, we don't break anything by recognizing them. They are replaced + by \b(?=\w) and \b(?<=\w) respectively. This can only happen at the top + nesting level, as no other inserted sequences will contains these oddities. + Sequences like [a[:<:]] are erroneous and are handled by the normal code + below. */ + + case CHAR_LEFT_SQUARE_BRACKET: + if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0) + { + cb->nestptr[0] = ptr + 7; + ptr = sub_start_of_word; /* Do not combine these statements; clang's */ + ptr--; /* sanitizer moans about a negative index. */ + continue; + } + + if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) + { + cb->nestptr[0] = ptr + 7; + ptr = sub_end_of_word; /* Do not combine these statements; clang's */ + ptr--; /* sanitizer moans about a negative index. */ + continue; + } + + /* Handle a real character class. */ + + previous = code; + + /* PCRE supports POSIX class stuff inside a class. Perl gives an error if + they are encountered at the top level, so we'll do that too. */ + + if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, &tempptr)) + { + *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR12 : ERR13; + goto FAILED; + } + + /* If the first character is '^', set the negation flag and skip it. Also, + if the first few characters (either before or after ^) are \Q\E or \E we + skip them too. This makes for compatibility with Perl. */ + + negate_class = FALSE; + for (;;) + { + c = *(++ptr); + if (c == CHAR_BACKSLASH) + { + if (ptr[1] == CHAR_E) + ptr++; + else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 3; + else + break; + } + else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) + negate_class = TRUE; + else break; + } + + /* Empty classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set. Otherwise, + an initial ']' is taken as a data character -- the code below handles + that. When empty classes are allowed, [] must always fail, so generate + OP_FAIL, whereas [^] must match any character, so generate OP_ALLANY. */ + + if (c == CHAR_RIGHT_SQUARE_BRACKET && + (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) + { + *code++ = negate_class? OP_ALLANY : OP_FAIL; + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + break; + } + + /* If a non-extended class contains a negative special such as \S, we need + to flip the negation flag at the end, so that support for characters > 255 + works correctly (they are all included in the class). An extended class may + need to insert specific matching or non-matching code for wide characters. + */ + + should_flip_negation = match_all_or_no_wide_chars = FALSE; + + /* Extended class (xclass) will be used when characters > 255 + might match. */ + +#ifdef SUPPORT_WIDE_CHARS + xclass = FALSE; + class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ + class_uchardata_base = class_uchardata; /* Save the start */ +#endif + + /* For optimization purposes, we track some properties of the class: + class_has_8bitchar will be non-zero if the class contains at least one 256 + character with a code point less than 256; class_one_char will be 1 if the + class contains just one character; xclass_has_prop will be TRUE if Unicode + property checks are present in the class. */ + + class_has_8bitchar = 0; + class_one_char = 0; +#ifdef SUPPORT_WIDE_CHARS + xclass_has_prop = FALSE; +#endif + + /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map + in a temporary bit of memory, in case the class contains fewer than two + 8-bit characters because in that case the compiled code doesn't use the bit + map. */ + + memset(classbits, 0, 32 * sizeof(uint8_t)); + + /* Process characters until ] is reached. As the test is at the end of the + loop, an initial ] is taken as a data character. At the start of the loop, + c contains the first code unit of the character. If it is zero, check for + the end of the pattern, to allow binary zero as data. */ + + for(;;) + { + PCRE2_SPTR oldptr; +#ifdef EBCDIC + BOOL range_is_literal = TRUE; +#endif + + if (c == CHAR_NULL && ptr >= cb->end_pattern) + { + *errorcodeptr = ERR6; /* Missing terminating ']' */ + goto FAILED; + } + +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(c)) + { /* Braces are required because the */ + GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ + } +#endif + + /* Inside \Q...\E everything is literal except \E */ + + if (inescq) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ + { + inescq = FALSE; /* Reset literal state */ + ptr++; /* Skip the 'E' */ + goto CONTINUE_CLASS; /* Carry on with next char */ + } + goto CHECK_RANGE; /* Could be range if \E follows */ + } + + /* Handle POSIX class names. Perl allows a negation extension of the + form [:^name:]. A square bracket that doesn't match the syntax is + treated as a literal. We also recognize the POSIX constructions + [.ch.] and [=ch=] ("collating elements") and fault them, as Perl + 5.6 and 5.8 do. */ + + if (c == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) + { + BOOL local_negate = FALSE; + int posix_class, taboffset, tabopt; + register const uint8_t *cbits = cb->cbits; + uint8_t pbits[32]; + + if (ptr[1] != CHAR_COLON) + { + *errorcodeptr = ERR13; + goto FAILED; + } + + ptr += 2; + if (*ptr == CHAR_CIRCUMFLEX_ACCENT) + { + local_negate = TRUE; + should_flip_negation = TRUE; /* Note negative special */ + ptr++; + } + + posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); + if (posix_class < 0) + { + *errorcodeptr = ERR30; + goto FAILED; + } + + /* If matching is caseless, upper and lower are converted to + alpha. This relies on the fact that the class table starts with + alpha, lower, upper as the first 3 entries. */ + + if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) + posix_class = 0; + + /* When PCRE2_UCP is set, some of the POSIX classes are converted to + different escape sequences that use Unicode properties \p or \P. Others + that are not available via \p or \P generate XCL_PROP/XCL_NOTPROP + directly. UCP support is not available unless UTF support is.*/ + +#ifdef SUPPORT_UNICODE + if ((options & PCRE2_UCP) != 0) + { + unsigned int ptype = 0; + int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0); + + /* The posix_substitutes table specifies which POSIX classes can be + converted to \p or \P items. This can only happen at top nestling + level, as there will never be a POSIX class in a string that is + substituted for something else. */ + + if (posix_substitutes[pc] != NULL) + { + cb->nestptr[0] = tempptr + 1; + ptr = posix_substitutes[pc] - 1; + goto CONTINUE_CLASS; + } + + /* There are three other classes that generate special property calls + that are recognized only in an XCLASS. */ + + else switch(posix_class) + { + case PC_GRAPH: + ptype = PT_PXGRAPH; + /* Fall through */ + case PC_PRINT: + if (ptype == 0) ptype = PT_PXPRINT; + /* Fall through */ + case PC_PUNCT: + if (ptype == 0) ptype = PT_PXPUNCT; + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = ptype; + *class_uchardata++ = 0; + xclass_has_prop = TRUE; + ptr = tempptr + 1; + goto CONTINUE_CLASS; + + /* For the other POSIX classes (ascii, xdigit) we are going to fall + through to the non-UCP case and build a bit map for characters with + code points less than 256. However, if we are in a negated POSIX + class, characters with code points greater than 255 must either all + match or all not match, depending on whether the whole class is not + or is negated. For example, for [[:^ascii:]... they must all match, + whereas for [^[:^xdigit:]... they must not. + + In the special case where there are no xclass items, this is + automatically handled by the use of OP_CLASS or OP_NCLASS, but an + explicit range is needed for OP_XCLASS. Setting a flag here causes + the range to be generated later when it is known that OP_XCLASS is + required. */ + + default: + match_all_or_no_wide_chars |= local_negate; + break; + } + } +#endif /* SUPPORT_UNICODE */ + + /* In the non-UCP case, or when UCP makes no difference, we build the + bit map for the POSIX class in a chunk of local store because we may be + adding and subtracting from it, and we don't want to subtract bits that + may be in the main map already. At the end we or the result into the + bit map that is being built. */ + + posix_class *= 3; + + /* Copy in the first table (always present) */ + + memcpy(pbits, cbits + posix_class_maps[posix_class], + 32 * sizeof(uint8_t)); + + /* If there is a second table, add or remove it as required. */ + + taboffset = posix_class_maps[posix_class + 1]; + tabopt = posix_class_maps[posix_class + 2]; + + if (taboffset >= 0) + { + if (tabopt >= 0) + for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; + else + for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; + } + + /* Now see if we need to remove any special characters. An option + value of 1 removes vertical space and 2 removes underscore. */ + + if (tabopt < 0) tabopt = -tabopt; + if (tabopt == 1) pbits[1] &= ~0x3c; + else if (tabopt == 2) pbits[11] &= 0x7f; + + /* Add the POSIX table or its complement into the main table that is + being built and we are done. */ + + if (local_negate) + for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c]; + else + for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; + + ptr = tempptr + 1; + /* Every class contains at least one < 256 character. */ + class_has_8bitchar = 1; + /* Every class contains at least two characters. */ + class_one_char = 2; + goto CONTINUE_CLASS; /* End of POSIX syntax handling */ + } + + /* Backslash may introduce a single character, or it may introduce one + of the specials, which just set a flag. The sequence \b is a special + case. Inside a class (and only there) it is treated as backspace. We + assume that other escapes have more than one character in them, so + speculatively set both class_has_8bitchar and class_one_char bigger + than one. Unrecognized escapes fall through and are faulted. */ + + if (c == CHAR_BACKSLASH) + { + escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr, + options, TRUE, cb); + if (*errorcodeptr != 0) goto FAILED; + if (escape == 0) /* Escaped single char */ + { + c = ec; +#ifdef EBCDIC + range_is_literal = FALSE; +#endif + } + else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ + else if (escape == ESC_N) /* \N is not supported in a class */ + { + *errorcodeptr = ERR71; + goto FAILED; + } + else if (escape == ESC_Q) /* Handle start of quoted string */ + { + if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) + { + ptr += 2; /* avoid empty string */ + } + else inescq = TRUE; + goto CONTINUE_CLASS; + } + else if (escape == ESC_E) goto CONTINUE_CLASS; /* Ignore orphan \E */ + + else /* Handle \d-type escapes */ + { + register const uint8_t *cbits = cb->cbits; + /* Every class contains at least two < 256 characters. */ + class_has_8bitchar++; + /* Every class contains at least two characters. */ + class_one_char += 2; + + switch (escape) + { +#ifdef SUPPORT_UNICODE + case ESC_du: /* These are the values given for \d etc */ + case ESC_DU: /* when PCRE2_UCP is set. We replace the */ + case ESC_wu: /* escape sequence with an appropriate \p */ + case ESC_WU: /* or \P to test Unicode properties instead */ + case ESC_su: /* of the default ASCII testing. This might be */ + case ESC_SU: /* a 2nd-level nesting for [[:<:]] or [[:>:]]. */ + cb->nestptr[1] = cb->nestptr[0]; + cb->nestptr[0] = ptr; + ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + class_has_8bitchar--; /* Undo! */ + break; +#endif + case ESC_d: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; + break; + + case ESC_D: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; + break; + + case ESC_w: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; + break; + + case ESC_W: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; + break; + + /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl + 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was + previously set by something earlier in the character class. + Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so + we could just adjust the appropriate bit. From PCRE 8.34 we no + longer treat \s and \S specially. */ + + case ESC_s: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; + break; + + case ESC_S: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; + break; + + /* The rest apply in both UCP and non-UCP cases. */ + + case ESC_h: + (void)add_list_to_class(classbits, &class_uchardata, options, cb, + PRIV(hspace_list), NOTACHAR); + break; + + case ESC_H: + (void)add_not_list_to_class(classbits, &class_uchardata, options, + cb, PRIV(hspace_list)); + break; + + case ESC_v: + (void)add_list_to_class(classbits, &class_uchardata, options, cb, + PRIV(vspace_list), NOTACHAR); + break; + + case ESC_V: + (void)add_not_list_to_class(classbits, &class_uchardata, options, + cb, PRIV(vspace_list)); + break; + + case ESC_p: + case ESC_P: +#ifdef SUPPORT_UNICODE + { + BOOL negated; + unsigned int ptype = 0, pdata = 0; + if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb)) + goto FAILED; + *class_uchardata++ = ((escape == ESC_p) != negated)? + XCL_PROP : XCL_NOTPROP; + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + xclass_has_prop = TRUE; + class_has_8bitchar--; /* Undo! */ + } + break; +#else + *errorcodeptr = ERR45; + goto FAILED; +#endif + /* Unrecognized escapes are faulted. */ + + default: + *errorcodeptr = ERR7; + goto FAILED; + } + + /* Handled \d-type escape */ + + goto CONTINUE_CLASS; + } + + /* Control gets here if the escape just defined a single character. + This is in c and may be greater than 256. */ + + escape = 0; + } /* End of backslash handling */ + + /* A character may be followed by '-' to form a range. However, Perl does + not permit ']' to be the end of the range. A '-' character at the end is + treated as a literal. Perl ignores orphaned \E sequences entirely. The + code for handling \Q and \E is messy. */ + + CHECK_RANGE: + while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) + { + inescq = FALSE; + ptr += 2; + } + oldptr = ptr; + + /* Remember if \r or \n were explicitly used */ + + if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + + /* Check for range */ + + if (!inescq && ptr[1] == CHAR_MINUS) + { + uint32_t d; + ptr += 2; + while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2; + + /* If we hit \Q (not followed by \E) at this point, go into escaped + mode. */ + + while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q) + { + ptr += 2; + if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { ptr += 2; continue; } + inescq = TRUE; + break; + } + + /* Minus (hyphen) at the end of a class is treated as a literal, so put + back the pointer and jump to handle the character that preceded it. */ + + if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) + { + ptr = oldptr; + goto CLASS_SINGLE_CHARACTER; + } + + /* Otherwise, we have a potential range; pick up the next character */ + +#ifdef SUPPORT_UNICODE + if (utf) + { /* Braces are required because the */ + GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ + } + else +#endif + d = *ptr; /* Not UTF mode */ + + /* The second part of a range can be a single-character escape + sequence, but not any of the other escapes. Perl treats a hyphen as a + literal in such circumstances. However, in Perl's warning mode, a + warning is given, so PCRE now faults it as it is almost certainly a + mistake on the user's part. */ + + if (!inescq) + { + if (d == CHAR_BACKSLASH) + { + int descape; + descape = PRIV(check_escape)(&ptr, cb->end_pattern, &d, + errorcodeptr, options, TRUE, cb); + if (*errorcodeptr != 0) goto FAILED; +#ifdef EBCDIC + range_is_literal = FALSE; +#endif + /* 0 means a character was put into d; \b is backspace; any other + special causes an error. */ + + if (descape != 0) + { + if (descape == ESC_b) d = CHAR_BS; else + { + *errorcodeptr = ERR50; + goto FAILED; + } + } + } + + /* A hyphen followed by a POSIX class is treated in the same way. */ + + else if (d == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, &tempptr)) + { + *errorcodeptr = ERR50; + goto FAILED; + } + } + + /* Check that the two values are in the correct order. Optimize + one-character ranges. */ + + if (d < c) + { + *errorcodeptr = ERR8; + goto FAILED; + } + if (d == c) goto CLASS_SINGLE_CHARACTER; /* A few lines below */ + + /* We have found a character range, so single character optimizations + cannot be done anymore. Any value greater than 1 indicates that there + is more than one character. */ + + class_one_char = 2; + + /* Remember an explicit \r or \n, and add the range to the class. */ + + if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + + /* In an EBCDIC environment, Perl treats alphabetic ranges specially + because there are holes in the encoding, and simply using the range A-Z + (for example) would include the characters in the holes. This applies + only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ + +#ifdef EBCDIC + if (range_is_literal && + (cb->ctypes[c] & ctype_letter) != 0 && + (cb->ctypes[d] & ctype_letter) != 0 && + (c <= CHAR_z) == (d <= CHAR_z)) + { + uint32_t uc = (c <= CHAR_z)? 0 : 64; + uint32_t C = c - uc; + uint32_t D = d - uc; + + if (C <= CHAR_i) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cb, C + uc, + ((D < CHAR_i)? D : CHAR_i) + uc); + C = CHAR_j; + } + + if (C <= D && C <= CHAR_r) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cb, C + uc, + ((D < CHAR_r)? D : CHAR_r) + uc); + C = CHAR_s; + } + + if (C <= D) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cb, C + uc, + D + uc); + } + } + else +#endif + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cb, c, d); + goto CONTINUE_CLASS; /* Go get the next char in the class */ + } + + /* Handle a single character - we can get here for a normal non-escape + char, or after \ that introduces a single character or for an apparent + range that isn't. Only the value 1 matters for class_one_char, so don't + increase it if it is already 2 or more ... just in case there's a class + with a zillion characters in it. */ + + CLASS_SINGLE_CHARACTER: + if (class_one_char < 2) class_one_char++; + + /* If class_one_char is 1 and xclass_has_prop is false, we have the first + single character in the class, and there have been no prior ranges, or + XCLASS items generated by escapes. If this is the final character in the + class, we can optimize by turning the item into a 1-character OP_CHAR[I] + if it's positive, or OP_NOT[I] if it's negative. In the positive case, it + can cause firstcu to be set. Otherwise, there can be no first char if + this item is first, whatever repeat count may follow. In the case of + reqcu, save the previous value for reinstating. */ + + if (!inescq && +#ifdef SUPPORT_UNICODE + !xclass_has_prop && +#endif + class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + { + ptr++; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + + if (negate_class) + { +#ifdef SUPPORT_UNICODE + int d; +#endif + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + + /* For caseless UTF mode, check whether this character has more than + one other case. If so, generate a special OP_NOTPROP item instead of + OP_NOTI. */ + +#ifdef SUPPORT_UNICODE + if (utf && (options & PCRE2_CASELESS) != 0 && + (d = UCD_CASESET(c)) != 0) + { + *code++ = OP_NOTPROP; + *code++ = PT_CLIST; + *code++ = d; + } + else +#endif + /* Char has only one other case, or UCP not available */ + + { + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; + code += PUTCHAR(c, code); + } + + /* We are finished with this character class */ + + goto END_CLASS; + } + + /* For a single, positive character, get the value into mcbuffer, and + then we can handle this with the normal one-character code. */ + mclength = PUTCHAR(c, mcbuffer); + goto ONE_CHAR; + } /* End of 1-char optimization */ + + /* There is more than one character in the class, or an XCLASS item + has been generated. Add this character to the class. */ + + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cb, c, c); + + /* Continue to the next character in the class. Closing square bracket + not within \Q..\E ends the class. A NULL character terminates a + nested substitution string, but may be a data character in the main + pattern (tested at the start of this loop). */ + + CONTINUE_CLASS: + c = *(++ptr); + if (c == CHAR_NULL && cb->nestptr[0] != NULL) + { + ptr = cb->nestptr[0]; + cb->nestptr[0] = cb->nestptr[1]; + cb->nestptr[1] = NULL; + c = *(++ptr); + } + +#ifdef SUPPORT_WIDE_CHARS + /* If any wide characters have been encountered, set xclass = TRUE. Then, + in the pre-compile phase, accumulate the length of the wide characters + and reset the pointer. This is so that very large classes that contain a + zillion wide characters do not overwrite the work space (which is on the + stack). */ + + if (class_uchardata > class_uchardata_base) + { + xclass = TRUE; + if (lengthptr != NULL) + { + *lengthptr += class_uchardata - class_uchardata_base; + class_uchardata = class_uchardata_base; + } + } +#endif + /* An unescaped ] ends the class */ + + if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; + } /* End of main class-processing loop */ + + /* If this is the first thing in the branch, there can be no first char + setting, whatever the repeat count. Any reqcu setting must remain + unchanged after any kind of repeat. */ + + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + + /* If there are characters with values > 255, or Unicode property settings + (\p or \P), we have to compile an extended class, with its own opcode, + unless there were no property settings and there was a negated special such + as \S in the class, and PCRE2_UCP is not set, because in that case all + characters > 255 are in or not in the class, so any that were explicitly + given as well can be ignored. + + In the UCP case, if certain negated POSIX classes ([:^ascii:] or + [^:xdigit:]) were present in a class, we either have to match or not match + all wide characters (depending on whether the whole class is or is not + negated). This requirement is indicated by match_all_or_no_wide_chars being + true. We do this by including an explicit range, which works in both cases. + + If, when generating an xclass, there are no characters < 256, we can omit + the bitmap in the actual compiled code. */ + +#ifdef SUPPORT_WIDE_CHARS +#ifdef SUPPORT_UNICODE + if (xclass && (xclass_has_prop || !should_flip_negation || + (options & PCRE2_UCP) != 0)) +#elif PCRE2_CODE_UNIT_WIDTH != 8 + if (xclass && (xclass_has_prop || !should_flip_negation)) +#endif + { + if (match_all_or_no_wide_chars) + { + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x100, class_uchardata); + class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata); + } + *class_uchardata++ = XCL_END; /* Marks the end of extra data */ + *code++ = OP_XCLASS; + code += LINK_SIZE; + *code = negate_class? XCL_NOT:0; + if (xclass_has_prop) *code |= XCL_HASPROP; + + /* If the map is required, move up the extra data to make room for it; + otherwise just move the code pointer to the end of the extra data. */ + + if (class_has_8bitchar > 0) + { + *code++ |= XCL_MAP; + memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, + CU2BYTES(class_uchardata - code)); + if (negate_class && !xclass_has_prop) + for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; + memcpy(code, classbits, 32); + code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); + } + else code = class_uchardata; + + /* Now fill in the complete length of the item */ + + PUT(previous, 1, (int)(code - previous)); + break; /* End of class handling */ + } +#endif + + /* If there are no characters > 255, or they are all to be included or + excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the + whole class was negated and whether there were negative specials such as \S + (non-UCP) in the class. Then copy the 32-byte map into the code vector, + negating it if necessary. */ + + *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; + if (lengthptr == NULL) /* Save time in the pre-compile phase */ + { + if (negate_class) + for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; + memcpy(code, classbits, 32); + } + code += 32 / sizeof(PCRE2_UCHAR); + + END_CLASS: + break; + + + /* ===================================================================*/ + /* Various kinds of repeat; '{' is not necessarily a quantifier, but this + has been tested above. */ + + case CHAR_LEFT_CURLY_BRACKET: + if (!is_quantifier) goto NORMAL_CHAR; + ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr); + if (*errorcodeptr != 0) goto FAILED; + goto REPEAT; + + case CHAR_ASTERISK: + repeat_min = 0; + repeat_max = -1; + goto REPEAT; + + case CHAR_PLUS: + repeat_min = 1; + repeat_max = -1; + goto REPEAT; + + case CHAR_QUESTION_MARK: + repeat_min = 0; + repeat_max = 1; + + REPEAT: + if (previous == NULL) + { + *errorcodeptr = ERR9; + goto FAILED; + } + + if (repeat_min == 0) + { + firstcu = zerofirstcu; /* Adjust for zero repeat */ + firstcuflags = zerofirstcuflags; + reqcu = zeroreqcu; /* Ditto */ + reqcuflags = zeroreqcuflags; + } + + /* Remember whether this is a variable length repeat */ + + reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; + + op_type = 0; /* Default single-char op codes */ + possessive_quantifier = FALSE; /* Default not possessive quantifier */ + + /* Save start of previous item, in case we have to move it up in order to + insert something before it. */ + + tempcode = previous; + + /* Before checking for a possessive quantifier, we must skip over + whitespace and comments in extended mode because Perl allows white space at + this point. */ + + if ((options & PCRE2_EXTENDED) != 0) + { + ptr++; + for (;;) + { + while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_space) != 0) ptr++; + if (*ptr != CHAR_NUMBER_SIGN) break; + ptr++; + while (ptr < cb->end_pattern) + { + if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cb->nllen. */ + ptr += cb->nllen; + break; + } + ptr++; +#ifdef SUPPORT_UNICODE + if (utf) FORWARDCHAR(ptr); +#endif + } /* Loop for comment characters */ + } /* Loop for multiple comments */ + ptr--; /* Last code unit of previous character. */ + } + + /* If the next character is '+', we have a possessive quantifier. This + implies greediness, whatever the setting of the PCRE2_UNGREEDY option. + If the next character is '?' this is a minimizing repeat, by default, + but if PCRE2_UNGREEDY is set, it works the other way round. We change the + repeat type to the non-default. */ + + if (ptr[1] == CHAR_PLUS) + { + repeat_type = 0; /* Force greedy */ + possessive_quantifier = TRUE; + ptr++; + } + else if (ptr[1] == CHAR_QUESTION_MARK) + { + repeat_type = greedy_non_default; + ptr++; + } + else repeat_type = greedy_default; + + /* If the repeat is {1} we can ignore it. */ + + if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; + + /* If previous was a recursion call, wrap it in atomic brackets so that + previous becomes the atomic group. All recursions were so wrapped in the + past, but it no longer happens for non-repeated recursions. In fact, the + repeated ones could be re-implemented independently so as not to need this, + but for the moment we rely on the code for repeating groups. */ + + if (*previous == OP_RECURSE) + { + memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE)); + *previous = OP_ONCE; + PUT(previous, 1, 2 + 2*LINK_SIZE); + previous[2 + 2*LINK_SIZE] = OP_KET; + PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); + code += 2 + 2 * LINK_SIZE; + length_prevgroup = 3 + 3*LINK_SIZE; + } + + /* Now handle repetition for the different types of item. */ + + /* If previous was a character or negated character match, abolish the item + and generate a repeat item instead. If a char item has a minimum of more + than one, ensure that it is set in reqcu - it might not be if a sequence + such as x{3} is the first thing in a branch because the x will have gone + into firstcu instead. */ + + if (*previous == OP_CHAR || *previous == OP_CHARI + || *previous == OP_NOT || *previous == OP_NOTI) + { + switch (*previous) + { + default: /* Make compiler happy. */ + case OP_CHAR: op_type = OP_STAR - OP_STAR; break; + case OP_CHARI: op_type = OP_STARI - OP_STAR; break; + case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break; + case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break; + } + + /* Deal with UTF characters that take up more than one code unit. It's + easier to write this out separately than try to macrify it. Use c to + hold the length of the character in code units, plus UTF_LENGTH to flag + that it's a length rather than a small character. */ + +#ifdef MAYBE_UTF_MULTI + if (utf && NOT_FIRSTCU(code[-1])) + { + PCRE2_UCHAR *lastchar = code - 1; + BACKCHAR(lastchar); + c = (int)(code - lastchar); /* Length of UTF character */ + memcpy(utf_units, lastchar, CU2BYTES(c)); /* Save the char */ + c |= UTF_LENGTH; /* Flag c as a length */ + } + else +#endif /* MAYBE_UTF_MULTI */ + + /* Handle the case of a single charater - either with no UTF support, or + with UTF disabled, or for a single-code-unit UTF character. */ + { + c = code[-1]; + if (*previous <= OP_CHARI && repeat_min > 1) + { + reqcu = c; + reqcuflags = req_caseopt | cb->req_varyopt; + } + } + + goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ + } + + /* If previous was a character type match (\d or similar), abolish it and + create a suitable repeat item. The code is shared with single-character + repeats by setting op_type to add a suitable offset into repeat_type. Note + the the Unicode property types will be present only when SUPPORT_UNICODE is + defined, but we don't wrap the little bits of code here because it just + makes it horribly messy. */ + + else if (*previous < OP_EODN) + { + PCRE2_UCHAR *oldcode; + int prop_type, prop_value; + op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ + c = *previous; /* Save previous opcode */ + if (c == OP_PROP || c == OP_NOTPROP) + { + prop_type = previous[1]; + prop_value = previous[2]; + } + else + { + /* Come here from just above with a character in c */ + OUTPUT_SINGLE_REPEAT: + prop_type = prop_value = -1; + } + + /* At this point we either have prop_type == prop_value == -1 and either + a code point or a character type that is not OP_[NOT]PROP in c, or we + have OP_[NOT]PROP in c and prop_type/prop_value not negative. */ + + oldcode = code; /* Save where we were */ + code = previous; /* Usually overwrite previous item */ + + /* If the maximum is zero then the minimum must also be zero; Perl allows + this case, so we do too - by simply omitting the item altogether. */ + + if (repeat_max == 0) goto END_REPEAT; + + /* Combine the op_type with the repeat_type */ + + repeat_type += op_type; + + /* A minimum of zero is handled either as the special case * or ?, or as + an UPTO, with the maximum given. */ + + if (repeat_min == 0) + { + if (repeat_max == -1) *code++ = OP_STAR + repeat_type; + else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; + else + { + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + + /* A repeat minimum of 1 is optimized into some special cases. If the + maximum is unlimited, we use OP_PLUS. Otherwise, the original item is + left in place and, if the maximum is greater than 1, we use OP_UPTO with + one less than the maximum. */ + + else if (repeat_min == 1) + { + if (repeat_max == -1) + *code++ = OP_PLUS + repeat_type; + else + { + code = oldcode; /* Leave previous item in place */ + if (repeat_max == 1) goto END_REPEAT; + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max - 1); + } + } + + /* The case {n,n} is just an EXACT, while the general case {n,m} is + handled as an EXACT followed by an UPTO or STAR or QUERY. */ + + else + { + *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ + PUT2INC(code, 0, repeat_min); + + /* Unless repeat_max equals repeat_min, fill in the data for EXACT, and + then generate the second opcode. In UTF mode, multi-code-unit + characters have their length in c, with the UTF_LENGTH bit as a flag, + and the code units in utf_units. For a repeated Unicode property match, + there are two extra values that define the required property, and c + never has the UTF_LENGTH bit set. */ + + if (repeat_max != repeat_min) + { +#ifdef MAYBE_UTF_MULTI + if (utf && (c & UTF_LENGTH) != 0) + { + memcpy(code, utf_units, CU2BYTES(c & 7)); + code += c & 7; + } + else +#endif /* MAYBE_UTF_MULTI */ + { + *code++ = c; + if (prop_type >= 0) + { + *code++ = prop_type; + *code++ = prop_value; + } + } + + /* Now set up the following opcode */ + + if (repeat_max < 0) *code++ = OP_STAR + repeat_type; else + { + repeat_max -= repeat_min; + if (repeat_max == 1) + { + *code++ = OP_QUERY + repeat_type; + } + else + { + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + } + } + + /* Fill in the character or character type for the final opcode. */ + +#ifdef MAYBE_UTF_MULTI + if (utf && (c & UTF_LENGTH) != 0) + { + memcpy(code, utf_units, CU2BYTES(c & 7)); + code += c & 7; + } + else +#endif /* MAYBEW_UTF_MULTI */ + { + *code++ = c; + if (prop_type >= 0) + { + *code++ = prop_type; + *code++ = prop_value; + } + } + } + + /* If previous was a character class or a back reference, we put the repeat + stuff after it, but just skip the item if the repeat was {0,0}. */ + + else if (*previous == OP_CLASS || *previous == OP_NCLASS || +#ifdef SUPPORT_WIDE_CHARS + *previous == OP_XCLASS || +#endif + *previous == OP_REF || *previous == OP_REFI || + *previous == OP_DNREF || *previous == OP_DNREFI) + { + if (repeat_max == 0) + { + code = previous; + goto END_REPEAT; + } + + if (repeat_min == 0 && repeat_max == -1) + *code++ = OP_CRSTAR + repeat_type; + else if (repeat_min == 1 && repeat_max == -1) + *code++ = OP_CRPLUS + repeat_type; + else if (repeat_min == 0 && repeat_max == 1) + *code++ = OP_CRQUERY + repeat_type; + else + { + *code++ = OP_CRRANGE + repeat_type; + PUT2INC(code, 0, repeat_min); + if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ + PUT2INC(code, 0, repeat_max); + } + } + + /* If previous was a bracket group, we may have to replicate it in certain + cases. Note that at this point we can encounter only the "basic" bracket + opcodes such as BRA and CBRA, as this is the place where they get converted + into the more special varieties such as BRAPOS and SBRA. A test for >= + OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, + ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND. + Originally, PCRE did not allow repetition of assertions, but now it does, + for Perl compatibility. */ + + else if (*previous >= OP_ASSERT && *previous <= OP_COND) + { + register int i; + int len = (int)(code - previous); + PCRE2_UCHAR *bralink = NULL; + PCRE2_UCHAR *brazeroptr = NULL; + + /* Repeating a DEFINE group (or any group where the condition is always + FALSE and there is only one branch) is pointless, but Perl allows the + syntax, so we just ignore the repeat. */ + + if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE && + previous[GET(previous, 1)] != OP_ALT) + goto END_REPEAT; + + /* There is no sense in actually repeating assertions. The only potential + use of repetition is in cases when the assertion is optional. Therefore, + if the minimum is greater than zero, just ignore the repeat. If the + maximum is not zero or one, set it to 1. */ + + if (*previous < OP_ONCE) /* Assertion */ + { + if (repeat_min > 0) goto END_REPEAT; + if (repeat_max < 0 || repeat_max > 1) repeat_max = 1; + } + + /* The case of a zero minimum is special because of the need to stick + OP_BRAZERO in front of it, and because the group appears once in the + data, whereas in other cases it appears the minimum number of times. For + this reason, it is simplest to treat this case separately, as otherwise + the code gets far too messy. There are several special subcases when the + minimum is zero. */ + + if (repeat_min == 0) + { + /* If the maximum is also zero, we used to just omit the group from the + output altogether, like this: + + ** if (repeat_max == 0) + ** { + ** code = previous; + ** goto END_REPEAT; + ** } + + However, that fails when a group or a subgroup within it is referenced + as a subroutine from elsewhere in the pattern, so now we stick in + OP_SKIPZERO in front of it so that it is skipped on execution. As we + don't have a list of which groups are referenced, we cannot do this + selectively. + + If the maximum is 1 or unlimited, we just have to stick in the BRAZERO + and do no more at this point. */ + + if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ + { + memmove(previous + 1, previous, CU2BYTES(len)); + code++; + if (repeat_max == 0) + { + *previous++ = OP_SKIPZERO; + goto END_REPEAT; + } + brazeroptr = previous; /* Save for possessive optimizing */ + *previous++ = OP_BRAZERO + repeat_type; + } + + /* If the maximum is greater than 1 and limited, we have to replicate + in a nested fashion, sticking OP_BRAZERO before each set of brackets. + The first one has to be handled carefully because it's the original + copy, which has to be moved up. The remainder can be handled by code + that is common with the non-zero minimum case below. We have to + adjust the value or repeat_max, since one less copy is required. */ + + else + { + int offset; + memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len)); + code += 2 + LINK_SIZE; + *previous++ = OP_BRAZERO + repeat_type; + *previous++ = OP_BRA; + + /* We chain together the bracket offset fields that have to be + filled in later when the ends of the brackets are reached. */ + + offset = (bralink == NULL)? 0 : (int)(previous - bralink); + bralink = previous; + PUTINC(previous, 0, offset); + } + + repeat_max--; + } + + /* If the minimum is greater than zero, replicate the group as many + times as necessary, and adjust the maximum to the number of subsequent + copies that we need. */ + + else + { + if (repeat_min > 1) + { + /* In the pre-compile phase, we don't actually do the replication. We + just adjust the length as if we had. Do some paranoid checks for + potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit + integer type when available, otherwise double. */ + + if (lengthptr != NULL) + { + size_t delta = (repeat_min - 1)*length_prevgroup; + if ((INT64_OR_DOUBLE)(repeat_min - 1)* + (INT64_OR_DOUBLE)length_prevgroup > + (INT64_OR_DOUBLE)INT_MAX || + OFLOW_MAX - *lengthptr < delta) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += delta; + } + + /* This is compiling for real. If there is a set first byte for + the group, and we have not yet set a "required byte", set it. */ + + else + { + if (groupsetfirstcu && reqcuflags < 0) + { + reqcu = firstcu; + reqcuflags = firstcuflags; + } + for (i = 1; i < repeat_min; i++) + { + memcpy(code, previous, CU2BYTES(len)); + code += len; + } + } + } + + if (repeat_max > 0) repeat_max -= repeat_min; + } + + /* This code is common to both the zero and non-zero minimum cases. If + the maximum is limited, it replicates the group in a nested fashion, + remembering the bracket starts on a stack. In the case of a zero minimum, + the first one was set up above. In all cases the repeat_max now specifies + the number of additional copies needed. Again, we must remember to + replicate entries on the forward reference list. */ + + if (repeat_max >= 0) + { + /* In the pre-compile phase, we don't actually do the replication. We + just adjust the length as if we had. For each repetition we must add 1 + to the length for BRAZERO and for all but the last repetition we must + add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some + paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is + a 64-bit integer type when available, otherwise double. */ + + if (lengthptr != NULL && repeat_max > 0) + { + size_t delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - + 2 - 2*LINK_SIZE; /* Last one doesn't nest */ + if ((INT64_OR_DOUBLE)repeat_max * + (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) + > (INT64_OR_DOUBLE)INT_MAX || + OFLOW_MAX - *lengthptr < delta) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += delta; + } + + /* This is compiling for real */ + + else for (i = repeat_max - 1; i >= 0; i--) + { + *code++ = OP_BRAZERO + repeat_type; + + /* All but the final copy start a new nesting, maintaining the + chain of brackets outstanding. */ + + if (i != 0) + { + int offset; + *code++ = OP_BRA; + offset = (bralink == NULL)? 0 : (int)(code - bralink); + bralink = code; + PUTINC(code, 0, offset); + } + + memcpy(code, previous, CU2BYTES(len)); + code += len; + } + + /* Now chain through the pending brackets, and fill in their length + fields (which are holding the chain links pro tem). */ + + while (bralink != NULL) + { + int oldlinkoffset; + int offset = (int)(code - bralink + 1); + PCRE2_UCHAR *bra = code - offset; + oldlinkoffset = GET(bra, 1); + bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; + *code++ = OP_KET; + PUTINC(code, 0, offset); + PUT(bra, 1, offset); + } + } + + /* If the maximum is unlimited, set a repeater in the final copy. For + ONCE brackets, that's all we need to do. However, possessively repeated + ONCE brackets can be converted into non-capturing brackets, as the + behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to + deal with possessive ONCEs specially. + + Otherwise, when we are doing the actual compile phase, check to see + whether this group is one that could match an empty string. If so, + convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so + that runtime checking can be done. [This check is also applied to ONCE + groups at runtime, but in a different way.] + + Then, if the quantifier was possessive and the bracket is not a + conditional, we convert the BRA code to the POS form, and the KET code to + KETRPOS. (It turns out to be convenient at runtime to detect this kind of + subpattern at both the start and at the end.) The use of special opcodes + makes it possible to reduce greatly the stack usage in pcre2_match(). If + the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. + + Then, if the minimum number of matches is 1 or 0, cancel the possessive + flag so that the default action below, of wrapping everything inside + atomic brackets, does not happen. When the minimum is greater than 1, + there will be earlier copies of the group, and so we still have to wrap + the whole thing. */ + + else + { + PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE; + PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1); + + /* Convert possessive ONCE brackets to non-capturing */ + + if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) && + possessive_quantifier) *bracode = OP_BRA; + + /* For non-possessive ONCE brackets, all we need to do is to + set the KET. */ + + if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC) + *ketcode = OP_KETRMAX + repeat_type; + + /* Handle non-ONCE brackets and possessive ONCEs (which have been + converted to non-capturing above). */ + + else + { + /* In the compile phase, check whether the group could match an empty + string. */ + + if (lengthptr == NULL) + { + PCRE2_UCHAR *scode = bracode; + do + { + int count = 0; + int rc = could_be_empty_branch(scode, ketcode, utf, cb, FALSE, + NULL, &count); + if (rc < 0) + { + *errorcodeptr = ERR86; + goto FAILED; + } + if (rc > 0) + { + *bracode += OP_SBRA - OP_BRA; + break; + } + scode += GET(scode, 1); + } + while (*scode == OP_ALT); + + /* A conditional group with only one branch has an implicit empty + alternative branch. */ + + if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT) + *bracode = OP_SCOND; + } + + /* Handle possessive quantifiers. */ + + if (possessive_quantifier) + { + /* For COND brackets, we wrap the whole thing in a possessively + repeated non-capturing bracket, because we have not invented POS + versions of the COND opcodes. */ + + if (*bracode == OP_COND || *bracode == OP_SCOND) + { + int nlen = (int)(code - bracode); + memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen)); + code += 1 + LINK_SIZE; + nlen += 1 + LINK_SIZE; + *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS; + *code++ = OP_KETRPOS; + PUTINC(code, 0, nlen); + PUT(bracode, 1, nlen); + } + + /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ + + else + { + *bracode += 1; /* Switch to xxxPOS opcodes */ + *ketcode = OP_KETRPOS; + } + + /* If the minimum is zero, mark it as possessive, then unset the + possessive flag when the minimum is 0 or 1. */ + + if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; + if (repeat_min < 2) possessive_quantifier = FALSE; + } + + /* Non-possessive quantifier */ + + else *ketcode = OP_KETRMAX + repeat_type; + } + } + } + + /* If previous is OP_FAIL, it was generated by an empty class [] + (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be + generated, that is by (*FAIL) or (?!), set previous to NULL, which gives a + "nothing to repeat" error above. We can just ignore the repeat in empty + class case. */ + + else if (*previous == OP_FAIL) goto END_REPEAT; + + /* Else there's some kind of shambles */ + + else + { + *errorcodeptr = ERR10; + goto FAILED; + } + + /* If the character following a repeat is '+', possessive_quantifier is + TRUE. For some opcodes, there are special alternative opcodes for this + case. For anything else, we wrap the entire repeated item inside OP_ONCE + brackets. Logically, the '+' notation is just syntactic sugar, taken from + Sun's Java package, but the special opcodes can optimize it. + + Some (but not all) possessively repeated subpatterns have already been + completely handled in the code just above. For them, possessive_quantifier + is always FALSE at this stage. Note that the repeated item starts at + tempcode, not at previous, which might be the first part of a string whose + (former) last char we repeated. */ + + if (possessive_quantifier) + { + int len; + + /* Possessifying an EXACT quantifier has no effect, so we can ignore it. + However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6}, + {5,}, or {5,10}). We skip over an EXACT item; if the length of what + remains is greater than zero, there's a further opcode that can be + handled. If not, do nothing, leaving the EXACT alone. */ + + switch(*tempcode) + { + case OP_TYPEEXACT: + tempcode += PRIV(OP_lengths)[*tempcode] + + ((tempcode[1 + IMM2_SIZE] == OP_PROP + || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); + break; + + /* CHAR opcodes are used for exacts whose count is 1. */ + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + tempcode += PRIV(OP_lengths)[*tempcode]; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(tempcode[-1])) + tempcode += GET_EXTRALEN(tempcode[-1]); +#endif + break; + + /* For the class opcodes, the repeat operator appears at the end; + adjust tempcode to point to it. */ + + case OP_CLASS: + case OP_NCLASS: + tempcode += 1 + 32/sizeof(PCRE2_UCHAR); + break; + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + tempcode += GET(tempcode, 1); + break; +#endif + } + + /* If tempcode is equal to code (which points to the end of the repeated + item), it means we have skipped an EXACT item but there is no following + QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In + all other cases, tempcode will be pointing to the repeat opcode, and will + be less than code, so the value of len will be greater than 0. */ + + len = (int)(code - tempcode); + if (len > 0) + { + unsigned int repcode = *tempcode; + + /* There is a table for possessifying opcodes, all of which are less + than OP_CALLOUT. A zero entry means there is no possessified version. + */ + + if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0) + *tempcode = opcode_possessify[repcode]; + + /* For opcode without a special possessified version, wrap the item in + ONCE brackets. */ + + else + { + memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len)); + code += 1 + LINK_SIZE; + len += 1 + LINK_SIZE; + tempcode[0] = OP_ONCE; + *code++ = OP_KET; + PUTINC(code, 0, len); + PUT(tempcode, 1, len); + } + } + } + + /* In all case we no longer have a previous item. We also set the + "follows varying string" flag for subsequently encountered reqcus if + it isn't already set and we have just passed a varying length item. */ + + END_REPEAT: + previous = NULL; + cb->req_varyopt |= reqvary; + break; + + + /* ===================================================================*/ + /* Start of nested parenthesized sub-expression, or lookahead or lookbehind + or option setting or condition or all the other extended parenthesis forms. + We must save the current high-water-mark for the forward reference list so + that we know where they start for this group. However, because the list may + be extended when there are very many forward references (usually the result + of a replicated inner group), we must use an offset rather than an absolute + address. Note that (?# comments are dealt with at the top of the loop; + they do not get this far. */ + + case CHAR_LEFT_PARENTHESIS: + ptr++; + + /* Deal with various "verbs" that can be introduced by '*'. */ + + if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' + || (MAX_255(ptr[1]) && ((cb->ctypes[ptr[1]] & ctype_letter) != 0)))) + { + int i, namelen; + int arglen = 0; + const char *vn = verbnames; + PCRE2_SPTR name = ptr + 1; + PCRE2_SPTR arg = NULL; + previous = NULL; + ptr++; + + /* Increment ptr, set namelen, check length */ + + READ_NAME(ctype_letter, ERR60, *errorcodeptr); + + /* It appears that Perl allows any characters whatsoever, other than + a closing parenthesis, to appear in arguments, so we no longer insist on + letters, digits, and underscores. Perl does not, however, do any + interpretation within arguments, and has no means of including a closing + parenthesis. PCRE supports escape processing but only when it is + requested by an option. Note that check_escape() will not return values + greater than the code unit maximum when not in UTF mode. */ + + if (*ptr == CHAR_COLON) + { + arg = ++ptr; + + if ((options & PCRE2_ALT_VERBNAMES) == 0) + { + arglen = 0; + while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) + { + ptr++; /* Check length as we go */ + arglen++; /* along, to avoid the */ + if ((unsigned int)arglen > MAX_MARK) /* possibility of overflow. */ + { + *errorcodeptr = ERR76; + goto FAILED; + } + } + } + else + { + /* The length check is in process_verb_names() */ + arglen = process_verb_name(&ptr, NULL, errorcodeptr, options, + utf, cb); + if (arglen < 0) goto FAILED; + } + } + + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR60; + goto FAILED; + } + + /* Scan the table of verb names */ + + for (i = 0; i < verbcount; i++) + { + if (namelen == verbs[i].len && + PRIV(strncmp_c8)(name, vn, namelen) == 0) + { + int setverb; + + /* Check for open captures before ACCEPT and convert it to + ASSERT_ACCEPT if in an assertion. */ + + if (verbs[i].op == OP_ACCEPT) + { + open_capitem *oc; + if (arglen != 0) + { + *errorcodeptr = ERR59; + goto FAILED; + } + cb->had_accept = TRUE; + /* In the first pass, just accumulate the length required; + otherwise hitting (*ACCEPT) inside many nested parentheses can + cause workspace overflow. */ + for (oc = cb->open_caps; oc != NULL; oc = oc->next) + { + if (lengthptr != NULL) + { + *lengthptr += CU2BYTES(1) + IMM2_SIZE; + } + else + { + *code++ = OP_CLOSE; + PUT2INC(code, 0, oc->number); + } + } + + setverb = *code++ = + (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; + + /* Do not set firstcu after *ACCEPT */ + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + } + + /* Handle other cases with/without an argument */ + + else if (arglen == 0) /* There is no argument */ + { + if (verbs[i].op < 0) /* Argument is mandatory */ + { + *errorcodeptr = ERR66; + goto FAILED; + } + setverb = *code++ = verbs[i].op; + } + + else /* An argument is present */ + { + if (verbs[i].op_arg < 0) /* Argument is forbidden */ + { + *errorcodeptr = ERR59; + goto FAILED; + } + setverb = *code++ = verbs[i].op_arg; + + /* Arguments can be very long, especially in 16- and 32-bit modes, + and can overflow the workspace in the first pass. Instead of + putting the argument into memory, we just update the length counter + and set up an empty argument. */ + + if (lengthptr != NULL) + { + *lengthptr += arglen; + *code++ = 0; + } + else + { + *code++ = arglen; + if ((options & PCRE2_ALT_VERBNAMES) != 0) + { + PCRE2_UCHAR *memcode = code; /* code is "register" */ + (void)process_verb_name(&arg, &memcode, errorcodeptr, options, + utf, cb); + code = memcode; + } + else /* No argument processing */ + { + memcpy(code, arg, CU2BYTES(arglen)); + code += arglen; + } + } + + *code++ = 0; + } + + switch (setverb) + { + case OP_THEN: + case OP_THEN_ARG: + cb->external_flags |= PCRE2_HASTHEN; + break; + + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + cb->had_pruneorskip = TRUE; + break; + } + + break; /* Found verb, exit loop */ + } + + vn += verbs[i].len + 1; + } + + if (i < verbcount) continue; /* Successfully handled a verb */ + *errorcodeptr = ERR60; /* Verb not recognized */ + goto FAILED; + } + + /* Initialization for "real" parentheses */ + + newoptions = options; + skipunits = 0; + bravalue = OP_CBRA; + reset_bracount = FALSE; + + /* Deal with the extended parentheses; all are introduced by '?', and the + appearance of any of them means that this is not a capturing group. */ + + if (*ptr == CHAR_QUESTION_MARK) + { + int i, count; + int namelen; /* Must be signed */ + uint32_t index; + uint32_t set, unset, *optset; + named_group *ng; + PCRE2_SPTR name; + PCRE2_UCHAR *slot; + + switch (*(++ptr)) + { + /* ------------------------------------------------------------ */ + case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ + reset_bracount = TRUE; + /* Fall through */ + + /* ------------------------------------------------------------ */ + case CHAR_COLON: /* Non-capturing bracket */ + bravalue = OP_BRA; + ptr++; + break; + + /* ------------------------------------------------------------ */ + case CHAR_LEFT_PARENTHESIS: + bravalue = OP_COND; /* Conditional group */ + tempptr = ptr; + + /* A condition can be an assertion, a number (referring to a numbered + group's having been set), a name (referring to a named group), or 'R', + referring to recursion. R and R&name are also permitted for + recursion tests. + + There are ways of testing a named group: (?(name)) is used by Python; + Perl 5.10 onwards uses (?() or (?('name')). + + There is one unfortunate ambiguity, caused by history. 'R' can be the + recursive thing or the name 'R' (and similarly for 'R' followed by + digits). We look for a name first; if not found, we try the other case. + + For compatibility with auto-callouts, we allow a callout to be + specified before a condition that is an assertion. First, check for the + syntax of a callout; if found, adjust the temporary pointer that is + used to check for an assertion condition. That's all that is needed! */ + + if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C) + { + if (IS_DIGIT(ptr[3]) || ptr[3] == CHAR_RIGHT_PARENTHESIS) + { + for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break; + if (ptr[i] == CHAR_RIGHT_PARENTHESIS) + tempptr += i + 1; + } + else + { + uint32_t delimiter = 0; + for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) + { + if (ptr[3] == PRIV(callout_start_delims)[i]) + { + delimiter = PRIV(callout_end_delims)[i]; + break; + } + } + if (delimiter != 0) + { + for (i = 4; ptr + i < cb->end_pattern; i++) + { + if (ptr[i] == delimiter) + { + if (ptr[i+1] == delimiter) i++; + else + { + if (ptr[i+1] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 2; + break; + } + } + } + } + } + + /* tempptr should now be pointing to the opening parenthesis of the + assertion condition. */ + + if (*tempptr != CHAR_LEFT_PARENTHESIS) + { + *errorcodeptr = ERR28; + goto FAILED; + } + } + + /* For conditions that are assertions, check the syntax, and then exit + the switch. This will take control down to where bracketed groups + are processed. The assertion will be handled as part of the group, + but we need to identify this case because the conditional assertion may + not be quantifier. */ + + if (tempptr[1] == CHAR_QUESTION_MARK && + (tempptr[2] == CHAR_EQUALS_SIGN || + tempptr[2] == CHAR_EXCLAMATION_MARK || + (tempptr[2] == CHAR_LESS_THAN_SIGN && + (tempptr[3] == CHAR_EQUALS_SIGN || + tempptr[3] == CHAR_EXCLAMATION_MARK)))) + { + cb->iscondassert = TRUE; + break; + } + + /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all + need to skip at least 1+IMM2_SIZE bytes at the start of the group. */ + + code[1+LINK_SIZE] = OP_CREF; + skipunits = 1+IMM2_SIZE; + refsign = -1; /* => not a number */ + namelen = -1; /* => not a name; must set to avoid warning */ + name = NULL; /* Always set to avoid warning */ + recno = 0; /* Always set to avoid warning */ + + /* Point at character after (?( */ + + ptr++; + + /* Check for (?(VERSION[>]=n.m), which is a facility whereby indirect + users of PCRE2 via an application can discover which release of PCRE2 + is being used. */ + + if (PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 && + ptr[7] != CHAR_RIGHT_PARENTHESIS) + { + BOOL ge = FALSE; + int major = 0; + int minor = 0; + + ptr += 7; + if (*ptr == CHAR_GREATER_THAN_SIGN) + { + ge = TRUE; + ptr++; + } + + /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT + references its argument twice. */ + + if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr))) + { + *errorcodeptr = ERR79; + goto FAILED; + } + + while (IS_DIGIT(*ptr)) major = major * 10 + *ptr++ - '0'; + if (*ptr == CHAR_DOT) + { + ptr++; + while (IS_DIGIT(*ptr)) minor = minor * 10 + *ptr++ - '0'; + if (minor < 10) minor *= 10; + } + + if (*ptr != CHAR_RIGHT_PARENTHESIS || minor > 99) + { + *errorcodeptr = ERR79; + goto FAILED; + } + + if (ge) + code[1+LINK_SIZE] = ((PCRE2_MAJOR > major) || + (PCRE2_MAJOR == major && PCRE2_MINOR >= minor))? + OP_TRUE : OP_FALSE; + else + code[1+LINK_SIZE] = (PCRE2_MAJOR == major && PCRE2_MINOR == minor)? + OP_TRUE : OP_FALSE; + + ptr++; + skipunits = 1; + break; /* End of condition processing */ + } + + /* Check for a test for recursion in a named group. */ + + if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND) + { + terminator = -1; + ptr += 2; + code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */ + } + + /* Check for a test for a named group's having been set, using the Perl + syntax (?() or (?('name'), and also allow for the original PCRE + syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */ + + else if (*ptr == CHAR_LESS_THAN_SIGN) + { + terminator = CHAR_GREATER_THAN_SIGN; + ptr++; + } + else if (*ptr == CHAR_APOSTROPHE) + { + terminator = CHAR_APOSTROPHE; + ptr++; + } + else + { + terminator = CHAR_NULL; + if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++; + else if (IS_DIGIT(*ptr)) refsign = 0; + } + + /* Handle a number */ + + if (refsign >= 0) + { + while (IS_DIGIT(*ptr)) + { + if (recno > INT_MAX / 10 - 1) /* Integer overflow */ + { + while (IS_DIGIT(*ptr)) ptr++; + *errorcodeptr = ERR61; + goto FAILED; + } + recno = recno * 10 + (int)(*ptr - CHAR_0); + ptr++; + } + } + + /* Otherwise we expect to read a name; anything else is an error. When + the referenced name is one of a number of duplicates, a different + opcode is used and it needs more memory. Unfortunately we cannot tell + whether this is the case in the first pass, so we have to allow for + more memory always. In the second pass, the additional to skipunits + happens later. */ + + else + { + if (IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR44; /* Group name must start with non-digit */ + goto FAILED; + } + if (!MAX_255(*ptr) || (cb->ctypes[*ptr] & ctype_word) == 0) + { + *errorcodeptr = ERR28; /* Assertion expected */ + goto FAILED; + } + name = ptr; + /* Increment ptr, set namelen, check length */ + READ_NAME(ctype_word, ERR48, *errorcodeptr); + if (lengthptr != NULL) skipunits += IMM2_SIZE; + } + + /* Check the terminator */ + + if ((terminator > 0 && *ptr++ != (PCRE2_UCHAR)terminator) || + *ptr++ != CHAR_RIGHT_PARENTHESIS) + { + ptr--; /* Error offset */ + *errorcodeptr = ERR26; /* Malformed number or name */ + goto FAILED; + } + + /* Do no further checking in the pre-compile phase. */ + + if (lengthptr != NULL) break; + + /* In the real compile we do the work of looking for the actual + reference. If refsign is not negative, it means we have a number in + recno. */ + + if (refsign >= 0) + { + if (recno <= 0) + { + *errorcodeptr = ERR35; + goto FAILED; + } + if (refsign != 0) recno = (refsign == CHAR_MINUS)? + (cb->bracount + 1) - recno : recno + cb->bracount; + if (recno <= 0 || (uint32_t)recno > cb->final_bracount) + { + *errorcodeptr = ERR15; + goto FAILED; + } + PUT2(code, 2+LINK_SIZE, recno); + if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; + break; + } + + /* Otherwise look for the name. */ + + slot = cb->name_table; + for (i = 0; i < cb->names_found; i++) + { + if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0) break; + slot += cb->name_entry_size; + } + + /* Found the named subpattern. If the name is duplicated, add one to + the opcode to change CREF/RREF into DNCREF/DNRREF and insert + appropriate data values. Otherwise, just insert the unique subpattern + number. */ + + if (i < cb->names_found) + { + int offset = i; /* Offset of first name found */ + + count = 0; + for (;;) + { + recno = GET2(slot, 0); /* Number for last found */ + if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; + count++; + if (++i >= cb->names_found) break; + slot += cb->name_entry_size; + if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) != 0 || + (slot+IMM2_SIZE)[namelen] != 0) break; + } + + if (count > 1) + { + PUT2(code, 2+LINK_SIZE, offset); + PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count); + skipunits += IMM2_SIZE; + code[1+LINK_SIZE]++; + } + else /* Not a duplicated name */ + { + PUT2(code, 2+LINK_SIZE, recno); + } + } + + /* If terminator == CHAR_NULL it means that the name followed directly + after the opening parenthesis [e.g. (?(abc)...] and in this case there + are some further alternatives to try. For the cases where terminator != + CHAR_NULL [things like (?(... or (?('name')... or (?(R&name)... ] + we have now checked all the possibilities, so give an error. */ + + else if (terminator != CHAR_NULL) + { + *errorcodeptr = ERR15; + goto FAILED; + } + + /* Check for (?(R) for recursion. Allow digits after R to specify a + specific group number. */ + + else if (*name == CHAR_R) + { + recno = 0; + for (i = 1; i < namelen; i++) + { + if (!IS_DIGIT(name[i])) + { + *errorcodeptr = ERR15; /* Non-existent subpattern */ + goto FAILED; + } + if (recno > INT_MAX / 10 - 1) /* Integer overflow */ + { + *errorcodeptr = ERR61; + goto FAILED; + } + recno = recno * 10 + name[i] - CHAR_0; + } + if (recno == 0) recno = RREF_ANY; + code[1+LINK_SIZE] = OP_RREF; /* Change test type */ + PUT2(code, 2+LINK_SIZE, recno); + } + + /* Similarly, check for the (?(DEFINE) "condition", which is always + false. During compilation we set OP_DEFINE to distinguish this from + other OP_FALSE conditions so that it can be checked for having only one + branch, but after that the opcode is changed to OP_FALSE. */ + + else if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0) + { + code[1+LINK_SIZE] = OP_DEFINE; + skipunits = 1; + } + + /* Reference to an unidentified subpattern. */ + + else + { + *errorcodeptr = ERR15; + goto FAILED; + } + break; + + + /* ------------------------------------------------------------ */ + case CHAR_EQUALS_SIGN: /* Positive lookahead */ + bravalue = OP_ASSERT; + cb->assert_depth += 1; + ptr++; + break; + + /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird + thing to do, but Perl allows all assertions to be quantified, and when + they contain capturing parentheses there may be a potential use for + this feature. Not that that applies to a quantified (?!) but we allow + it for uniformity. */ + + /* ------------------------------------------------------------ */ + case CHAR_EXCLAMATION_MARK: /* Negative lookahead */ + ptr++; + if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK && + ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK && + (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2))) + { + *code++ = OP_FAIL; + previous = NULL; + continue; + } + bravalue = OP_ASSERT_NOT; + cb->assert_depth += 1; + break; + + + /* ------------------------------------------------------------ */ + case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */ + switch (ptr[1]) + { + case CHAR_EQUALS_SIGN: /* Positive lookbehind */ + bravalue = OP_ASSERTBACK; + cb->assert_depth += 1; + ptr += 2; + break; + + case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */ + bravalue = OP_ASSERTBACK_NOT; + cb->assert_depth += 1; + ptr += 2; + break; + + /* Must be a name definition - as the syntax was checked in the + pre-pass, we can assume here that it is valid. Skip over the name + and go to handle the numbered group. */ + + default: + while (*(++ptr) != CHAR_GREATER_THAN_SIGN); + ptr++; + goto NUMBERED_GROUP; + } + break; + + + /* ------------------------------------------------------------ */ + case CHAR_GREATER_THAN_SIGN: /* One-time brackets */ + bravalue = OP_ONCE; + ptr++; + break; + + + /* ------------------------------------------------------------ */ + case CHAR_C: /* Callout */ + previous_callout = code; /* Save for later completion */ + after_manual_callout = 1; /* Skip one item before completing */ + ptr++; /* Character after (?C */ + + /* A callout may have a string argument, delimited by one of a fixed + number of characters, or an undelimited numerical argument, or no + argument, which is the same as (?C0). Different opcodes are used for + the two cases. */ + + if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr)) + { + uint32_t delimiter = 0; + + for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) + { + if (*ptr == PRIV(callout_start_delims)[i]) + { + delimiter = PRIV(callout_end_delims)[i]; + break; + } + } + + if (delimiter == 0) + { + *errorcodeptr = ERR82; + goto FAILED; + } + + /* During the pre-compile phase, we parse the string and update the + length. There is no need to generate any code. (In fact, the string + has already been parsed in the pre-pass that looks for named + parentheses, but it does no harm to leave this code in.) */ + + if (lengthptr != NULL) /* Only check the string */ + { + PCRE2_SPTR start = ptr; + do + { + if (++ptr >= cb->end_pattern) + { + *errorcodeptr = ERR81; + ptr = start; /* To give a more useful message */ + goto FAILED; + } + if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; + } + while (ptr[0] != delimiter); + + /* Start points to the opening delimiter, ptr points to the + closing delimiter. We must allow for including the delimiter and + for the terminating zero. Any doubled delimiters within the string + make this an overestimate, but it is not worth bothering about. */ + + (*lengthptr) += (ptr - start) + 2 + (1 + 4*LINK_SIZE); + } + + /* In the real compile we can copy the string, knowing that it is + syntactically OK. The starting delimiter is included so that the + client can discover it if they want. We also pass the start offset to + help a script language give better error messages. */ + + else + { + PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE); + *callout_string++ = *ptr++; + PUT(code, 1 + 3*LINK_SIZE, (int)(ptr - cb->start_pattern)); /* Start offset */ + for(;;) + { + if (*ptr == delimiter) + { + if (ptr[1] == delimiter) ptr++; else break; + } + *callout_string++ = *ptr++; + } + *callout_string++ = CHAR_NULL; + code[0] = OP_CALLOUT_STR; + PUT(code, 1, (int)(ptr + 2 - cb->start_pattern)); /* Next offset */ + PUT(code, 1 + LINK_SIZE, 0); /* Default length */ + PUT(code, 1 + 2*LINK_SIZE, /* Compute size */ + (int)(callout_string - code)); + code = callout_string; + } + + /* Advance to what should be the closing parenthesis, which is + checked below. */ + + ptr++; + } + + /* Handle a callout with an optional numerical argument, which must be + less than or equal to 255. A missing argument gives 0. */ + + else + { + int n = 0; + code[0] = OP_CALLOUT; /* Numerical callout */ + while (IS_DIGIT(*ptr)) + { + n = n * 10 + *ptr++ - CHAR_0; + if (n > 255) + { + *errorcodeptr = ERR38; + goto FAILED; + } + } + PUT(code, 1, (int)(ptr - cb->start_pattern + 1)); /* Next offset */ + PUT(code, 1 + LINK_SIZE, 0); /* Default length */ + code[1 + 2*LINK_SIZE] = n; /* Callout number */ + code += PRIV(OP_lengths)[OP_CALLOUT]; + } + + /* Both formats must have a closing parenthesis */ + + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR39; + goto FAILED; + } + + /* Callouts cannot be quantified. */ + + previous = NULL; + continue; + + + /* ------------------------------------------------------------ */ + case CHAR_P: /* Python-style named subpattern handling */ + if (*(++ptr) == CHAR_EQUALS_SIGN || + *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */ + { + is_recurse = *ptr == CHAR_GREATER_THAN_SIGN; + terminator = CHAR_RIGHT_PARENTHESIS; + goto NAMED_REF_OR_RECURSE; + } + else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */ + { + *errorcodeptr = ERR41; + goto FAILED; + } + /* Fall through to handle (?P< as (?< is handled */ + + + /* ------------------------------------------------------------ */ + case CHAR_APOSTROPHE: /* Define a name - note fall through above */ + + /* The syntax was checked and the list of names was set up in the + pre-pass, so there is nothing to be done now except to skip over the + name. */ + + terminator = (*ptr == CHAR_LESS_THAN_SIGN)? + CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; + while (*(++ptr) != (unsigned int)terminator); + ptr++; + goto NUMBERED_GROUP; /* Set up numbered group */ + + + /* ------------------------------------------------------------ */ + case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */ + terminator = CHAR_RIGHT_PARENTHESIS; + is_recurse = TRUE; + /* Fall through */ + + /* We come here from the Python syntax above that handles both + references (?P=name) and recursion (?P>name), as well as falling + through from the Perl recursion syntax (?&name). We also come here from + the Perl \k or \k'name' back reference syntax and the \k{name} + .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */ + + NAMED_REF_OR_RECURSE: + name = ++ptr; + if (IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR44; /* Group name must start with non-digit */ + goto FAILED; + } + /* Increment ptr, set namelen, check length */ + READ_NAME(ctype_word, ERR48, *errorcodeptr); + + /* In the pre-compile phase, do a syntax check. */ + + if (lengthptr != NULL) + { + if (namelen == 0) + { + *errorcodeptr = ERR62; + goto FAILED; + } + if (*ptr != (PCRE2_UCHAR)terminator) + { + *errorcodeptr = ERR42; + goto FAILED; + } + } + + /* Scan the list of names generated in the pre-pass in order to get + a number and whether or not this name is duplicated. */ + + recno = 0; + is_dupname = FALSE; + ng = cb->named_groups; + + for (i = 0; i < cb->names_found; i++, ng++) + { + if (namelen == ng->length && + PRIV(strncmp)(name, ng->name, namelen) == 0) + { + open_capitem *oc; + is_dupname = ng->isdup; + recno = ng->number; + + /* For a recursion, that's all that is needed. We can now go to the + code that handles numerical recursion. */ + + if (is_recurse) goto HANDLE_RECURSION; + + /* For a back reference, update the back reference map and the + maximum back reference. Then for each group we must check to see if + it is recursive, that is, it is inside the group that it + references. A flag is set so that the group can be made atomic. */ + + cb->backref_map |= (recno < 32)? (1u << recno) : 1; + if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; + + for (oc = cb->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; + break; + } + } + } + } + + /* If the name was not found we have a bad reference. */ + + if (recno == 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + + /* If a back reference name is not duplicated, we can handle it as a + numerical reference. */ + + if (!is_dupname) goto HANDLE_REFERENCE; + + /* If a back reference name is duplicated, we generate a different + opcode to a numerical back reference. In the second pass we must search + for the index and count in the final name table. */ + + count = 0; + index = 0; + + if (lengthptr == NULL) + { + slot = cb->name_table; + for (i = 0; i < cb->names_found; i++) + { + if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0 && + slot[IMM2_SIZE+namelen] == 0) + { + if (count == 0) index = i; + count++; + } + slot += cb->name_entry_size; + } + + if (count == 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + } + + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + previous = code; + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF; + PUT2INC(code, 0, index); + PUT2INC(code, 0, count); + continue; /* End of back ref handling */ + + + /* ------------------------------------------------------------ */ + case CHAR_R: /* Recursion, same as (?0) */ + recno = 0; + if (*(++ptr) != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR29; + goto FAILED; + } + goto HANDLE_RECURSION; + + + /* ------------------------------------------------------------ */ + case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */ + case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: + case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: + { + terminator = CHAR_RIGHT_PARENTHESIS; + + /* Come here from the \g<...> and \g'...' code (Oniguruma + compatibility). However, the syntax has been checked to ensure that + the ... are a (signed) number, so that neither ERR63 nor ERR29 will + be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY + ever be taken. */ + + HANDLE_NUMERICAL_RECURSION: + + if ((refsign = *ptr) == CHAR_PLUS) + { + ptr++; + if (!IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR63; + goto FAILED; + } + } + else if (refsign == CHAR_MINUS) + { + if (!IS_DIGIT(ptr[1])) + goto OTHER_CHAR_AFTER_QUERY; + ptr++; + } + + recno = 0; + while (IS_DIGIT(*ptr)) + { + if (recno > INT_MAX / 10 - 1) /* Integer overflow */ + { + while (IS_DIGIT(*ptr)) ptr++; + *errorcodeptr = ERR61; + goto FAILED; + } + recno = recno * 10 + *ptr++ - CHAR_0; + } + + if (*ptr != (PCRE2_UCHAR)terminator) + { + *errorcodeptr = ERR29; + goto FAILED; + } + + if (refsign == CHAR_MINUS) + { + if (recno == 0) + { + *errorcodeptr = ERR58; + goto FAILED; + } + recno = (int)(cb->bracount + 1) - recno; + if (recno <= 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + } + else if (refsign == CHAR_PLUS) + { + if (recno == 0) + { + *errorcodeptr = ERR58; + goto FAILED; + } + recno += cb->bracount; + } + + if ((uint32_t)recno > cb->final_bracount) + { + *errorcodeptr = ERR15; + goto FAILED; + } + + /* Come here from code above that handles a named recursion. + We insert the number of the called group after OP_RECURSE. At the + end of compiling the pattern is scanned and these numbers are + replaced by offsets within the pattern. It is done like this to avoid + problems with forward references and adjusting offsets when groups + are duplicated and moved (as discovered in previous implementations). + Note that a recursion does not have a set first character (relevant + if it is repeated, because it will then be wrapped with ONCE + brackets). */ + + HANDLE_RECURSION: + previous = code; + *code = OP_RECURSE; + PUT(code, 1, recno); + code += 1 + LINK_SIZE; + groupsetfirstcu = FALSE; + cb->had_recurse = TRUE; + } + + /* Can't determine a first byte now */ + + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + continue; + + + /* ------------------------------------------------------------ */ + default: /* Other characters: check option setting */ + OTHER_CHAR_AFTER_QUERY: + set = unset = 0; + optset = &set; + + while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) + { + switch (*ptr++) + { + case CHAR_MINUS: optset = &unset; break; + + case CHAR_J: /* Record that it changed in the external options */ + *optset |= PCRE2_DUPNAMES; + cb->external_flags |= PCRE2_JCHANGED; + break; + + case CHAR_i: *optset |= PCRE2_CASELESS; break; + case CHAR_m: *optset |= PCRE2_MULTILINE; break; + case CHAR_s: *optset |= PCRE2_DOTALL; break; + case CHAR_x: *optset |= PCRE2_EXTENDED; break; + case CHAR_U: *optset |= PCRE2_UNGREEDY; break; + + default: *errorcodeptr = ERR11; + ptr--; /* Correct the offset */ + goto FAILED; + } + } + + /* Set up the changed option bits, but don't change anything yet. */ + + newoptions = (options | set) & (~unset); + + /* If the options ended with ')' this is not the start of a nested + group with option changes, so the options change at this level. They + must also be passed back for use in subsequent branches. Reset the + greedy defaults and the case value for firstcu and reqcu. */ + + if (*ptr == CHAR_RIGHT_PARENTHESIS) + { + *optionsptr = options = newoptions; + greedy_default = ((newoptions & PCRE2_UNGREEDY) != 0); + greedy_non_default = greedy_default ^ 1; + req_caseopt = ((newoptions & PCRE2_CASELESS) != 0)? REQ_CASELESS:0; + previous = NULL; /* This item can't be repeated */ + continue; /* It is complete */ + } + + /* If the options ended with ':' we are heading into a nested group + with possible change of options. Such groups are non-capturing and are + not assertions of any kind. All we need to do is skip over the ':'; + the newoptions value is handled below. */ + + bravalue = OP_BRA; + ptr++; + } /* End of switch for character following (? */ + } /* End of (? handling */ + + /* Opening parenthesis not followed by '*' or '?'. If PCRE2_NO_AUTO_CAPTURE + is set, all unadorned brackets become non-capturing and behave like (?:...) + brackets. */ + + else if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) + { + bravalue = OP_BRA; + } + + /* Else we have a capturing group. */ + + else + { + NUMBERED_GROUP: + cb->bracount += 1; + PUT2(code, 1+LINK_SIZE, cb->bracount); + skipunits = IMM2_SIZE; + } + + /* Process nested bracketed regex. First check for parentheses nested too + deeply. */ + + if ((cb->parens_depth += 1) > (int)(cb->cx->parens_nest_limit)) + { + *errorcodeptr = ERR19; + goto FAILED; + } + + /* All assertions used not to be repeatable, but this was changed for Perl + compatibility. All kinds can now be repeated except for assertions that are + conditions (Perl also forbids these to be repeated). We copy code into a + non-register variable (tempcode) in order to be able to pass its address + because some compilers complain otherwise. At the start of a conditional + group whose condition is an assertion, cb->iscondassert is set. We unset it + here so as to allow assertions later in the group to be quantified. */ + + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT && + cb->iscondassert) + { + previous = NULL; + cb->iscondassert = FALSE; + } + else + { + previous = code; + } + + *code = bravalue; + tempcode = code; + tempreqvary = cb->req_varyopt; /* Save value before bracket */ + tempbracount = cb->bracount; /* Save value before bracket */ + length_prevgroup = 0; /* Initialize for pre-compile phase */ + + if (!compile_regex( + newoptions, /* The complete new option state */ + &tempcode, /* Where to put code (updated) */ + &ptr, /* Input pointer (updated) */ + errorcodeptr, /* Where to put an error message */ + (bravalue == OP_ASSERTBACK || + bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ + reset_bracount, /* True if (?| group */ + skipunits, /* Skip over bracket number */ + cond_depth + + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ + &subfirstcu, /* For possible first char */ + &subfirstcuflags, + &subreqcu, /* For possible last char */ + &subreqcuflags, + bcptr, /* Current branch chain */ + cb, /* Compile data block */ + (lengthptr == NULL)? NULL : /* Actual compile phase */ + &length_prevgroup /* Pre-compile phase */ + )) + goto FAILED; + + cb->parens_depth -= 1; + + /* If this was an atomic group and there are no capturing groups within it, + generate OP_ONCE_NC instead of OP_ONCE. */ + + if (bravalue == OP_ONCE && cb->bracount <= tempbracount) + *code = OP_ONCE_NC; + + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) + cb->assert_depth -= 1; + + /* At the end of compiling, code is still pointing to the start of the + group, while tempcode has been updated to point past the end of the group. + The pattern pointer (ptr) is on the bracket. + + If this is a conditional bracket, check that there are no more than + two branches in the group, or just one if it's a DEFINE group. We do this + in the real compile phase, not in the pre-pass, where the whole group may + not be available. */ + + if (bravalue == OP_COND && lengthptr == NULL) + { + PCRE2_UCHAR *tc = code; + int condcount = 0; + + do { + condcount++; + tc += GET(tc,1); + } + while (*tc != OP_KET); + + /* A DEFINE group is never obeyed inline (the "condition" is always + false). It must have only one branch. Having checked this, change the + opcode to OP_FALSE. */ + + if (code[LINK_SIZE+1] == OP_DEFINE) + { + if (condcount > 1) + { + *errorcodeptr = ERR54; + goto FAILED; + } + code[LINK_SIZE+1] = OP_FALSE; + bravalue = OP_DEFINE; /* Just a flag to suppress char handling below */ + } + + /* A "normal" conditional group. If there is just one branch, we must not + make use of its firstcu or reqcu, because this is equivalent to an + empty second branch. */ + + else + { + if (condcount > 2) + { + *errorcodeptr = ERR27; + goto FAILED; + } + if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE; + } + } + + /* Error if hit end of pattern */ + + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR14; + goto FAILED; + } + + /* In the pre-compile phase, update the length by the length of the group, + less the brackets at either end. Then reduce the compiled code to just a + set of non-capturing brackets so that it doesn't use much memory if it is + duplicated by a quantifier.*/ + + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; + code++; /* This already contains bravalue */ + PUTINC(code, 0, 1 + LINK_SIZE); + *code++ = OP_KET; + PUTINC(code, 0, 1 + LINK_SIZE); + break; /* No need to waste time with special character handling */ + } + + /* Otherwise update the main code pointer to the end of the group. */ + + code = tempcode; + + /* For a DEFINE group, required and first character settings are not + relevant. */ + + if (bravalue == OP_DEFINE) break; + + /* Handle updating of the required and first characters for other types of + group. Update for normal brackets of all kinds, and conditions with two + branches (see code above). If the bracket is followed by a quantifier with + zero repeat, we have to back off. Hence the definition of zeroreqcu and + zerofirstcu outside the main loop so that they can be accessed for the + back off. */ + + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + groupsetfirstcu = FALSE; + + if (bravalue >= OP_ONCE) + { + /* If we have not yet set a firstcu in this branch, take it from the + subpattern, remembering that it was set here so that a repeat of more + than one can replicate it as reqcu if necessary. If the subpattern has + no firstcu, set "none" for the whole branch. In both cases, a zero + repeat forces firstcu to "none". */ + + if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET) + { + if (subfirstcuflags >= 0) + { + firstcu = subfirstcu; + firstcuflags = subfirstcuflags; + groupsetfirstcu = TRUE; + } + else firstcuflags = REQ_NONE; + zerofirstcuflags = REQ_NONE; + } + + /* If firstcu was previously set, convert the subpattern's firstcu + into reqcu if there wasn't one, using the vary flag that was in + existence beforehand. */ + + else if (subfirstcuflags >= 0 && subreqcuflags < 0) + { + subreqcu = subfirstcu; + subreqcuflags = subfirstcuflags | tempreqvary; + } + + /* If the subpattern set a required byte (or set a first byte that isn't + really the first byte - see above), set it. */ + + if (subreqcuflags >= 0) + { + reqcu = subreqcu; + reqcuflags = subreqcuflags; + } + } + + /* For a forward assertion, we take the reqcu, if set. This can be + helpful if the pattern that follows the assertion doesn't set a different + char. For example, it's useful for /(?=abcde).+/. We can't set firstcu + for an assertion, however because it leads to incorrect effect for patterns + such as /(?=a)a.+/ when the "real" "a" would then become a reqcu instead + of a firstcu. This is overcome by a scan at the end if there's no + firstcu, looking for an asserted first char. */ + + else if (bravalue == OP_ASSERT && subreqcuflags >= 0) + { + reqcu = subreqcu; + reqcuflags = subreqcuflags; + } + break; /* End of processing '(' */ + + + /* ===================================================================*/ + /* Handle metasequences introduced by \. For ones like \d, the ESC_ values + are arranged to be the negation of the corresponding OP_values in the + default case when PCRE2_UCP is not set. For the back references, the values + are negative the reference number. Only back references and those types + that consume a character may be repeated. We can test for values between + ESC_b and ESC_Z for the latter; this may have to change if any new ones are + ever created. + + Note: \Q and \E are handled at the start of the character-processing loop, + not here. */ + + case CHAR_BACKSLASH: + tempptr = ptr; + escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr, + options, FALSE, cb); + if (*errorcodeptr != 0) goto FAILED; + + if (escape == 0) /* The escape coded a single character */ + c = ec; + else + { + /* For metasequences that actually match a character, we disable the + setting of a first character if it hasn't already been set. */ + + if (firstcuflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z) + firstcuflags = REQ_NONE; + + /* Set values to reset to if this is followed by a zero repeat. */ + + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + + /* \g or \g'name' is a subroutine call by name and \g or \g'n' + is a subroutine call by number (Oniguruma syntax). In fact, the value + ESC_g is returned only for these cases. So we don't need to check for < + or ' if the value is ESC_g. For the Perl syntax \g{n} the value is + -n, and for the Perl syntax \g{name} the result is ESC_k (as + that is a synonym for a named back reference). */ + + if (escape == ESC_g) + { + PCRE2_SPTR p; + uint32_t cf; + + terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? + CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; + + /* These two statements stop the compiler for warning about possibly + unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In + fact, because we do the check for a number below, the paths that + would actually be in error are never taken. */ + + skipunits = 0; + reset_bracount = FALSE; + + /* If it's not a signed or unsigned number, treat it as a name. */ + + cf = ptr[1]; + if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf)) + { + is_recurse = TRUE; + goto NAMED_REF_OR_RECURSE; + } + + /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus + or a digit. */ + + p = ptr + 2; + while (IS_DIGIT(*p)) p++; + if (*p != (PCRE2_UCHAR)terminator) + { + *errorcodeptr = ERR57; + goto FAILED; + } + ptr++; + goto HANDLE_NUMERICAL_RECURSION; + } + + /* \k or \k'name' is a back reference by name (Perl syntax). + We also support \k{name} (.NET syntax). */ + + if (escape == ESC_k) + { + if ((ptr[1] != CHAR_LESS_THAN_SIGN && + ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) + { + *errorcodeptr = ERR69; + goto FAILED; + } + is_recurse = FALSE; + terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? + CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)? + CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET; + goto NAMED_REF_OR_RECURSE; + } + + /* Back references are handled specially; must disable firstcu if + not set to cope with cases like (?=(\w+))\1: which would otherwise set + ':' later. */ + + if (escape < 0) + { + open_capitem *oc; + recno = -escape; + + /* Come here from named backref handling when the reference is to a + single group (i.e. not to a duplicated name). */ + + HANDLE_REFERENCE: + if (recno > (int)cb->final_bracount) + { + *errorcodeptr = ERR15; + goto FAILED; + } + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + previous = code; + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF; + PUT2INC(code, 0, recno); + cb->backref_map |= (recno < 32)? (1u << recno) : 1; + if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; + + /* Check to see if this back reference is recursive, that it, it + is inside the group that it references. A flag is set so that the + group can be made atomic. */ + + for (oc = cb->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; + break; + } + } + } + + /* So are Unicode property matches, if supported. */ + +#ifdef SUPPORT_UNICODE + else if (escape == ESC_P || escape == ESC_p) + { + BOOL negated; + unsigned int ptype = 0, pdata = 0; + if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb)) + goto FAILED; + previous = code; + *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP; + *code++ = ptype; + *code++ = pdata; + } +#else + + /* If Unicode properties are not supported, \X, \P, and \p are not + allowed. */ + + else if (escape == ESC_X || escape == ESC_P || escape == ESC_p) + { + *errorcodeptr = ERR45; + goto FAILED; + } +#endif + + /* The use of \C can be locked out. */ + +#ifdef NEVER_BACKSLASH_C + else if (escape == ESC_C) + { + *errorcodeptr = ERR85; + goto FAILED; + } +#else + else if (escape == ESC_C && (options & PCRE2_NEVER_BACKSLASH_C) != 0) + { + *errorcodeptr = ERR83; + goto FAILED; + } +#endif + + /* For the rest (including \X when Unicode properties are supported), we + can obtain the OP value by negating the escape value in the default + situation when PCRE2_UCP is not set. When it *is* set, we substitute + Unicode property tests. Note that \b and \B do a one-character + lookbehind, and \A also behaves as if it does. */ + + else + { + if (escape == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */ + if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) && + cb->max_lookbehind == 0) + cb->max_lookbehind = 1; +#ifdef SUPPORT_UNICODE + if (escape >= ESC_DU && escape <= ESC_wu) + { + cb->nestptr[1] = cb->nestptr[0]; /* Back up if at 2nd level */ + cb->nestptr[0] = ptr + 1; /* Where to resume */ + ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + } + else +#endif + /* In non-UTF mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE + so that it works in DFA mode and in lookbehinds. */ + + { + previous = (escape > ESC_b && escape < ESC_Z)? code : NULL; + *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; + } + } + continue; + } + + /* We have a data character whose value is in c. In UTF-8 mode it may have + a value > 127. We set its representation in the length/buffer, and then + handle it as a data character. */ + + mclength = PUTCHAR(c, mcbuffer); + goto ONE_CHAR; + + + /* ===================================================================*/ + /* Handle a literal character. It is guaranteed not to be whitespace or # + when the extended flag is set. If we are in a UTF mode, it may be a + multi-unit literal character. */ + + default: + NORMAL_CHAR: + mclength = 1; + mcbuffer[0] = c; + +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(c)) + ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr)); +#endif + + /* At this point we have the character's bytes in mcbuffer, and the length + in mclength. When not in UTF mode, the length is always 1. */ + + ONE_CHAR: + previous = code; + + /* For caseless UTF mode, check whether this character has more than one + other case. If so, generate a special OP_PROP item instead of OP_CHARI. */ + +#ifdef SUPPORT_UNICODE + if (utf && (options & PCRE2_CASELESS) != 0) + { + GETCHAR(c, mcbuffer); + if ((c = UCD_CASESET(c)) != 0) + { + *code++ = OP_PROP; + *code++ = PT_CLIST; + *code++ = c; + if (firstcuflags == REQ_UNSET) + firstcuflags = zerofirstcuflags = REQ_NONE; + break; + } + } +#endif + + /* Caseful matches, or not one of the multicase characters. */ + + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR; + for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; + + /* Remember if \r or \n were seen */ + + if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL) + cb->external_flags |= PCRE2_HASCRORLF; + + /* Set the first and required bytes appropriately. If no previous first + byte, set it from this character, but revert to none on a zero repeat. + Otherwise, leave the firstcu value alone, and don't change it on a zero + repeat. */ + + if (firstcuflags == REQ_UNSET) + { + zerofirstcuflags = REQ_NONE; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + + /* If the character is more than one byte long, we can set firstcu + only if it is not to be matched caselessly. */ + + if (mclength == 1 || req_caseopt == 0) + { + firstcu = mcbuffer[0] | req_caseopt; + firstcu = mcbuffer[0]; + firstcuflags = req_caseopt; + + if (mclength != 1) + { + reqcu = code[-1]; + reqcuflags = cb->req_varyopt; + } + } + else firstcuflags = reqcuflags = REQ_NONE; + } + + /* firstcu was previously set; we can set reqcu only if the length is + 1 or the matching is caseful. */ + + else + { + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + if (mclength == 1 || req_caseopt == 0) + { + reqcu = code[-1]; + reqcuflags = req_caseopt | cb->req_varyopt; + } + } + + break; /* End of literal character handling */ + } + } /* end of big loop */ + +/* Control never reaches here by falling through, only by a goto for all the +error states. Pass back the position in the pattern so that it can be displayed +to the user for diagnosing the error. */ + +FAILED: +*ptrptr = ptr; +return FALSE; +} + + + +/************************************************* +* Compile regex: a sequence of alternatives * +*************************************************/ + +/* On entry, ptr is pointing past the bracket character, but on return it +points to the closing bracket, or vertical bar, or end of string. The code +variable is pointing at the byte into which the BRA operator has been stored. +This function is used during the pre-compile phase when we are trying to find +out the amount of memory needed, as well as during the real compile phase. The +value of lengthptr distinguishes the two phases. + +Arguments: + options option bits, including any changes for this subpattern + codeptr -> the address of the current code pointer + ptrptr -> the address of the current pattern pointer + errorcodeptr -> pointer to error code variable + lookbehind TRUE if this is a lookbehind assertion + reset_bracount TRUE to reset the count for each branch + skipunits skip this many code units at start (for brackets and OP_COND) + cond_depth depth of nesting for conditional subpatterns + firstcuptr place to put the first required code unit + firstcuflagsptr place to put the first code unit flags, or a negative number + reqcuptr place to put the last required code unit + reqcuflagsptr place to put the last required code unit flags, or a negative number + bcptr pointer to the chain of currently open branches + cb points to the data block with tables pointers etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase + +Returns: TRUE on success +*/ + +static BOOL +compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, PCRE2_SPTR *ptrptr, + int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, uint32_t skipunits, + int cond_depth, uint32_t *firstcuptr, int32_t *firstcuflagsptr, + uint32_t *reqcuptr, int32_t *reqcuflagsptr, branch_chain *bcptr, + compile_block *cb, size_t *lengthptr) +{ +PCRE2_SPTR ptr = *ptrptr; +PCRE2_UCHAR *code = *codeptr; +PCRE2_UCHAR *last_branch = code; +PCRE2_UCHAR *start_bracket = code; +PCRE2_UCHAR *reverse_count = NULL; +open_capitem capitem; +int capnumber = 0; +uint32_t firstcu, reqcu; +int32_t firstcuflags, reqcuflags; +uint32_t branchfirstcu, branchreqcu; +int32_t branchfirstcuflags, branchreqcuflags; +size_t length; +unsigned int orig_bracount; +unsigned int max_bracount; +branch_chain bc; + +/* If set, call the external function that checks for stack availability. */ + +if (cb->cx->stack_guard != NULL && + cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data)) + { + *errorcodeptr= ERR33; + return FALSE; + } + +/* Miscellaneous initialization */ + +bc.outer = bcptr; +bc.current_branch = code; + +firstcu = reqcu = 0; +firstcuflags = reqcuflags = REQ_UNSET; + +/* Accumulate the length for use in the pre-compile phase. Start with the +length of the BRA and KET and any extra code units that are required at the +beginning. We accumulate in a local variable to save frequent testing of +lengthptr for NULL. We cannot do this by looking at the value of 'code' at the +start and end of each alternative, because compiled items are discarded during +the pre-compile phase so that the work space is not exceeded. */ + +length = 2 + 2*LINK_SIZE + skipunits; + +/* WARNING: If the above line is changed for any reason, you must also change +the code that abstracts option settings at the start of the pattern and makes +them global. It tests the value of length for (2 + 2*LINK_SIZE) in the +pre-compile phase to find out whether or not anything has yet been compiled. + +If this is a capturing subpattern, add to the chain of open capturing items +so that we can detect them if (*ACCEPT) is encountered. This is also used to +detect groups that contain recursive back references to themselves. Note that +only OP_CBRA need be tested here; changing this opcode to one of its variants, +e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */ + +if (*code == OP_CBRA) + { + capnumber = GET2(code, 1 + LINK_SIZE); + capitem.number = capnumber; + capitem.next = cb->open_caps; + capitem.flag = FALSE; + cb->open_caps = &capitem; + } + +/* Offset is set zero to mark that this bracket is still open */ + +PUT(code, 1, 0); +code += 1 + LINK_SIZE + skipunits; + +/* Loop for each alternative branch */ + +orig_bracount = max_bracount = cb->bracount; + +for (;;) + { + /* For a (?| group, reset the capturing bracket count so that each branch + uses the same numbers. */ + + if (reset_bracount) cb->bracount = orig_bracount; + + /* Set up dummy OP_REVERSE if lookbehind assertion */ + + if (lookbehind) + { + *code++ = OP_REVERSE; + reverse_count = code; + PUTINC(code, 0, 0); + length += 1 + LINK_SIZE; + } + + /* Now compile the branch; in the pre-compile phase its length gets added + into the length. */ + + if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstcu, + &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc, + cond_depth, cb, (lengthptr == NULL)? NULL : &length)) + { + *ptrptr = ptr; + return FALSE; + } + + /* Keep the highest bracket count in case (?| was used and some branch + has fewer than the rest. */ + + if (cb->bracount > max_bracount) max_bracount = cb->bracount; + + /* In the real compile phase, there is some post-processing to be done. */ + + if (lengthptr == NULL) + { + /* If this is the first branch, the firstcu and reqcu values for the + branch become the values for the regex. */ + + if (*last_branch != OP_ALT) + { + firstcu = branchfirstcu; + firstcuflags = branchfirstcuflags; + reqcu = branchreqcu; + reqcuflags = branchreqcuflags; + } + + /* If this is not the first branch, the first char and reqcu have to + match the values from all the previous branches, except that if the + previous value for reqcu didn't have REQ_VARY set, it can still match, + and we set REQ_VARY for the regex. */ + + else + { + /* If we previously had a firstcu, but it doesn't match the new branch, + we have to abandon the firstcu for the regex, but if there was + previously no reqcu, it takes on the value of the old firstcu. */ + + if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu) + { + if (firstcuflags >= 0) + { + if (reqcuflags < 0) + { + reqcu = firstcu; + reqcuflags = firstcuflags; + } + } + firstcuflags = REQ_NONE; + } + + /* If we (now or from before) have no firstcu, a firstcu from the + branch becomes a reqcu if there isn't a branch reqcu. */ + + if (firstcuflags < 0 && branchfirstcuflags >= 0 && + branchreqcuflags < 0) + { + branchreqcu = branchfirstcu; + branchreqcuflags = branchfirstcuflags; + } + + /* Now ensure that the reqcus match */ + + if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) || + reqcu != branchreqcu) + reqcuflags = REQ_NONE; + else + { + reqcu = branchreqcu; + reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */ + } + } + + /* If lookbehind, check that this branch matches a fixed-length string, and + put the length into the OP_REVERSE item. Temporarily mark the end of the + branch with OP_END. If the branch contains OP_RECURSE, the result is + FFL_LATER (a negative value) because there may be forward references that + we can't check here. Set a flag to cause another lookbehind check at the + end. Why not do it all at the end? Because common errors can be picked up + here and the offset of the problem can be shown. */ + + if (lookbehind) + { + int fixed_length; + int count = 0; + *code = OP_END; + fixed_length = find_fixedlength(last_branch, (options & PCRE2_UTF) != 0, + FALSE, cb, NULL, &count); + if (fixed_length == FFL_LATER) + { + cb->check_lookbehind = TRUE; + } + else if (fixed_length < 0) + { + *errorcodeptr = fixed_length_errors[-fixed_length]; + *ptrptr = ptr; + return FALSE; + } + else + { + if (fixed_length > cb->max_lookbehind) + cb->max_lookbehind = fixed_length; + PUT(reverse_count, 0, fixed_length); + } + } + } + + /* Reached end of expression, either ')' or end of pattern. In the real + compile phase, go back through the alternative branches and reverse the chain + of offsets, with the field in the BRA item now becoming an offset to the + first alternative. If there are no alternatives, it points to the end of the + group. The length in the terminating ket is always the length of the whole + bracketed item. Return leaving the pointer at the terminating char. */ + + if (*ptr != CHAR_VERTICAL_LINE) + { + if (lengthptr == NULL) + { + size_t branch_length = code - last_branch; + do + { + size_t prev_length = GET(last_branch, 1); + PUT(last_branch, 1, branch_length); + branch_length = prev_length; + last_branch -= branch_length; + } + while (branch_length > 0); + } + + /* Fill in the ket */ + + *code = OP_KET; + PUT(code, 1, (int)(code - start_bracket)); + code += 1 + LINK_SIZE; + + /* If it was a capturing subpattern, check to see if it contained any + recursive back references. If so, we must wrap it in atomic brackets. In + any event, remove the block from the chain. */ + + if (capnumber > 0) + { + if (cb->open_caps->flag) + { + memmove(start_bracket + 1 + LINK_SIZE, start_bracket, + CU2BYTES(code - start_bracket)); + *start_bracket = OP_ONCE; + code += 1 + LINK_SIZE; + PUT(start_bracket, 1, (int)(code - start_bracket)); + *code = OP_KET; + PUT(code, 1, (int)(code - start_bracket)); + code += 1 + LINK_SIZE; + length += 2 + 2*LINK_SIZE; + } + cb->open_caps = cb->open_caps->next; + } + + /* Retain the highest bracket number, in case resetting was used. */ + + cb->bracount = max_bracount; + + /* Set values to pass back */ + + *codeptr = code; + *ptrptr = ptr; + *firstcuptr = firstcu; + *firstcuflagsptr = firstcuflags; + *reqcuptr = reqcu; + *reqcuflagsptr = reqcuflags; + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < length) + { + *errorcodeptr = ERR20; + return FALSE; + } + *lengthptr += length; + } + return TRUE; + } + + /* Another branch follows. In the pre-compile phase, we can move the code + pointer back to where it was for the start of the first branch. (That is, + pretend that each branch is the only one.) + + In the real compile phase, insert an ALT node. Its length field points back + to the previous branch while the bracket remains open. At the end the chain + is reversed. It's done like this so that the start of the bracket has a + zero offset until it is closed, making it possible to detect recursion. */ + + if (lengthptr != NULL) + { + code = *codeptr + 1 + LINK_SIZE + skipunits; + length += 1 + LINK_SIZE; + } + else + { + *code = OP_ALT; + PUT(code, 1, (int)(code - last_branch)); + bc.current_branch = last_branch = code; + code += 1 + LINK_SIZE; + } + + /* Advance past the vertical bar */ + + ptr++; + } +/* Control never reaches here */ +} + + + +/************************************************* +* Check for anchored pattern * +*************************************************/ + +/* Try to find out if this is an anchored regular expression. Consider each +alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket +all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then +it's anchored. However, if this is a multiline pattern, then only OP_SOD will +be found, because ^ generates OP_CIRCM in that mode. + +We can also consider a regex to be anchored if OP_SOM starts all its branches. +This is the code for \G, which means "match at start of match position, taking +into account the match offset". + +A branch is also implicitly anchored if it starts with .* and DOTALL is set, +because that will try the rest of the pattern at all possible matching points, +so there is no point trying again.... er .... + +.... except when the .* appears inside capturing parentheses, and there is a +subsequent back reference to those parentheses. We haven't enough information +to catch that case precisely. + +At first, the best we could do was to detect when .* was in capturing brackets +and the highest back reference was greater than or equal to that level. +However, by keeping a bitmap of the first 31 back references, we can catch some +of the more common cases more precisely. + +... A second exception is when the .* appears inside an atomic group, because +this prevents the number of characters it matches from being adjusted. + +Arguments: + code points to start of the compiled pattern + bracket_map a bitmap of which brackets we are inside while testing; this + handles up to substring 31; after that we just have to take + the less precise approach + cb points to the compile data block + atomcount atomic group level + +Returns: TRUE or FALSE +*/ + +static BOOL +is_anchored(register PCRE2_SPTR code, unsigned int bracket_map, + compile_block *cb, int atomcount) +{ +do { + PCRE2_SPTR scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); + register int op = *scode; + + /* Non-capturing brackets */ + + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) + { + if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE; + } + + /* Capturing brackets */ + + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) + { + int n = GET2(scode, 1+LINK_SIZE); + int new_map = bracket_map | ((n < 32)? (1u << n) : 1); + if (!is_anchored(scode, new_map, cb, atomcount)) return FALSE; + } + + /* Positive forward assertions and conditions */ + + else if (op == OP_ASSERT || op == OP_COND) + { + if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE; + } + + /* Atomic groups */ + + else if (op == OP_ONCE || op == OP_ONCE_NC) + { + if (!is_anchored(scode, bracket_map, cb, atomcount + 1)) + return FALSE; + } + + /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and + it isn't in brackets that are or may be referenced or inside an atomic + group. There is also an option that disables auto-anchoring. */ + + else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || + op == OP_TYPEPOSSTAR)) + { + if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 || + atomcount > 0 || cb->had_pruneorskip || + (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) + return FALSE; + } + + /* Check for explicit anchoring */ + + else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; + + code += GET(code, 1); + } +while (*code == OP_ALT); /* Loop for each alternative */ +return TRUE; +} + + + +/************************************************* +* Check for starting with ^ or .* * +*************************************************/ + +/* This is called to find out if every branch starts with ^ or .* so that +"first char" processing can be done to speed things up in multiline +matching and for non-DOTALL patterns that start with .* (which must start at +the beginning or after \n). As in the case of is_anchored() (see above), we +have to take account of back references to capturing brackets that contain .* +because in that case we can't make the assumption. Also, the appearance of .* +inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not +count, because once again the assumption no longer holds. + +Arguments: + code points to start of the compiled pattern or a group + bracket_map a bitmap of which brackets we are inside while testing; this + handles up to substring 31; after that we just have to take + the less precise approach + cb points to the compile data + atomcount atomic group level + +Returns: TRUE or FALSE +*/ + +static BOOL +is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb, + int atomcount) +{ +do { + PCRE2_SPTR scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); + register int op = *scode; + + /* If we are at the start of a conditional assertion group, *both* the + conditional assertion *and* what follows the condition must satisfy the test + for start of line. Other kinds of condition fail. Note that there may be an + auto-callout at the start of a condition. */ + + if (op == OP_COND) + { + scode += 1 + LINK_SIZE; + + if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; + else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE); + + switch (*scode) + { + case OP_CREF: + case OP_DNCREF: + case OP_RREF: + case OP_DNRREF: + case OP_FAIL: + case OP_FALSE: + case OP_TRUE: + return FALSE; + + default: /* Assertion */ + if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; + do scode += GET(scode, 1); while (*scode == OP_ALT); + scode += 1 + LINK_SIZE; + break; + } + scode = first_significant_code(scode, FALSE); + op = *scode; + } + + /* Non-capturing brackets */ + + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) + { + if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; + } + + /* Capturing brackets */ + + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) + { + int n = GET2(scode, 1+LINK_SIZE); + int new_map = bracket_map | ((n < 32)? (1u << n) : 1); + if (!is_startline(scode, new_map, cb, atomcount)) return FALSE; + } + + /* Positive forward assertions */ + + else if (op == OP_ASSERT) + { + if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; + } + + /* Atomic brackets */ + + else if (op == OP_ONCE || op == OP_ONCE_NC) + { + if (!is_startline(scode, bracket_map, cb, atomcount + 1)) return FALSE; + } + + /* .* means "start at start or after \n" if it isn't in atomic brackets or + brackets that may be referenced, as long as the pattern does not contain + *PRUNE or *SKIP, because these break the feature. Consider, for example, + /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the + start of a line. There is also an option that disables this optimization. */ + + else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) + { + if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 || + atomcount > 0 || cb->had_pruneorskip || + (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) + return FALSE; + } + + /* Check for explicit circumflex; anything else gives a FALSE result. Note + in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC + because the number of characters matched by .* cannot be adjusted inside + them. */ + + else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; + + /* Move on to the next alternative */ + + code += GET(code, 1); + } +while (*code == OP_ALT); /* Loop for each alternative */ +return TRUE; +} + + + +/************************************************* +* Check for asserted fixed first code unit * +*************************************************/ + +/* During compilation, the "first code unit" settings from forward assertions +are discarded, because they can cause conflicts with actual literals that +follow. However, if we end up without a first code unit setting for an +unanchored pattern, it is worth scanning the regex to see if there is an +initial asserted first code unit. If all branches start with the same asserted +code unit, or with a non-conditional bracket all of whose alternatives start +with the same asserted code unit (recurse ad lib), then we return that code +unit, with the flags set to zero or REQ_CASELESS; otherwise return zero with +REQ_NONE in the flags. + +Arguments: + code points to start of compiled pattern + flags points to the first code unit flags + inassert TRUE if in an assertion + +Returns: the fixed first code unit, or 0 with REQ_NONE in flags +*/ + +static uint32_t +find_firstassertedcu(PCRE2_SPTR code, int32_t *flags, BOOL inassert) +{ +register uint32_t c = 0; +int cflags = REQ_NONE; + +*flags = REQ_NONE; +do { + uint32_t d; + int dflags; + int xl = (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; + PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE); + register PCRE2_UCHAR op = *scode; + + switch(op) + { + default: + return 0; + + case OP_BRA: + case OP_BRAPOS: + case OP_CBRA: + case OP_SCBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_ASSERT: + case OP_ONCE: + case OP_ONCE_NC: + d = find_firstassertedcu(scode, &dflags, op == OP_ASSERT); + if (dflags < 0) + return 0; + if (cflags < 0) { c = d; cflags = dflags; } + else if (c != d || cflags != dflags) return 0; + break; + + case OP_EXACT: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + if (!inassert) return 0; + if (cflags < 0) { c = scode[1]; cflags = 0; } + else if (c != scode[1]) return 0; + break; + + case OP_EXACTI: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + if (!inassert) return 0; + if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; } + else if (c != scode[1]) return 0; + break; + } + + code += GET(code, 1); + } +while (*code == OP_ALT); + +*flags = cflags; +return c; +} + + + +/************************************************* +* Add an entry to the name/number table * +*************************************************/ + +/* This function is called between compiling passes to add an entry to the +name/number table, maintaining alphabetical order. Checking for permitted +and forbidden duplicates has already been done. + +Arguments: + cb the compile data block + name the name to add + length the length of the name + groupno the group number + +Returns: nothing +*/ + +static void +add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length, + unsigned int groupno) +{ +int i; +PCRE2_UCHAR *slot = cb->name_table; + +for (i = 0; i < cb->names_found; i++) + { + int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length)); + if (crc == 0 && slot[IMM2_SIZE+length] != 0) + crc = -1; /* Current name is a substring */ + + /* Make space in the table and break the loop for an earlier name. For a + duplicate or later name, carry on. We do this for duplicates so that in the + simple case (when ?(| is not used) they are in order of their numbers. In all + cases they are in the order in which they appear in the pattern. */ + + if (crc < 0) + { + memmove(slot + cb->name_entry_size, slot, + CU2BYTES((cb->names_found - i) * cb->name_entry_size)); + break; + } + + /* Continue the loop for a later or duplicate name */ + + slot += cb->name_entry_size; + } + +PUT2(slot, 0, groupno); +memcpy(slot + IMM2_SIZE, name, CU2BYTES(length)); +cb->names_found++; + +/* Add a terminating zero and fill the rest of the slot with zeroes so that +the memory is all initialized. Otherwise valgrind moans about uninitialized +memory when saving serialized compiled patterns. */ + +memset(slot + IMM2_SIZE + length, 0, + CU2BYTES(cb->name_entry_size - length - IMM2_SIZE)); +} + + + +/************************************************* +* External function to compile a pattern * +*************************************************/ + +/* This function reads a regular expression in the form of a string and returns +a pointer to a block of store holding a compiled version of the expression. + +Arguments: + pattern the regular expression + patlen the length of the pattern, or PCRE2_ZERO_TERMINATED + options option bits + errorptr pointer to errorcode + erroroffset pointer to error offset + ccontext points to a compile context or is NULL + +Returns: pointer to compiled data block, or NULL on error, + with errorcode and erroroffset set +*/ + +PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION +pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options, + int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext) +{ +BOOL utf; /* Set TRUE for UTF mode */ +pcre2_real_code *re = NULL; /* What we will return */ +compile_block cb; /* "Static" compile-time data */ +const uint8_t *tables; /* Char tables base pointer */ + +PCRE2_UCHAR *code; /* Current pointer in compiled code */ +PCRE2_SPTR codestart; /* Start of compiled code */ +PCRE2_SPTR ptr; /* Current pointer in pattern */ + +size_t length = 1; /* Allow or final END opcode */ +size_t usedlength; /* Actual length used */ +size_t re_blocksize; /* Size of memory block */ + +int32_t firstcuflags, reqcuflags; /* Type of first/req code unit */ +uint32_t firstcu, reqcu; /* Value of first/req code unit */ +uint32_t setflags = 0; /* NL and BSR set flags */ + +uint32_t skipatstart; /* When checking (*UTF) etc */ +uint32_t limit_match = UINT32_MAX; /* Unset match limits */ +uint32_t limit_recursion = UINT32_MAX; + +int newline = 0; /* Unset; can be set by the pattern */ +int bsr = 0; /* Unset; can be set by the pattern */ +int errorcode = 0; /* Initialize to avoid compiler warn */ + +/* Comments at the head of this file explain about these variables. */ + +PCRE2_UCHAR *copied_pattern = NULL; +PCRE2_UCHAR stack_copied_pattern[COPIED_PATTERN_SIZE]; +named_group named_groups[NAMED_GROUP_LIST_SIZE]; + +/* The workspace is used in different ways in the different compiling phases. +It needs to be 16-bit aligned for the preliminary group scan, and 32-bit +aligned for the group information cache. */ + +uint32_t c32workspace[C32_WORK_SIZE]; +PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c32workspace; + + +/* -------------- Check arguments and set up the pattern ----------------- */ + +/* There must be error code and offset pointers. */ + +if (errorptr == NULL || erroroffset == NULL) return NULL; +*errorptr = ERR0; +*erroroffset = 0; + +/* There must be a pattern! */ + +if (pattern == NULL) + { + *errorptr = ERR16; + return NULL; + } + +/* Check that all undefined public option bits are zero. */ + +if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0) + { + *errorptr = ERR17; + return NULL; + } + +/* A NULL compile context means "use a default context" */ + +if (ccontext == NULL) + ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context)); + +/* A zero-terminated pattern is indicated by the special length value +PCRE2_ZERO_TERMINATED. Otherwise, we make a copy of the pattern and add a zero, +to ensure that it is always possible to look one code unit beyond the end of +the pattern's characters. In both cases, check that the pattern is overlong. */ + +if (patlen == PCRE2_ZERO_TERMINATED) + { + patlen = PRIV(strlen)(pattern); + if (patlen > ccontext->max_pattern_length) + { + *errorptr = ERR88; + return NULL; + } + } +else + { + if (patlen > ccontext->max_pattern_length) + { + *errorptr = ERR88; + return NULL; + } + if (patlen < COPIED_PATTERN_SIZE) + copied_pattern = stack_copied_pattern; + else + { + copied_pattern = ccontext->memctl.malloc(CU2BYTES(patlen + 1), + ccontext->memctl.memory_data); + if (copied_pattern == NULL) + { + *errorptr = ERR21; + return NULL; + } + } + memcpy(copied_pattern, pattern, CU2BYTES(patlen)); + copied_pattern[patlen] = 0; + pattern = copied_pattern; + } + +/* ------------ Initialize the "static" compile data -------------- */ + +tables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables); + +cb.lcc = tables + lcc_offset; /* Individual */ +cb.fcc = tables + fcc_offset; /* character */ +cb.cbits = tables + cbits_offset; /* tables */ +cb.ctypes = tables + ctypes_offset; + +cb.assert_depth = 0; +cb.bracount = cb.final_bracount = 0; +cb.cx = ccontext; +cb.dupnames = FALSE; +cb.end_pattern = pattern + patlen; +cb.nestptr[0] = cb.nestptr[1] = NULL; +cb.external_flags = 0; +cb.external_options = options; +cb.groupinfo = c32workspace; +cb.had_recurse = FALSE; +cb.iscondassert = FALSE; +cb.max_lookbehind = 0; +cb.name_entry_size = 0; +cb.name_table = NULL; +cb.named_groups = named_groups; +cb.named_group_list_size = NAMED_GROUP_LIST_SIZE; +cb.names_found = 0; +cb.open_caps = NULL; +cb.parens_depth = 0; +cb.req_varyopt = 0; +cb.start_code = cworkspace; +cb.start_pattern = pattern; +cb.start_workspace = cworkspace; +cb.workspace_size = COMPILE_WORK_SIZE; + +/* Maximum back reference and backref bitmap. The bitmap records up to 31 back +references to help in deciding whether (.*) can be treated as anchored or not. +*/ + +cb.top_backref = 0; +cb.backref_map = 0; + +/* --------------- Start looking at the pattern --------------- */ + +/* Check for global one-time option settings at the start of the pattern, and +remember the offset to the actual regex. */ + +ptr = pattern; +skipatstart = 0; + +while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && + ptr[skipatstart+1] == CHAR_ASTERISK) + { + unsigned int i; + for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) + { + pso *p = pso_list + i; + + if (PRIV(strncmp_c8)(ptr+skipatstart+2, (char *)(p->name), p->length) == 0) + { + uint32_t c, pp; + + skipatstart += p->length + 2; + switch(p->type) + { + case PSO_OPT: + cb.external_options |= p->value; + break; + + case PSO_FLG: + setflags |= p->value; + break; + + case PSO_NL: + newline = p->value; + setflags |= PCRE2_NL_SET; + break; + + case PSO_BSR: + bsr = p->value; + setflags |= PCRE2_BSR_SET; + break; + + case PSO_LIMM: + case PSO_LIMR: + c = 0; + pp = skipatstart; + if (!IS_DIGIT(ptr[pp])) + { + errorcode = ERR60; + ptr += pp; + goto HAD_ERROR; + } + while (IS_DIGIT(ptr[pp])) + { + if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */ + c = c*10 + (ptr[pp++] - CHAR_0); + } + if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS) + { + errorcode = ERR60; + ptr += pp; + goto HAD_ERROR; + } + if (p->type == PSO_LIMM) limit_match = c; + else limit_recursion = c; + skipatstart += pp - skipatstart; + break; + } + break; /* Out of the table scan loop */ + } + } + if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */ + } + +/* End of pattern-start options; advance to start of real regex. */ + +ptr += skipatstart; + +/* Can't support UTF or UCP unless PCRE2 has been compiled with UTF support. */ + +#ifndef SUPPORT_UNICODE +if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0) + { + errorcode = ERR32; + goto HAD_ERROR; + } +#endif + +/* Check UTF. We have the original options in 'options', with that value as +modified by (*UTF) etc in cb->external_options. */ + +utf = (cb.external_options & PCRE2_UTF) != 0; +if (utf) + { + if ((options & PCRE2_NEVER_UTF) != 0) + { + errorcode = ERR74; + goto HAD_ERROR; + } + if ((options & PCRE2_NO_UTF_CHECK) == 0 && + (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0) + goto HAD_UTF_ERROR; + } + +/* Check UCP lockout. */ + +if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) == + (PCRE2_UCP|PCRE2_NEVER_UCP)) + { + errorcode = ERR75; + goto HAD_ERROR; + } + +/* Process the BSR setting. */ + +if (bsr == 0) bsr = ccontext->bsr_convention; + +/* Process the newline setting. */ + +if (newline == 0) newline = ccontext->newline_convention; +cb.nltype = NLTYPE_FIXED; +switch(newline) + { + case PCRE2_NEWLINE_CR: + cb.nllen = 1; + cb.nl[0] = CHAR_CR; + break; + + case PCRE2_NEWLINE_LF: + cb.nllen = 1; + cb.nl[0] = CHAR_NL; + break; + + case PCRE2_NEWLINE_CRLF: + cb.nllen = 2; + cb.nl[0] = CHAR_CR; + cb.nl[1] = CHAR_NL; + break; + + case PCRE2_NEWLINE_ANY: + cb.nltype = NLTYPE_ANY; + break; + + case PCRE2_NEWLINE_ANYCRLF: + cb.nltype = NLTYPE_ANYCRLF; + break; + + default: + errorcode = ERR56; + goto HAD_ERROR; + } + +/* Before we do anything else, do a pre-scan of the pattern in order to +discover the named groups and their numerical equivalents, so that this +information is always available for the remaining processing. */ + +errorcode = scan_for_captures(&ptr, cb.external_options, &cb); +if (errorcode != 0) goto HAD_ERROR; + +/* For obscure debugging this code can be enabled. */ + +#if 0 + { + int i; + named_group *ng = cb.named_groups; + fprintf(stderr, "+++Captures: %d\n", cb.final_bracount); + for (i = 0; i < cb.names_found; i++, ng++) + { + fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name); + } + } +#endif + +/* Reset current bracket count to zero and current pointer to the start of the +pattern. */ + +cb.bracount = 0; +ptr = pattern + skipatstart; + +/* Pretend to compile the pattern while actually just accumulating the amount +of memory required in the 'length' variable. This behaviour is triggered by +passing a non-NULL final argument to compile_regex(). We pass a block of +workspace (cworkspace) for it to compile parts of the pattern into; the +compiled code is discarded when it is no longer needed, so hopefully this +workspace will never overflow, though there is a test for its doing so. + +On error, errorcode will be set non-zero, so we don't need to look at the +result of the function. The initial options have been put into the cb block so +that they can be changed if an option setting is found within the regex right +at the beginning. Bringing initial option settings outside can help speed up +starting point checks. We still have to pass a separate options variable (the +first argument) because that may change as the pattern is processed. */ + +code = cworkspace; +*code = OP_BRA; + +(void)compile_regex(cb.external_options, &code, &ptr, &errorcode, FALSE, + FALSE, 0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, + &cb, &length); + +if (errorcode != 0) goto HAD_ERROR; +if (length > MAX_PATTERN_SIZE) + { + errorcode = ERR20; + goto HAD_ERROR; + } + +/* Compute the size of, and then get and initialize, the data block for storing +the compiled pattern and names table. Integer overflow should no longer be +possible because nowadays we limit the maximum value of cb.names_found and +cb.name_entry_size. */ + +re_blocksize = sizeof(pcre2_real_code) + + CU2BYTES(length + cb.names_found * cb.name_entry_size); +re = (pcre2_real_code *) + ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data); +if (re == NULL) + { + errorcode = ERR21; + goto HAD_ERROR; + } + +re->memctl = ccontext->memctl; +re->tables = tables; +re->executable_jit = NULL; +memset(re->start_bitmap, 0, 32 * sizeof(uint8_t)); +re->blocksize = re_blocksize; +re->magic_number = MAGIC_NUMBER; +re->compile_options = options; +re->overall_options = cb.external_options; +re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags; +re->limit_match = limit_match; +re->limit_recursion = limit_recursion; +re->first_codeunit = 0; +re->last_codeunit = 0; +re->bsr_convention = bsr; +re->newline_convention = newline; +re->max_lookbehind = 0; +re->minlength = 0; +re->top_bracket = 0; +re->top_backref = 0; +re->name_entry_size = cb.name_entry_size; +re->name_count = cb.names_found; + +/* The basic block is immediately followed by the name table, and the compiled +code follows after that. */ + +codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_entry_size * re->name_count; + +/* Workspace is needed to remember information about numbered groups: whether a +group can match an empty string and what its fixed length is. This is done to +avoid the possibility of recursive references causing very long compile times +when checking these features. Unnumbered groups do not have this exposure since +they cannot be referenced. We use an indexed vector for this purpose. If there +are sufficiently few groups, it can be the c32workspace vector, as set up +above. Otherwise we have to get/free a special vector. The vector must be +initialized to zero. */ + +if (cb.final_bracount >= C32_WORK_SIZE) + { + cb.groupinfo = ccontext->memctl.malloc( + (cb.final_bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data); + if (cb.groupinfo == NULL) + { + errorcode = ERR21; + goto HAD_ERROR; + } + } +memset(cb.groupinfo, 0, (cb.final_bracount + 1) * sizeof(uint32_t)); + +/* Update the compile data block for the actual compile. The starting points of +the name/number translation table and of the code are passed around in the +compile data block. The start/end pattern and initial options are already set +from the pre-compile phase, as is the name_entry_size field. Reset the bracket +count and the names_found field. */ + +cb.parens_depth = 0; +cb.assert_depth = 0; +cb.bracount = 0; +cb.max_lookbehind = 0; +cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); +cb.start_code = codestart; +cb.iscondassert = FALSE; +cb.req_varyopt = 0; +cb.had_accept = FALSE; +cb.had_pruneorskip = FALSE; +cb.check_lookbehind = FALSE; +cb.open_caps = NULL; + +/* If any named groups were found, create the name/number table from the list +created in the pre-pass. */ + +if (cb.names_found > 0) + { + int i = cb.names_found; + named_group *ng = cb.named_groups; + cb.names_found = 0; + for (; i > 0; i--, ng++) + add_name_to_table(&cb, ng->name, ng->length, ng->number); + } + +/* Set up a starting, non-extracting bracket, then compile the expression. On +error, errorcode will be set non-zero, so we don't need to look at the result +of the function here. */ + +ptr = pattern + skipatstart; +code = (PCRE2_UCHAR *)codestart; +*code = OP_BRA; +(void)compile_regex(re->overall_options, &code, &ptr, &errorcode, FALSE, FALSE, + 0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL); + +re->top_bracket = cb.bracount; +re->top_backref = cb.top_backref; +re->max_lookbehind = cb.max_lookbehind; + +if (cb.had_accept) + { + reqcu = 0; /* Must disable after (*ACCEPT) */ + reqcuflags = REQ_NONE; + } + +/* If we have not reached end of pattern after a successful compile, there's an +excess bracket. Fill in the final opcode and check for disastrous overflow. +If no overflow, but the estimated length exceeds the really used length, adjust +the value of re->blocksize, and if valgrind support is configured, mark the +extra allocated memory as unaddressable, so that any out-of-bound reads can be +detected. */ + +if (errorcode == 0 && ptr < cb.end_pattern) errorcode = ERR22; +*code++ = OP_END; +usedlength = code - codestart; +if (usedlength > length) errorcode = ERR23; else + { + re->blocksize -= CU2BYTES(length - usedlength); +#ifdef SUPPORT_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength)); +#endif + } + +/* Scan the pattern for recursion/subroutine calls and convert the group +numbers into offsets. Maintain a small cache so that repeated groups containing +recursions are efficiently handled. */ + +#define RSCAN_CACHE_SIZE 8 + +if (errorcode == 0 && cb.had_recurse) + { + PCRE2_UCHAR *rcode; + PCRE2_SPTR rgroup; + int ccount = 0; + int start = RSCAN_CACHE_SIZE; + recurse_cache rc[RSCAN_CACHE_SIZE]; + + for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf); + rcode != NULL; + rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf)) + { + int i, p, recno; + + recno = (int)GET(rcode, 1); + if (recno == 0) rgroup = codestart; else + { + PCRE2_SPTR search_from = codestart; + rgroup = NULL; + for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7) + { + if (recno == rc[p].recno) + { + rgroup = rc[p].group; + break; + } + + /* Group n+1 must always start to the right of group n, so we can save + search time below when the new group number is greater than any of the + previously found groups. */ + + if (recno > rc[p].recno) search_from = rc[p].group; + } + + if (rgroup == NULL) + { + rgroup = PRIV(find_bracket)(search_from, utf, recno); + if (rgroup == NULL) + { + errorcode = ERR53; + break; + } + if (--start < 0) start = RSCAN_CACHE_SIZE - 1; + rc[start].recno = recno; + rc[start].group = rgroup; + if (ccount < RSCAN_CACHE_SIZE) ccount++; + } + } + + PUT(rcode, 1, rgroup - codestart); + } + } + +/* In rare debugging situations we sometimes need to look at the compiled code +at this stage. */ + +#ifdef CALL_PRINTINT +pcre2_printint(re, stderr, TRUE); +fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength); +#endif + +/* After a successful compile, give an error if there's back reference to a +non-existent capturing subpattern. Then, unless disabled, check whether any +single character iterators can be auto-possessified. The function overwrites +the appropriate opcode values, so the type of the pointer must be cast. NOTE: +the intermediate variable "temp" is used in this code because at least one +compiler gives a warning about loss of "const" attribute if the cast +(PCRE2_UCHAR *)codestart is used directly in the function call. */ + +if (errorcode == 0) + { + if (re->top_backref > re->top_bracket) errorcode = ERR15; + else if ((re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0) + { + PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart; + if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80; + } + } + +/* If there were any lookbehind assertions that contained OP_RECURSE +(recursions or subroutine calls), a flag is set for them to be checked here, +because they may contain forward references. Actual recursions cannot be fixed +length, but subroutine calls can. It is done like this so that those without +OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The +exceptional ones forgo this. We scan the pattern to check that they are fixed +length, and set their lengths. */ + +if (errorcode == 0 && cb.check_lookbehind) + { + PCRE2_UCHAR *cc = (PCRE2_UCHAR *)codestart; + + /* Loop, searching for OP_REVERSE items, and process those that do not have + their length set. (Actually, it will also re-process any that have a length + of zero, but that is a pathological case, and it does no harm.) When we find + one, we temporarily terminate the branch it is in while we scan it. Note that + calling find_bracket() with a negative group number returns a pointer to the + OP_REVERSE item, not the actual lookbehind. */ + + for (cc = (PCRE2_UCHAR *)PRIV(find_bracket)(codestart, utf, -1); + cc != NULL; + cc = (PCRE2_UCHAR *)PRIV(find_bracket)(cc, utf, -1)) + { + if (GET(cc, 1) == 0) + { + int fixed_length; + int count = 0; + PCRE2_UCHAR *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); + int end_op = *be; + *be = OP_END; + fixed_length = find_fixedlength(cc, utf, TRUE, &cb, NULL, &count); + *be = end_op; + if (fixed_length < 0) + { + errorcode = fixed_length_errors[-fixed_length]; + break; + } + if (fixed_length > cb.max_lookbehind) cb.max_lookbehind = fixed_length; + PUT(cc, 1, fixed_length); + } + cc += 1 + LINK_SIZE; + } + + /* The previous value of the maximum lookbehind was transferred to the + compiled regex block above. We could have updated this value in the loop + above, but keep the two values in step, just in case some later code below + uses the cb value. */ + + re->max_lookbehind = cb.max_lookbehind; + } + +/* Failed to compile, or error while post-processing. Earlier errors get here +via the dreaded goto. */ + +if (errorcode != 0) + { + HAD_ERROR: + *erroroffset = (int)(ptr - pattern); + HAD_UTF_ERROR: + *errorptr = errorcode; + pcre2_code_free(re); + re = NULL; + goto EXIT; + } + +/* Successful compile. If the anchored option was not passed, set it if +we can determine that the pattern is anchored by virtue of ^ characters or \A +or anything else, such as starting with non-atomic .* when DOTALL is set and +there are no occurrences of *PRUNE or *SKIP (though there is an option to +disable this case). */ + +if ((re->overall_options & PCRE2_ANCHORED) == 0 && + is_anchored(codestart, 0, &cb, 0)) + re->overall_options |= PCRE2_ANCHORED; + +/* If the pattern is still not anchored and we do not have a first code unit, +see if there is one that is asserted (these are not saved during the compile +because they can cause conflicts with actual literals that follow). This code +need not be obeyed if PCRE2_NO_START_OPTIMIZE is set, as the data it would +create will not be used. */ + +if ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0) + { + if (firstcuflags < 0) + firstcu = find_firstassertedcu(codestart, &firstcuflags, FALSE); + + /* Save the data for a first code unit. */ + + if (firstcuflags >= 0) + { + re->first_codeunit = firstcu; + re->flags |= PCRE2_FIRSTSET; + + /* Handle caseless first code units. */ + + if ((firstcuflags & REQ_CASELESS) != 0) + { + if (firstcu < 128 || (!utf && firstcu < 255)) + { + if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS; + } + + /* The first code unit is > 128 in UTF mode, or > 255 otherwise. In + 8-bit UTF mode, codepoints in the range 128-255 are introductory code + points and cannot have another case. In 16-bit and 32-bit modes, we can + check wide characters when UTF (and therefore UCP) is supported. */ + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + else if (firstcu <= MAX_UTF_CODE_POINT && + UCD_OTHERCASE(firstcu) != firstcu) + re->flags |= PCRE2_FIRSTCASELESS; +#endif + } + } + + /* When there is no first code unit, see if we can set the PCRE2_STARTLINE + flag. This is helpful for multiline matches when all branches start with ^ + and also when all branches start with non-atomic .* for non-DOTALL matches + when *PRUNE and SKIP are not present. (There is an option that disables this + case.) */ + + else if (is_startline(codestart, 0, &cb, 0)) re->flags |= PCRE2_STARTLINE; + } + +/* Handle the "required code unit", if one is set. In the case of an anchored +pattern, do this only if it follows a variable length item in the pattern. +Again, skip this if PCRE2_NO_START_OPTIMIZE is set. */ + +if (reqcuflags >= 0 && + ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0 || + (reqcuflags & REQ_VARY) != 0)) + { + re->last_codeunit = reqcu; + re->flags |= PCRE2_LASTSET; + + /* Handle caseless required code units as for first code units (above). */ + + if ((reqcuflags & REQ_CASELESS) != 0) + { + if (reqcu < 128 || (!utf && reqcu < 255)) + { + if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS; + } +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu) + re->flags |= PCRE2_LASTCASELESS; +#endif + } + } + +/* Check for a pattern than can match an empty string, so that this information +can be provided to applications. */ + +do + { + int count = 0; + int rc = could_be_empty_branch(codestart, code, utf, &cb, TRUE, NULL, &count); + if (rc < 0) + { + errorcode = ERR86; + goto HAD_ERROR; + } + if (rc > 0) + { + re->flags |= PCRE2_MATCH_EMPTY; + break; + } + codestart += GET(codestart, 1); + } +while (*codestart == OP_ALT); + +/* Finally, unless PCRE2_NO_START_OPTIMIZE is set, study the compiled pattern +to set up information such as a bitmap of starting code units and a minimum +matching length. */ + +if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && + PRIV(study)(re) != 0) + { + errorcode = ERR31; + goto HAD_ERROR; + } + +/* Control ends up here in all cases. If memory was obtained for a +zero-terminated copy of the pattern, remember to free it before returning. Also +free the list of named groups if a larger one had to be obtained, and likewise +the group information vector. */ + +EXIT: +if (copied_pattern != stack_copied_pattern) + ccontext->memctl.free(copied_pattern, ccontext->memctl.memory_data); +if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE) + ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data); +if (cb.groupinfo != c32workspace) + ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data); + +return re; /* Will be NULL after an error */ +} + +/* End of pcre2_compile.c */ diff --git a/pcre2/src/pcre2_config.c b/pcre2/src/pcre2_config.c new file mode 100644 index 000000000..921845949 --- /dev/null +++ b/pcre2/src/pcre2_config.c @@ -0,0 +1,217 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes +its value gets changed by pcre2_internal.h to be in code units. */ + +static int configured_link_size = LINK_SIZE; + +#include "pcre2_internal.h" + +/* These macros are the standard way of turning unquoted text into C strings. +They allow macros like PCRE2_MAJOR to be defined without quotes, which is +convenient for user programs that want to test their values. */ + +#define STRING(a) # a +#define XSTRING(s) STRING(s) + + +/************************************************* +* Return info about what features are configured * +*************************************************/ + +/* +Arguments: + what what information is required + where where to put the information + +Returns: 0 if data returned + >= 0 if where is NULL, giving length required + PCRE2_ERROR_BADOPTION if "where" not recognized + or JIT target requested when JIT not enabled +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_config(uint32_t what, void *where) +{ +if (where == NULL) /* Requests a length */ + { + switch(what) + { + default: + return PCRE2_ERROR_BADOPTION; + + case PCRE2_CONFIG_BSR: + case PCRE2_CONFIG_JIT: + case PCRE2_CONFIG_LINKSIZE: + case PCRE2_CONFIG_MATCHLIMIT: + case PCRE2_CONFIG_NEWLINE: + case PCRE2_CONFIG_PARENSLIMIT: + case PCRE2_CONFIG_RECURSIONLIMIT: + case PCRE2_CONFIG_STACKRECURSE: + case PCRE2_CONFIG_UNICODE: + return sizeof(uint32_t); + + /* These are handled below */ + + case PCRE2_CONFIG_JITTARGET: + case PCRE2_CONFIG_UNICODE_VERSION: + case PCRE2_CONFIG_VERSION: + break; + } + } + +switch (what) + { + default: + return PCRE2_ERROR_BADOPTION; + + case PCRE2_CONFIG_BSR: +#ifdef BSR_ANYCRLF + *((uint32_t *)where) = PCRE2_BSR_ANYCRLF; +#else + *((uint32_t *)where) = PCRE2_BSR_UNICODE; +#endif + break; + + case PCRE2_CONFIG_JIT: +#ifdef SUPPORT_JIT + *((uint32_t *)where) = 1; +#else + *((uint32_t *)where) = 0; +#endif + break; + + case PCRE2_CONFIG_JITTARGET: +#ifdef SUPPORT_JIT + { + const char *v = PRIV(jit_get_target)(); + return 1 + ((where == NULL)? + strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + } +#else + return PCRE2_ERROR_BADOPTION; +#endif + + case PCRE2_CONFIG_LINKSIZE: + *((uint32_t *)where) = configured_link_size; + break; + + case PCRE2_CONFIG_MATCHLIMIT: + *((uint32_t *)where) = MATCH_LIMIT; + break; + + case PCRE2_CONFIG_NEWLINE: + *((uint32_t *)where) = NEWLINE_DEFAULT; + break; + + case PCRE2_CONFIG_PARENSLIMIT: + *((uint32_t *)where) = PARENS_NEST_LIMIT; + break; + + case PCRE2_CONFIG_RECURSIONLIMIT: + *((uint32_t *)where) = MATCH_LIMIT_RECURSION; + break; + + case PCRE2_CONFIG_STACKRECURSE: +#ifdef HEAP_MATCH_RECURSE + *((uint32_t *)where) = 0; +#else + *((uint32_t *)where) = 1; +#endif + break; + + case PCRE2_CONFIG_UNICODE_VERSION: + { +#if defined SUPPORT_UNICODE + const char *v = PRIV(unicode_version); +#else + const char *v = "Unicode not supported"; +#endif + return 1 + ((where == NULL)? + strlen(v): PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + } + break; + + case PCRE2_CONFIG_UNICODE: +#if defined SUPPORT_UNICODE + *((uint32_t *)where) = 1; +#else + *((uint32_t *)where) = 0; +#endif + break; + + /* The hackery in setting "v" below is to cope with the case when + PCRE2_PRERELEASE is set to an empty string (which it is for real releases). + If the second alternative is used in this case, it does not leave a space + before the date. On the other hand, if all four macros are put into a single + XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted. + There are problems using an "obvious" approach like this: + + XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR) + XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE) + + because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion + of STRING(). The C standard states: "If (before argument substitution) any + argument consists of no preprocessing tokens, the behavior is undefined." It + turns out the gcc treats this case as a single empty string - which is what + we really want - but Visual C grumbles about the lack of an argument for the + macro. Unfortunately, both are within their rights. As there seems to be no + way to test for a macro's value being empty at compile time, we have to + resort to a runtime test. */ + + case PCRE2_CONFIG_VERSION: + { + const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)? + XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) : + XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE); + return 1 + ((where == NULL)? + strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + } + } + +return 0; +} + +/* End of pcre2_config.c */ diff --git a/pcre2/src/pcre2_context.c b/pcre2/src/pcre2_context.c new file mode 100644 index 000000000..ae050fe92 --- /dev/null +++ b/pcre2/src/pcre2_context.c @@ -0,0 +1,391 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + + +/************************************************* +* Default malloc/free functions * +*************************************************/ + +/* Ignore the "user data" argument in each case. */ + +static void *default_malloc(size_t size, void *data) +{ +(void)data; +return malloc(size); +} + + +static void default_free(void *block, void *data) +{ +(void)data; +free(block); +} + + + +/************************************************* +* Get a block and save memory control * +*************************************************/ + +/* This internal function is called to get a block of memory in which the +memory control data is to be stored at the start for future use. + +Arguments: + size amount of memory required + memctl pointer to a memctl block or NULL + +Returns: pointer to memory or NULL on failure +*/ + +extern void * +PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl) +{ +pcre2_memctl *newmemctl; +void *yield = (memctl == NULL)? malloc(size) : + memctl->malloc(size, memctl->memory_data); +if (yield == NULL) return NULL; +newmemctl = (pcre2_memctl *)yield; +if (memctl == NULL) + { + newmemctl->malloc = default_malloc; + newmemctl->free = default_free; + newmemctl->memory_data = NULL; + } +else *newmemctl = *memctl; +return yield; +} + + + +/************************************************* +* Create and initialize contexts * +*************************************************/ + +/* Initializing for compile and match contexts is done in separate, private +functions so that these can be called from functions such as pcre2_compile() +when an external context is not supplied. The initializing functions have an +option to set up default memory management. */ + +PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION +pcre2_general_context_create(void *(*private_malloc)(size_t, void *), + void (*private_free)(void *, void *), void *memory_data) +{ +pcre2_general_context *gcontext; +if (private_malloc == NULL) private_malloc = default_malloc; +if (private_free == NULL) private_free = default_free; +gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data); +if (gcontext == NULL) return NULL; +gcontext->memctl.malloc = private_malloc; +gcontext->memctl.free = private_free; +gcontext->memctl.memory_data = memory_data; +return gcontext; +} + + +/* A default compile context is set up to save having to initialize at run time +when no context is supplied to the compile function. */ + +const pcre2_compile_context PRIV(default_compile_context) = { + { default_malloc, default_free, NULL }, /* Default memory handling */ + NULL, /* Stack guard */ + NULL, /* Stack guard data */ + PRIV(default_tables), /* Character tables */ + PCRE2_UNSET, /* Max pattern length */ + BSR_DEFAULT, /* Backslash R default */ + NEWLINE_DEFAULT, /* Newline convention */ + PARENS_NEST_LIMIT }; /* As it says */ + +/* The create function copies the default into the new memory, but must +override the default memory handling functions if a gcontext was provided. */ + +PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION +pcre2_compile_context_create(pcre2_general_context *gcontext) +{ +pcre2_compile_context *ccontext = PRIV(memctl_malloc)( + sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext); +if (ccontext == NULL) return NULL; +*ccontext = PRIV(default_compile_context); +if (gcontext != NULL) + *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext); +return ccontext; +} + + +/* A default match context is set up to save having to initialize at run time +when no context is supplied to a match function. */ + +const pcre2_match_context PRIV(default_match_context) = { + { default_malloc, default_free, NULL }, +#ifdef HEAP_MATCH_RECURSE + { default_malloc, default_free, NULL }, +#endif +#ifdef SUPPORT_JIT + NULL, + NULL, +#endif + NULL, + NULL, + PCRE2_UNSET, /* Offset limit */ + MATCH_LIMIT, + MATCH_LIMIT_RECURSION }; + +/* The create function copies the default into the new memory, but must +override the default memory handling functions if a gcontext was provided. */ + +PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION +pcre2_match_context_create(pcre2_general_context *gcontext) +{ +pcre2_match_context *mcontext = PRIV(memctl_malloc)( + sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext); +if (mcontext == NULL) return NULL; +*mcontext = PRIV(default_match_context); +if (gcontext != NULL) + *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext); +return mcontext; +} + + +/************************************************* +* Context copy functions * +*************************************************/ + +PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION +pcre2_general_context_copy(pcre2_general_context *gcontext) +{ +pcre2_general_context *new = + gcontext->memctl.malloc(sizeof(pcre2_real_general_context), + gcontext->memctl.memory_data); +if (new == NULL) return NULL; +memcpy(new, gcontext, sizeof(pcre2_real_general_context)); +return new; +} + + +PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION +pcre2_compile_context_copy(pcre2_compile_context *ccontext) +{ +pcre2_compile_context *new = + ccontext->memctl.malloc(sizeof(pcre2_real_compile_context), + ccontext->memctl.memory_data); +if (new == NULL) return NULL; +memcpy(new, ccontext, sizeof(pcre2_real_compile_context)); +return new; +} + + +PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION +pcre2_match_context_copy(pcre2_match_context *mcontext) +{ +pcre2_match_context *new = + mcontext->memctl.malloc(sizeof(pcre2_real_match_context), + mcontext->memctl.memory_data); +if (new == NULL) return NULL; +memcpy(new, mcontext, sizeof(pcre2_real_match_context)); +return new; +} + + + +/************************************************* +* Context free functions * +*************************************************/ + + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_general_context_free(pcre2_general_context *gcontext) +{ +if (gcontext != NULL) + gcontext->memctl.free(gcontext, gcontext->memctl.memory_data); +} + + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_compile_context_free(pcre2_compile_context *ccontext) +{ +if (ccontext != NULL) + ccontext->memctl.free(ccontext, ccontext->memctl.memory_data); +} + + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_match_context_free(pcre2_match_context *mcontext) +{ +if (mcontext != NULL) + mcontext->memctl.free(mcontext, mcontext->memctl.memory_data); +} + + + + +/************************************************* +* Set values in contexts * +*************************************************/ + +/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid +data is given. Only some of the functions are able to test the validity of the +data. */ + + +/* ------------ Compile contexts ------------ */ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_character_tables(pcre2_compile_context *ccontext, + const unsigned char *tables) +{ +ccontext->tables = tables; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value) +{ +switch(value) + { + case PCRE2_BSR_ANYCRLF: + case PCRE2_BSR_UNICODE: + ccontext->bsr_convention = value; + return 0; + + default: + return PCRE2_ERROR_BADDATA; + } +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length) +{ +ccontext->max_pattern_length = length; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline) +{ +switch(newline) + { + case PCRE2_NEWLINE_CR: + case PCRE2_NEWLINE_LF: + case PCRE2_NEWLINE_CRLF: + case PCRE2_NEWLINE_ANY: + case PCRE2_NEWLINE_ANYCRLF: + ccontext->newline_convention = newline; + return 0; + + default: + return PCRE2_ERROR_BADDATA; + } +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit) +{ +ccontext->parens_nest_limit = limit; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext, + int (*guard)(uint32_t, void *), void *user_data) +{ +ccontext->stack_guard = guard; +ccontext->stack_guard_data = user_data; +return 0; +} + + +/* ------------ Match contexts ------------ */ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_callout(pcre2_match_context *mcontext, + int (*callout)(pcre2_callout_block *, void *), void *callout_data) +{ +mcontext->callout = callout; +mcontext->callout_data = callout_data; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit) +{ +mcontext->match_limit = limit; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit) +{ +mcontext->offset_limit = limit; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit) +{ +mcontext->recursion_limit = limit; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_recursion_memory_management(pcre2_match_context *mcontext, + void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *), + void *mydata) +{ +#ifdef HEAP_MATCH_RECURSE +mcontext->stack_memctl.malloc = mymalloc; +mcontext->stack_memctl.free = myfree; +mcontext->stack_memctl.memory_data = mydata; +#else +(void)mcontext; +(void)mymalloc; +(void)myfree; +(void)mydata; +#endif +return 0; +} + +/* End of pcre2_context.c */ diff --git a/pcre2/src/pcre2_dfa_match.c b/pcre2/src/pcre2_dfa_match.c new file mode 100644 index 000000000..76bc08525 --- /dev/null +++ b/pcre2/src/pcre2_dfa_match.c @@ -0,0 +1,3618 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains the external function pcre2_dfa_match(), which is an +alternative matching function that uses a sort of DFA algorithm (not a true +FSM). This is NOT Perl-compatible, but it has advantages in certain +applications. */ + + +/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved +the performance of his patterns greatly. I could not use it as it stood, as it +was not thread safe, and made assumptions about pattern sizes. Also, it caused +test 7 to loop, and test 9 to crash with a segfault. + +The issue is the check for duplicate states, which is done by a simple linear +search up the state list. (Grep for "duplicate" below to find the code.) For +many patterns, there will never be many states active at one time, so a simple +linear search is fine. In patterns that have many active states, it might be a +bottleneck. The suggested code used an indexing scheme to remember which states +had previously been used for each character, and avoided the linear search when +it knew there was no chance of a duplicate. This was implemented when adding +states to the state lists. + +I wrote some thread-safe, not-limited code to try something similar at the time +of checking for duplicates (instead of when adding states), using index vectors +on the stack. It did give a 13% improvement with one specially constructed +pattern for certain subject strings, but on other strings and on many of the +simpler patterns in the test suite it did worse. The major problem, I think, +was the extra time to initialize the index. This had to be done for each call +of internal_dfa_match(). (The supplied patch used a static vector, initialized +only once - I suspect this was the cause of the problems with the tests.) + +Overall, I concluded that the gains in some cases did not outweigh the losses +in others, so I abandoned this code. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK mb /* Block containing newline information */ +#define PSSTART start_subject /* Field containing processed string start */ +#define PSEND end_subject /* Field containing processed string end */ + +#include "pcre2_internal.h" + +#define PUBLIC_DFA_MATCH_OPTIONS \ + (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ + PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ + PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART) + + +/************************************************* +* Code parameters and static tables * +*************************************************/ + +/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes +into others, under special conditions. A gap of 20 between the blocks should be +enough. The resulting opcodes don't have to be less than 256 because they are +never stored, so we push them well clear of the normal opcodes. */ + +#define OP_PROP_EXTRA 300 +#define OP_EXTUNI_EXTRA 320 +#define OP_ANYNL_EXTRA 340 +#define OP_HSPACE_EXTRA 360 +#define OP_VSPACE_EXTRA 380 + + +/* This table identifies those opcodes that are followed immediately by a +character that is to be tested in some way. This makes it possible to +centralize the loading of these characters. In the case of Type * etc, the +"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a +small value. Non-zero values in the table are the offsets from the opcode where +the character is to be found. ***NOTE*** If the start of this table is +modified, the three tables that follow must also be modified. */ + +static const uint8_t coptable[] = { + 0, /* End */ + 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */ + 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */ + 0, 0, 0, /* Any, AllAny, Anybyte */ + 0, 0, /* \P, \p */ + 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ + 0, /* \X */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ + 1, /* Char */ + 1, /* Chari */ + 1, /* not */ + 1, /* noti */ + /* Positive single-char repeats */ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */ + 1+IMM2_SIZE, /* exact */ + 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */ + 1+IMM2_SIZE, /* exact I */ + 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ + /* Negative single-char repeats - only for chars < 256 */ + 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */ + 1+IMM2_SIZE, /* NOT exact */ + 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */ + 1+IMM2_SIZE, /* NOT exact I */ + 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */ + /* Positive type repeats */ + 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */ + 1+IMM2_SIZE, /* Type exact */ + 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */ + /* Character class & ref repeats */ + 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ + 0, 0, /* CRRANGE, CRMINRANGE */ + 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */ + 0, /* CLASS */ + 0, /* NCLASS */ + 0, /* XCLASS - variable length */ + 0, /* REF */ + 0, /* REFI */ + 0, /* DNREF */ + 0, /* DNREFI */ + 0, /* RECURSE */ + 0, /* CALLOUT */ + 0, /* CALLOUT_STR */ + 0, /* Alt */ + 0, /* Ket */ + 0, /* KetRmax */ + 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ + 0, /* Assert */ + 0, /* Assert not */ + 0, /* Assert behind */ + 0, /* Assert behind not */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ + 0, 0, /* CREF, DNCREF */ + 0, 0, /* RREF, DNRREF */ + 0, 0, /* FALSE, TRUE */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ +}; + +/* This table identifies those opcodes that inspect a character. It is used to +remember the fact that a character could have been inspected when the end of +the subject is reached. ***NOTE*** If the start of this table is modified, the +two tables that follow must also be modified. */ + +static const uint8_t poptable[] = { + 0, /* End */ + 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */ + 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ + 1, 1, 1, /* Any, AllAny, Anybyte */ + 1, 1, /* \P, \p */ + 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ + 1, /* \X */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ + 1, /* Char */ + 1, /* Chari */ + 1, /* not */ + 1, /* noti */ + /* Positive single-char repeats */ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ + 1, 1, 1, /* upto, minupto, exact */ + 1, 1, 1, 1, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* upto I, minupto I, exact I */ + 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */ + /* Negative single-char repeats - only for chars < 256 */ + 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ + 1, 1, 1, /* NOT upto, minupto, exact */ + 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* NOT upto I, minupto I, exact I */ + 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */ + /* Positive type repeats */ + 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ + 1, 1, 1, /* Type upto, minupto, exact */ + 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */ + /* Character class & ref repeats */ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ + 1, 1, /* CRRANGE, CRMINRANGE */ + 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */ + 1, /* CLASS */ + 1, /* NCLASS */ + 1, /* XCLASS - variable length */ + 0, /* REF */ + 0, /* REFI */ + 0, /* DNREF */ + 0, /* DNREFI */ + 0, /* RECURSE */ + 0, /* CALLOUT */ + 0, /* CALLOUT_STR */ + 0, /* Alt */ + 0, /* Ket */ + 0, /* KetRmax */ + 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ + 0, /* Assert */ + 0, /* Assert not */ + 0, /* Assert behind */ + 0, /* Assert behind not */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ + 0, 0, /* CREF, DNCREF */ + 0, 0, /* RREF, DNRREF */ + 0, 0, /* FALSE, TRUE */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ +}; + +/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, +and \w */ + +static const uint8_t toptable1[] = { + 0, 0, 0, 0, 0, 0, + ctype_digit, ctype_digit, + ctype_space, ctype_space, + ctype_word, ctype_word, + 0, 0 /* OP_ANY, OP_ALLANY */ +}; + +static const uint8_t toptable2[] = { + 0, 0, 0, 0, 0, 0, + ctype_digit, 0, + ctype_space, 0, + ctype_word, 0, + 1, 1 /* OP_ANY, OP_ALLANY */ +}; + + +/* Structure for holding data about a particular state, which is in effect the +current data for an active path through the match tree. It must consist +entirely of ints because the working vector we are passed, and which we put +these structures in, is a vector of ints. */ + +typedef struct stateblock { + int offset; /* Offset to opcode (-ve has meaning) */ + int count; /* Count for repeats */ + int data; /* Some use extra data */ +} stateblock; + +#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) + + + +/************************************************* +* Match a Regular Expression - DFA engine * +*************************************************/ + +/* This internal function applies a compiled pattern to a subject string, +starting at a given point, using a DFA engine. This function is called from the +external one, possibly multiple times if the pattern is not anchored. The +function calls itself recursively for some kinds of subpattern. + +Arguments: + mb the match_data block with fixed information + this_start_code the opening bracket of this subexpression's code + current_subject where we currently are in the subject string + start_offset start offset in the subject string + offsets vector to contain the matching string offsets + offsetcount size of same + workspace vector of workspace + wscount size of same + rlevel function call recursion level + +Returns: > 0 => number of match offset pairs placed in offsets + = 0 => offsets overflowed; longest matches are present + -1 => failed to match + < -1 => some kind of unexpected problem + +The following macros are used for adding states to the two state vectors (one +for the current character, one for the following character). */ + +#define ADD_ACTIVE(x,y) \ + if (active_count++ < wscount) \ + { \ + next_active_state->offset = (x); \ + next_active_state->count = (y); \ + next_active_state++; \ + } \ + else return PCRE2_ERROR_DFA_WSSIZE + +#define ADD_ACTIVE_DATA(x,y,z) \ + if (active_count++ < wscount) \ + { \ + next_active_state->offset = (x); \ + next_active_state->count = (y); \ + next_active_state->data = (z); \ + next_active_state++; \ + } \ + else return PCRE2_ERROR_DFA_WSSIZE + +#define ADD_NEW(x,y) \ + if (new_count++ < wscount) \ + { \ + next_new_state->offset = (x); \ + next_new_state->count = (y); \ + next_new_state++; \ + } \ + else return PCRE2_ERROR_DFA_WSSIZE + +#define ADD_NEW_DATA(x,y,z) \ + if (new_count++ < wscount) \ + { \ + next_new_state->offset = (x); \ + next_new_state->count = (y); \ + next_new_state->data = (z); \ + next_new_state++; \ + } \ + else return PCRE2_ERROR_DFA_WSSIZE + +/* And now, here is the code */ + +static int +internal_dfa_match( + dfa_match_block *mb, + PCRE2_SPTR this_start_code, + PCRE2_SPTR current_subject, + PCRE2_SIZE start_offset, + PCRE2_SIZE *offsets, + uint32_t offsetcount, + int *workspace, + int wscount, + int rlevel) +{ +stateblock *active_states, *new_states, *temp_states; +stateblock *next_active_state, *next_new_state; + +const uint8_t *ctypes, *lcc, *fcc; +PCRE2_SPTR ptr; +PCRE2_SPTR end_code; +PCRE2_SPTR first_op; + +dfa_recursion_info new_recursive; + +int active_count, new_count, match_count; + +/* Some fields in the mb block are frequently referenced, so we load them into +independent variables in the hope that this will perform better. */ + +PCRE2_SPTR start_subject = mb->start_subject; +PCRE2_SPTR end_subject = mb->end_subject; +PCRE2_SPTR start_code = mb->start_code; + +#ifdef SUPPORT_UNICODE +BOOL utf = (mb->poptions & PCRE2_UTF) != 0; +#else +BOOL utf = FALSE; +#endif + +BOOL reset_could_continue = FALSE; + +rlevel++; +offsetcount &= (-2); + +wscount -= 2; +wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / + (2 * INTS_PER_STATEBLOCK); + +ctypes = mb->tables + ctypes_offset; +lcc = mb->tables + lcc_offset; +fcc = mb->tables + fcc_offset; + +match_count = PCRE2_ERROR_NOMATCH; /* A negative number */ + +active_states = (stateblock *)(workspace + 2); +next_new_state = new_states = active_states + wscount; +new_count = 0; + +first_op = this_start_code + 1 + LINK_SIZE + + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) + ? IMM2_SIZE:0); + +/* The first thing in any (sub) pattern is a bracket of some sort. Push all +the alternative states onto the list, and find out where the end is. This +makes is possible to use this function recursively, when we want to stop at a +matching internal ket rather than at the end. + +If the first opcode in the first alternative is OP_REVERSE, we are dealing with +a backward assertion. In that case, we have to find out the maximum amount to +move back, and set up each alternative appropriately. */ + +if (*first_op == OP_REVERSE) + { + size_t max_back = 0; + size_t gone_back; + + end_code = this_start_code; + do + { + size_t back = GET(end_code, 2+LINK_SIZE); + if (back > max_back) max_back = back; + end_code += GET(end_code, 1); + } + while (*end_code == OP_ALT); + + /* If we can't go back the amount required for the longest lookbehind + pattern, go back as far as we can; some alternatives may still be viable. */ + +#ifdef SUPPORT_UNICODE + /* In character mode we have to step back character by character */ + + if (utf) + { + for (gone_back = 0; gone_back < max_back; gone_back++) + { + if (current_subject <= start_subject) break; + current_subject--; + ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--); + } + } + else +#endif + + /* In byte-mode we can do this quickly. */ + + { + size_t current_offset = (size_t)(current_subject - start_subject); + gone_back = (current_offset < max_back)? current_offset : max_back; + current_subject -= gone_back; + } + + /* Save the earliest consulted character */ + + if (current_subject < mb->start_used_ptr) + mb->start_used_ptr = current_subject; + + /* Now we can process the individual branches. */ + + end_code = this_start_code; + do + { + size_t back = GET(end_code, 2+LINK_SIZE); + if (back <= gone_back) + { + int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE); + ADD_NEW_DATA(-bstate, 0, gone_back - back); + } + end_code += GET(end_code, 1); + } + while (*end_code == OP_ALT); + } + +/* This is the code for a "normal" subpattern (not a backward assertion). The +start of a whole pattern is always one of these. If we are at the top level, +we may be asked to restart matching from the same point that we reached for a +previous partial match. We still have to scan through the top-level branches to +find the end state. */ + +else + { + end_code = this_start_code; + + /* Restarting */ + + if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0) + { + do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); + new_count = workspace[1]; + if (!workspace[0]) + memcpy(new_states, active_states, new_count * sizeof(stateblock)); + } + + /* Not restarting */ + + else + { + int length = 1 + LINK_SIZE + + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) + ? IMM2_SIZE:0); + do + { + ADD_NEW((int)(end_code - start_code + length), 0); + end_code += GET(end_code, 1); + length = 1 + LINK_SIZE; + } + while (*end_code == OP_ALT); + } + } + +workspace[0] = 0; /* Bit indicating which vector is current */ + +/* Loop for scanning the subject */ + +ptr = current_subject; +for (;;) + { + int i, j; + int clen, dlen; + uint32_t c, d; + int forced_fail = 0; + BOOL partial_newline = FALSE; + BOOL could_continue = reset_could_continue; + reset_could_continue = FALSE; + + if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr; + + /* Make the new state list into the active state list and empty the + new state list. */ + + temp_states = active_states; + active_states = new_states; + new_states = temp_states; + active_count = new_count; + new_count = 0; + + workspace[0] ^= 1; /* Remember for the restarting feature */ + workspace[1] = active_count; + + /* Set the pointers for adding new states */ + + next_active_state = active_states + active_count; + next_new_state = new_states; + + /* Load the current character from the subject outside the loop, as many + different states may want to look at it, and we assume that at least one + will. */ + + if (ptr < end_subject) + { + clen = 1; /* Number of data items in the character */ +#ifdef SUPPORT_UNICODE + GETCHARLENTEST(c, ptr, clen); +#else + c = *ptr; +#endif /* SUPPORT_UNICODE */ + } + else + { + clen = 0; /* This indicates the end of the subject */ + c = NOTACHAR; /* This value should never actually be used */ + } + + /* Scan up the active states and act on each one. The result of an action + may be to add more states to the currently active list (e.g. on hitting a + parenthesis) or it may be to put states on the new list, for considering + when we move the character pointer on. */ + + for (i = 0; i < active_count; i++) + { + stateblock *current_state = active_states + i; + BOOL caseless = FALSE; + PCRE2_SPTR code; + int state_offset = current_state->offset; + int codevalue, rrc; + int count; + + /* A negative offset is a special case meaning "hold off going to this + (negated) state until the number of characters in the data field have + been skipped". If the could_continue flag was passed over from a previous + state, arrange for it to passed on. */ + + if (state_offset < 0) + { + if (current_state->data > 0) + { + ADD_NEW_DATA(state_offset, current_state->count, + current_state->data - 1); + if (could_continue) reset_could_continue = TRUE; + continue; + } + else + { + current_state->offset = state_offset = -state_offset; + } + } + + /* Check for a duplicate state with the same count, and skip if found. + See the note at the head of this module about the possibility of improving + performance here. */ + + for (j = 0; j < i; j++) + { + if (active_states[j].offset == state_offset && + active_states[j].count == current_state->count) + goto NEXT_ACTIVE_STATE; + } + + /* The state offset is the offset to the opcode */ + + code = start_code + state_offset; + codevalue = *code; + + /* If this opcode inspects a character, but we are at the end of the + subject, remember the fact for use when testing for a partial match. */ + + if (clen == 0 && poptable[codevalue] != 0) + could_continue = TRUE; + + /* If this opcode is followed by an inline character, load it. It is + tempting to test for the presence of a subject character here, but that + is wrong, because sometimes zero repetitions of the subject are + permitted. + + We also use this mechanism for opcodes such as OP_TYPEPLUS that take an + argument that is not a data character - but is always one byte long because + the values are small. We have to take special action to deal with \P, \p, + \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert + these ones to new opcodes. */ + + if (coptable[codevalue] > 0) + { + dlen = 1; +#ifdef SUPPORT_UNICODE + if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else +#endif /* SUPPORT_UNICODE */ + d = code[coptable[codevalue]]; + if (codevalue >= OP_TYPESTAR) + { + switch(d) + { + case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM; + case OP_NOTPROP: + case OP_PROP: codevalue += OP_PROP_EXTRA; break; + case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break; + case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break; + case OP_NOT_HSPACE: + case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break; + case OP_NOT_VSPACE: + case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break; + default: break; + } + } + } + else + { + dlen = 0; /* Not strictly necessary, but compilers moan */ + d = NOTACHAR; /* if these variables are not set. */ + } + + + /* Now process the individual opcodes */ + + switch (codevalue) + { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors coptable or poptable, which are indexed by + opcode, are not the correct length. It seems to be the only way to do + such a check at compile time, as the sizeof() operator does not work + in the C preprocessor. */ + + case OP_TABLE_LENGTH: + case OP_TABLE_LENGTH + + ((sizeof(coptable) == OP_TABLE_LENGTH) && + (sizeof(poptable) == OP_TABLE_LENGTH)): + break; + +/* ========================================================================== */ + /* Reached a closing bracket. If not at the end of the pattern, carry + on with the next opcode. For repeating opcodes, also add the repeat + state. Note that KETRPOS will always be encountered at the end of the + subpattern, because the possessive subpattern repeats are always handled + using recursive calls. Thus, it never adds any new states. + + At the end of the (sub)pattern, unless we have an empty string and + PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the + start of the subject, save the match data, shifting up all previous + matches so we always have the longest first. */ + + case OP_KET: + case OP_KETRMIN: + case OP_KETRMAX: + case OP_KETRPOS: + if (code != end_code) + { + ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); + if (codevalue != OP_KET) + { + ADD_ACTIVE(state_offset - GET(code, 1), 0); + } + } + else + { + if (ptr > current_subject || + ((mb->moptions & PCRE2_NOTEMPTY) == 0 && + ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 || + current_subject > start_subject + mb->start_offset))) + { + if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; + else if (match_count > 0 && ++match_count * 2 > (int)offsetcount) + match_count = 0; + count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2; + if (count > 0) memmove(offsets + 2, offsets, count * sizeof(PCRE2_SIZE)); + if (offsetcount >= 2) + { + offsets[0] = (int)(current_subject - start_subject); + offsets[1] = (int)(ptr - start_subject); + } + if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count; + } + } + break; + +/* ========================================================================== */ + /* These opcodes add to the current list of states without looking + at the current character. */ + + /*-----------------------------------------------------------------*/ + case OP_ALT: + do { code += GET(code, 1); } while (*code == OP_ALT); + ADD_ACTIVE((int)(code - start_code), 0); + break; + + /*-----------------------------------------------------------------*/ + case OP_BRA: + case OP_SBRA: + do + { + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + code += GET(code, 1); + } + while (*code == OP_ALT); + break; + + /*-----------------------------------------------------------------*/ + case OP_CBRA: + case OP_SCBRA: + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0); + code += GET(code, 1); + while (*code == OP_ALT) + { + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + code += GET(code, 1); + } + break; + + /*-----------------------------------------------------------------*/ + case OP_BRAZERO: + case OP_BRAMINZERO: + ADD_ACTIVE(state_offset + 1, 0); + code += 1 + GET(code, 2); + while (*code == OP_ALT) code += GET(code, 1); + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + break; + + /*-----------------------------------------------------------------*/ + case OP_SKIPZERO: + code += 1 + GET(code, 2); + while (*code == OP_ALT) code += GET(code, 1); + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + break; + + /*-----------------------------------------------------------------*/ + case OP_CIRC: + if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_CIRCM: + if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) || + ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 ) + && WAS_NEWLINE(ptr))) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_EOD: + if (ptr >= end_subject) + { + if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) + could_continue = TRUE; + else { ADD_ACTIVE(state_offset + 1, 0); } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_SOD: + if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_SOM: + if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); } + break; + + +/* ========================================================================== */ + /* These opcodes inspect the next subject character, and sometimes + the previous one as well, but do not have an argument. The variable + clen contains the length of the current character and is zero if we are + at the end of the subject. */ + + /*-----------------------------------------------------------------*/ + case OP_ANY: + if (clen > 0 && !IS_NEWLINE(ptr)) + { + if (ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else + { + ADD_NEW(state_offset + 1, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_ALLANY: + if (clen > 0) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_EODN: + if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen)) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_DOLL: + if ((mb->moptions & PCRE2_NOTEOL) == 0) + { + if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || + ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) && + (ptr == end_subject - mb->nllen) + )) + { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_DOLLM: + if ((mb->moptions & PCRE2_NOTEOL) == 0) + { + if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || + ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) + { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } + } + else if (IS_NEWLINE(ptr)) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + + case OP_DIGIT: + case OP_WHITESPACE: + case OP_WORDCHAR: + if (clen > 0 && c < 256 && + ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_DIGIT: + case OP_NOT_WHITESPACE: + case OP_NOT_WORDCHAR: + if (clen > 0 && (c >= 256 || + ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + { + int left_word, right_word; + + if (ptr > start_subject) + { + PCRE2_SPTR temp = ptr - 1; + if (temp < mb->start_used_ptr) mb->start_used_ptr = temp; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (utf) { BACKCHAR(temp); } +#endif + GETCHARTEST(d, temp); +#ifdef SUPPORT_UNICODE + if ((mb->poptions & PCRE2_UCP) != 0) + { + if (d == '_') left_word = TRUE; else + { + int cat = UCD_CATEGORY(d); + left_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + left_word = d < 256 && (ctypes[d] & ctype_word) != 0; + } + else left_word = FALSE; + + if (clen > 0) + { + if (ptr >= mb->last_used_ptr) + { + PCRE2_SPTR temp = ptr + 1; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (utf) { FORWARDCHARTEST(temp, mb->end_subject); } +#endif + mb->last_used_ptr = temp; + } +#ifdef SUPPORT_UNICODE + if ((mb->poptions & PCRE2_UCP) != 0) + { + if (c == '_') right_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + right_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + right_word = c < 256 && (ctypes[c] & ctype_word) != 0; + } + else right_word = FALSE; + + if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) + { ADD_ACTIVE(state_offset + 1, 0); } + } + break; + + + /*-----------------------------------------------------------------*/ + /* Check the next character by Unicode property. We will get here only + if the support is in the binary; otherwise a compile-time error occurs. + */ + +#ifdef SUPPORT_UNICODE + case OP_PROP: + case OP_NOTPROP: + if (clen > 0) + { + BOOL OK; + const uint32_t *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[1]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[2]; + break; + + case PT_PC: + OK = prop->chartype == code[2]; + break; + + case PT_SC: + OK = prop->script == code[2]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } + break; + + case PT_WORD: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[2]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); } + } + break; +#endif + + + +/* ========================================================================== */ + /* These opcodes likewise inspect the subject character, but have an + argument that is not a data character. It is one of these opcodes: + OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE, + OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + if (d == OP_ANY && ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + (c < 256 && + (d != OP_ANY || !IS_NEWLINE(ptr)) && + ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) + { + if (count > 0 && codevalue == OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + if (d == OP_ANY && ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + (c < 256 && + (d != OP_ANY || !IS_NEWLINE(ptr)) && + ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) + { + if (codevalue == OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + 2, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + if (d == OP_ANY && ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + (c < 256 && + (d != OP_ANY || !IS_NEWLINE(ptr)) && + ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) + { + if (codevalue == OP_TYPEPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEEXACT: + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + if (d == OP_ANY && ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + (c < 256 && + (d != OP_ANY || !IS_NEWLINE(ptr)) && + ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) + { + if (++count >= (int)GET2(code, 1)) + { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + if (d == OP_ANY && ptr + 1 >= mb->end_subject && + (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + (c < 256 && + (d != OP_ANY || !IS_NEWLINE(ptr)) && + ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) + { + if (codevalue == OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + +/* ========================================================================== */ + /* These are virtual opcodes that are used when something like + OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its + argument. It keeps the code above fast for the other cases. The argument + is in the d variable. */ + +#ifdef SUPPORT_UNICODE + case OP_PROP_EXTRA + OP_TYPEPLUS: + case OP_PROP_EXTRA + OP_TYPEMINPLUS: + case OP_PROP_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); } + if (clen > 0) + { + BOOL OK; + const uint32_t *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[2]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; + break; + + case PT_PC: + OK = prop->chartype == code[3]; + break; + + case PT_SC: + OK = prop->script == code[3]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } + break; + + case PT_WORD: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[3]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEPLUS: + case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS: + case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + int lgb, rgb; + PCRE2_SPTR nptr = ptr + clen; + int ncount = 0; + if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + count++; + ADD_NEW_DATA(-state_offset, count, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEPLUS: + case OP_ANYNL_EXTRA + OP_TYPEMINPLUS: + case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; + goto ANYNL01; + + case CHAR_CR: + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL01: + case CHAR_LF: + if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, ncount); + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEPLUS: + case OP_VSPACE_EXTRA + OP_TYPEMINPLUS: + case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_VSPACE)) + { + if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEPLUS: + case OP_HSPACE_EXTRA + OP_TYPEMINPLUS: + case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ +#ifdef SUPPORT_UNICODE + case OP_PROP_EXTRA + OP_TYPEQUERY: + case OP_PROP_EXTRA + OP_TYPEMINQUERY: + case OP_PROP_EXTRA + OP_TYPEPOSQUERY: + count = 4; + goto QS1; + + case OP_PROP_EXTRA + OP_TYPESTAR: + case OP_PROP_EXTRA + OP_TYPEMINSTAR: + case OP_PROP_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS1: + + ADD_ACTIVE(state_offset + 4, 0); + if (clen > 0) + { + BOOL OK; + const uint32_t *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[2]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; + break; + + case PT_PC: + OK = prop->chartype == code[3]; + break; + + case PT_SC: + OK = prop->script == code[3]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } + break; + + case PT_WORD: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[3]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEQUERY: + case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY: + case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS2; + + case OP_EXTUNI_EXTRA + OP_TYPESTAR: + case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR: + case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS2: + + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + int lgb, rgb; + PCRE2_SPTR nptr = ptr + clen; + int ncount = 0; + if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + ADD_NEW_DATA(-(state_offset + count), 0, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEQUERY: + case OP_ANYNL_EXTRA + OP_TYPEMINQUERY: + case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS3; + + case OP_ANYNL_EXTRA + OP_TYPESTAR: + case OP_ANYNL_EXTRA + OP_TYPEMINSTAR: + case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS3: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; + goto ANYNL02; + + case CHAR_CR: + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL02: + case CHAR_LF: + if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount); + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEQUERY: + case OP_VSPACE_EXTRA + OP_TYPEMINQUERY: + case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS4; + + case OP_VSPACE_EXTRA + OP_TYPESTAR: + case OP_VSPACE_EXTRA + OP_TYPEMINSTAR: + case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS4: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + if (OK == (d == OP_VSPACE)) + { + if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEQUERY: + case OP_HSPACE_EXTRA + OP_TYPEMINQUERY: + case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS5; + + case OP_HSPACE_EXTRA + OP_TYPESTAR: + case OP_HSPACE_EXTRA + OP_TYPEMINSTAR: + case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS5: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ +#ifdef SUPPORT_UNICODE + case OP_PROP_EXTRA + OP_TYPEEXACT: + case OP_PROP_EXTRA + OP_TYPEUPTO: + case OP_PROP_EXTRA + OP_TYPEMINUPTO: + case OP_PROP_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + const uint32_t *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[1 + IMM2_SIZE + 1]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2]; + break; + + case PT_PC: + OK = prop->chartype == code[1 + IMM2_SIZE + 2]; + break; + + case PT_SC: + OK = prop->script == code[1 + IMM2_SIZE + 2]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } + break; + + case PT_WORD: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEEXACT: + case OP_EXTUNI_EXTRA + OP_TYPEUPTO: + case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: + case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + int lgb, rgb; + PCRE2_SPTR nptr = ptr + clen; + int ncount = 0; + if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + if (++count >= (int)GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } + else + { ADD_NEW_DATA(-state_offset, count, ncount); } + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEEXACT: + case OP_ANYNL_EXTRA + OP_TYPEUPTO: + case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: + case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; + goto ANYNL03; + + case CHAR_CR: + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL03: + case CHAR_LF: + if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } + else + { ADD_NEW_DATA(-state_offset, count, ncount); } + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEEXACT: + case OP_VSPACE_EXTRA + OP_TYPEUPTO: + case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: + case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + } + + if (OK == (d == OP_VSPACE)) + { + if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } + else + { ADD_NEW_DATA(-state_offset, count, 0); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEEXACT: + case OP_HSPACE_EXTRA + OP_TYPEUPTO: + case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: + case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } + else + { ADD_NEW_DATA(-state_offset, count, 0); } + } + } + break; + +/* ========================================================================== */ + /* These opcodes are followed by a character that is usually compared + to the current subject character; it is loaded into d. We still get + here even if there is no subject character, because in some cases zero + repetitions are permitted. */ + + /*-----------------------------------------------------------------*/ + case OP_CHAR: + if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_CHARI: + if (clen == 0) break; + +#ifdef SUPPORT_UNICODE + if (utf) + { + if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else + { + unsigned int othercase; + if (c < 128) + othercase = fcc[c]; + else + othercase = UCD_OTHERCASE(c); + if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } + } + } + else +#endif /* SUPPORT_UNICODE */ + /* Not UTF mode */ + { + if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) + { ADD_NEW(state_offset + 2, 0); } + } + break; + + +#ifdef SUPPORT_UNICODE + /*-----------------------------------------------------------------*/ + /* This is a tricky one because it can match more than one character. + Find out how many characters to skip, and then set up a negative state + to wait for them to pass before continuing. */ + + case OP_EXTUNI: + if (clen > 0) + { + int lgb, rgb; + PCRE2_SPTR nptr = ptr + clen; + int ncount = 0; + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + /* This is a tricky like EXTUNI because it too can match more than one + character (when CR is followed by LF). In this case, set up a negative + state to wait for one character to pass before continuing. */ + + case OP_ANYNL: + if (clen > 0) switch(c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; + + case CHAR_LF: + ADD_NEW(state_offset + 1, 0); + break; + + case CHAR_CR: + if (ptr + 1 >= end_subject) + { + ADD_NEW(state_offset + 1, 0); + if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + } + else if (UCHAR21TEST(ptr + 1) == CHAR_LF) + { + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else + { + ADD_NEW(state_offset + 1, 0); + } + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_VSPACE: + if (clen > 0) switch(c) + { + VSPACE_CASES: + break; + + default: + ADD_NEW(state_offset + 1, 0); + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE: + if (clen > 0) switch(c) + { + VSPACE_CASES: + ADD_NEW(state_offset + 1, 0); + break; + + default: + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_HSPACE: + if (clen > 0) switch(c) + { + HSPACE_CASES: + break; + + default: + ADD_NEW(state_offset + 1, 0); + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE: + if (clen > 0) switch(c) + { + HSPACE_CASES: + ADD_NEW(state_offset + 1, 0); + break; + + default: + break; + } + break; + + /*-----------------------------------------------------------------*/ + /* Match a negated single character casefully. */ + + case OP_NOT: + if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + /* Match a negated single character caselessly. */ + + case OP_NOTI: + if (clen > 0) + { + unsigned int otherd; +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + if (c != d && c != otherd) + { ADD_NEW(state_offset + dlen + 1, 0); } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + + /* Fall through */ + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } + if (clen > 0) + { + uint32_t otherd = NOTACHAR; + if (caseless) + { +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + } + if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) + { + if (count > 0 && + (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS)) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSQUERY: + ADD_ACTIVE(state_offset + dlen + 1, 0); + if (clen > 0) + { + uint32_t otherd = NOTACHAR; + if (caseless) + { +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + } + if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + dlen + 1, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ + case OP_STAR: + case OP_MINSTAR: + case OP_POSSTAR: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPOSSTAR: + ADD_ACTIVE(state_offset + dlen + 1, 0); + if (clen > 0) + { + uint32_t otherd = NOTACHAR; + if (caseless) + { +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + } + if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXACTI: + case OP_NOTEXACTI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ + case OP_EXACT: + case OP_NOTEXACT: + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + uint32_t otherd = NOTACHAR; + if (caseless) + { +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + } + if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) + { + if (++count >= (int)GET2(code, 1)) + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTPOSUPTO: + ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0); + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + uint32_t otherd = NOTACHAR; + if (caseless) + { +#ifdef SUPPORT_UNICODE + if (utf && d >= 128) + otherd = UCD_OTHERCASE(d); + else +#endif /* SUPPORT_UNICODE */ + otherd = TABLE_GET(d, fcc, d); + } + if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= (int)GET2(code, 1)) + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + +/* ========================================================================== */ + /* These are the class-handling opcodes */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + BOOL isinclass = FALSE; + int next_state_offset; + PCRE2_SPTR ecode; + + /* For a simple class, there is always just a 32-byte table, and we + can set isinclass from it. */ + + if (codevalue != OP_XCLASS) + { + ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); + if (clen > 0) + { + isinclass = (c > 255)? (codevalue == OP_NCLASS) : + ((((uint8_t *)(code + 1))[c/8] & (1 << (c&7))) != 0); + } + } + + /* An extended class may have a table or a list of single characters, + ranges, or both, and it may be positive or negative. There's a + function that sorts all this out. */ + + else + { + ecode = code + GET(code, 1); + if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); + } + + /* At this point, isinclass is set for all kinds of class, and ecode + points to the byte after the end of the class. If there is a + quantifier, this is where it will be. */ + + next_state_offset = (int)(ecode - start_code); + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + ADD_ACTIVE(next_state_offset + 1, 0); + if (isinclass) + { + if (*ecode == OP_CRPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } + if (isinclass) + { + if (count > 0 && *ecode == OP_CRPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + break; + + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + ADD_ACTIVE(next_state_offset + 1, 0); + if (isinclass) + { + if (*ecode == OP_CRPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(next_state_offset + 1, 0); + } + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + count = current_state->count; /* Already matched */ + if (count >= (int)GET2(ecode, 1)) + { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } + if (isinclass) + { + int max = (int)GET2(ecode, 1 + IMM2_SIZE); + if (*ecode == OP_CRPOSRANGE) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= max && max != 0) /* Max 0 => no limit */ + { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + break; + + default: + if (isinclass) { ADD_NEW(next_state_offset, 0); } + break; + } + } + break; + +/* ========================================================================== */ + /* These are the opcodes for fancy brackets of various kinds. We have + to use recursion in order to handle them. The "always failing" assertion + (?!) is optimised to OP_FAIL when compiling, so we have to support that, + though the other "backtracking verbs" are not supported. */ + + case OP_FAIL: + forced_fail++; /* Count FAILs for multiple states */ + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + { + PCRE2_SPTR endasscode = code + GET(code, 1); + PCRE2_SIZE local_offsets[2]; + int rc; + int local_workspace[1000]; + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); + + rc = internal_dfa_match( + mb, /* static match data */ + code, /* this subexpression's code */ + ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + if (rc == PCRE2_ERROR_DFA_UITEM) return rc; + if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) + { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_COND: + case OP_SCOND: + { + PCRE2_SIZE local_offsets[1000]; + int local_workspace[1000]; + int codelink = GET(code, 1); + int condcode; + + /* Because of the way auto-callout works during compile, a callout item + is inserted between OP_COND and an assertion condition. This does not + happen for the other conditions. */ + + if (code[LINK_SIZE + 1] == OP_CALLOUT + || code[LINK_SIZE + 1] == OP_CALLOUT_STR) + { + unsigned int callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT) + ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 2 + 3*LINK_SIZE); + rrc = 0; + if (mb->callout != NULL) + { + pcre2_callout_block cb; + cb.version = 1; + cb.capture_top = 1; + cb.capture_last = 0; + cb.offset_vector = offsets; + cb.mark = NULL; /* No (*MARK) support */ + cb.subject = start_subject; + cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject); + cb.start_match = (PCRE2_SIZE)(current_subject - start_subject); + cb.current_position = (PCRE2_SIZE)(ptr - start_subject); + cb.pattern_position = GET(code, LINK_SIZE + 2); + cb.next_item_length = GET(code, LINK_SIZE + 2 + LINK_SIZE); + + if (code[LINK_SIZE + 1] == OP_CALLOUT) + { + cb.callout_number = code[2 + 3*LINK_SIZE]; + cb.callout_string_offset = 0; + cb.callout_string = NULL; + cb.callout_string_length = 0; + } + else + { + cb.callout_number = 0; + cb.callout_string_offset = GET(code, 2 + 4*LINK_SIZE); + cb.callout_string = code + (2 + 5*LINK_SIZE) + 1; + cb.callout_string_length = + callout_length - (1 + 4*LINK_SIZE) - 2; + } + + if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0) + return rrc; /* Abandon */ + } + if (rrc > 0) break; /* Fail this thread */ + code += callout_length; /* Skip callout data */ + } + + condcode = code[LINK_SIZE+1]; + + /* Back reference conditions and duplicate named recursion conditions + are not supported */ + + if (condcode == OP_CREF || condcode == OP_DNCREF || + condcode == OP_DNRREF) + return PCRE2_ERROR_DFA_UCOND; + + /* The DEFINE condition is always false, and the assertion (?!) is + converted to OP_FAIL. */ + + if (condcode == OP_FALSE || condcode == OP_FAIL) + { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + + /* There is also an always-true condition */ + + else if (condcode == OP_TRUE) + { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } + + /* The only supported version of OP_RREF is for the value RREF_ANY, + which means "test if in any recursion". We can't test for specifically + recursed groups. */ + + else if (condcode == OP_RREF) + { + int value = GET2(code, LINK_SIZE + 2); + if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND; + if (mb->recursive != NULL) + { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } + else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + } + + /* Otherwise, the condition is an assertion */ + + else + { + int rc; + PCRE2_SPTR asscode = code + LINK_SIZE + 1; + PCRE2_SPTR endasscode = asscode + GET(asscode, 1); + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); + + rc = internal_dfa_match( + mb, /* fixed match data */ + asscode, /* this subexpression's code */ + ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + if (rc == PCRE2_ERROR_DFA_UITEM) return rc; + if ((rc >= 0) == + (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) + { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } + else + { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_RECURSE: + { + dfa_recursion_info *ri; + PCRE2_SIZE local_offsets[1000]; + int local_workspace[1000]; + PCRE2_SPTR callpat = start_code + GET(code, 1); + uint32_t recno = (callpat == mb->start_code)? 0 : + GET2(callpat, 1 + LINK_SIZE); + int rc; + + /* Check for repeating a recursion without advancing the subject + pointer. This should catch convoluted mutual recursions. (Some simple + cases are caught at compile time.) */ + + for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && ptr == ri->subject_position) + return PCRE2_ERROR_RECURSELOOP; + + /* Remember this recursion and where we started it so as to + catch infinite loops. */ + + new_recursive.group_num = recno; + new_recursive.subject_position = ptr; + new_recursive.prevrec = mb->recursive; + mb->recursive = &new_recursive; + + rc = internal_dfa_match( + mb, /* fixed match data */ + callpat, /* this subexpression's code */ + ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + mb->recursive = new_recursive.prevrec; /* Done this recursion */ + + /* Ran out of internal offsets */ + + if (rc == 0) return PCRE2_ERROR_DFA_RECURSE; + + /* For each successful matched substring, set up the next state with a + count of characters to skip before trying it. Note that the count is in + characters, not bytes. */ + + if (rc > 0) + { + for (rc = rc*2 - 2; rc >= 0; rc -= 2) + { + int charcount = local_offsets[rc+1] - local_offsets[rc]; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (utf) + { + PCRE2_SPTR p = start_subject + local_offsets[rc]; + PCRE2_SPTR pp = start_subject + local_offsets[rc+1]; + while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; + } +#endif + if (charcount > 0) + { + ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); + } + else + { + ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0); + } + } + } + else if (rc != PCRE2_ERROR_NOMATCH) return rc; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + { + int charcount, matched_count; + PCRE2_SPTR local_ptr = ptr; + BOOL allow_zero; + + if (codevalue == OP_BRAPOSZERO) + { + allow_zero = TRUE; + codevalue = *(++code); /* Codevalue will be one of above BRAs */ + } + else allow_zero = FALSE; + + /* Loop to match the subpattern as many times as possible as if it were + a complete pattern. */ + + for (matched_count = 0;; matched_count++) + { + PCRE2_SIZE local_offsets[2]; + int local_workspace[1000]; + + int rc = internal_dfa_match( + mb, /* fixed match data */ + code, /* this subexpression's code */ + local_ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + /* Failed to match */ + + if (rc < 0) + { + if (rc != PCRE2_ERROR_NOMATCH) return rc; + break; + } + + /* Matched: break the loop if zero characters matched. */ + + charcount = local_offsets[1] - local_offsets[0]; + if (charcount == 0) break; + local_ptr += charcount; /* Advance temporary position ptr */ + } + + /* At this point we have matched the subpattern matched_count + times, and local_ptr is pointing to the character after the end of the + last match. */ + + if (matched_count > 0 || allow_zero) + { + PCRE2_SPTR end_subpattern = code; + int next_state_offset; + + do { end_subpattern += GET(end_subpattern, 1); } + while (*end_subpattern == OP_ALT); + next_state_offset = + (int)(end_subpattern - start_code + LINK_SIZE + 1); + + /* Optimization: if there are no more active states, and there + are no new states yet set up, then skip over the subject string + right here, to save looping. Otherwise, set up the new state to swing + into action when the end of the matched substring is reached. */ + + if (i + 1 >= active_count && new_count == 0) + { + ptr = local_ptr; + clen = 0; + ADD_NEW(next_state_offset, 0); + } + else + { + PCRE2_SPTR p = ptr; + PCRE2_SPTR pp = local_ptr; + charcount = (int)(pp - p); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; +#endif + ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_ONCE: + case OP_ONCE_NC: + { + PCRE2_SIZE local_offsets[2]; + int local_workspace[1000]; + + int rc = internal_dfa_match( + mb, /* fixed match data */ + code, /* this subexpression's code */ + ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + if (rc >= 0) + { + PCRE2_SPTR end_subpattern = code; + int charcount = local_offsets[1] - local_offsets[0]; + int next_state_offset, repeat_state_offset; + + do { end_subpattern += GET(end_subpattern, 1); } + while (*end_subpattern == OP_ALT); + next_state_offset = + (int)(end_subpattern - start_code + LINK_SIZE + 1); + + /* If the end of this subpattern is KETRMAX or KETRMIN, we must + arrange for the repeat state also to be added to the relevant list. + Calculate the offset, or set -1 for no repeat. */ + + repeat_state_offset = (*end_subpattern == OP_KETRMAX || + *end_subpattern == OP_KETRMIN)? + (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1; + + /* If we have matched an empty string, add the next state at the + current character pointer. This is important so that the duplicate + checking kicks in, which is what breaks infinite loops that match an + empty string. */ + + if (charcount == 0) + { + ADD_ACTIVE(next_state_offset, 0); + } + + /* Optimization: if there are no more active states, and there + are no new states yet set up, then skip over the subject string + right here, to save looping. Otherwise, set up the new state to swing + into action when the end of the matched substring is reached. */ + + else if (i + 1 >= active_count && new_count == 0) + { + ptr += charcount; + clen = 0; + ADD_NEW(next_state_offset, 0); + + /* If we are adding a repeat state at the new character position, + we must fudge things so that it is the only current state. + Otherwise, it might be a duplicate of one we processed before, and + that would cause it to be skipped. */ + + if (repeat_state_offset >= 0) + { + next_active_state = active_states; + active_count = 0; + i = -1; + ADD_ACTIVE(repeat_state_offset, 0); + } + } + else + { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (utf) + { + PCRE2_SPTR p = start_subject + local_offsets[0]; + PCRE2_SPTR pp = start_subject + local_offsets[1]; + while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; + } +#endif + ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + if (repeat_state_offset >= 0) + { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } + } + } + else if (rc != PCRE2_ERROR_NOMATCH) return rc; + } + break; + + +/* ========================================================================== */ + /* Handle callouts */ + + case OP_CALLOUT: + case OP_CALLOUT_STR: + { + unsigned int callout_length = (*code == OP_CALLOUT) + ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 1 + 2*LINK_SIZE); + rrc = 0; + + if (mb->callout != NULL) + { + pcre2_callout_block cb; + cb.version = 1; + cb.capture_top = 1; + cb.capture_last = 0; + cb.offset_vector = offsets; + cb.mark = NULL; /* No (*MARK) support */ + cb.subject = start_subject; + cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject); + cb.start_match = (PCRE2_SIZE)(current_subject - start_subject); + cb.current_position = (PCRE2_SIZE)(ptr - start_subject); + cb.pattern_position = GET(code, 1); + cb.next_item_length = GET(code, 1 + LINK_SIZE); + + if (*code == OP_CALLOUT) + { + cb.callout_number = code[1 + 2*LINK_SIZE]; + cb.callout_string_offset = 0; + cb.callout_string = NULL; + cb.callout_string_length = 0; + } + else + { + cb.callout_number = 0; + cb.callout_string_offset = GET(code, 1 + 3*LINK_SIZE); + cb.callout_string = code + (1 + 4*LINK_SIZE) + 1; + cb.callout_string_length = + callout_length - (1 + 4*LINK_SIZE) - 2; + } + + if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0) + return rrc; /* Abandon */ + } + if (rrc == 0) + { ADD_ACTIVE(state_offset + callout_length, 0); } + } + break; + + +/* ========================================================================== */ + default: /* Unsupported opcode */ + return PCRE2_ERROR_DFA_UITEM; + } + + NEXT_ACTIVE_STATE: continue; + + } /* End of loop scanning active states */ + + /* We have finished the processing at the current subject character. If no + new states have been set for the next character, we have found all the + matches that we are going to find. If we are at the top level and partial + matching has been requested, check for appropriate conditions. + + The "forced_ fail" variable counts the number of (*F) encountered for the + character. If it is equal to the original active_count (saved in + workspace[1]) it means that (*F) was found on every active state. In this + case we don't want to give a partial match. + + The "could_continue" variable is true if a state could have continued but + for the fact that the end of the subject was reached. */ + + if (new_count <= 0) + { + if (rlevel == 1 && /* Top level, and */ + could_continue && /* Some could go on, and */ + forced_fail != workspace[1] && /* Not all forced fail & */ + ( /* either... */ + (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */ + || /* or... */ + ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */ + match_count < 0) /* no matches */ + ) && /* And... */ + ( + partial_newline || /* Either partial NL */ + ( /* or ... */ + ptr >= end_subject && /* End of subject and */ + ptr > mb->start_used_ptr) /* Inspected non-empty string */ + ) + ) + match_count = PCRE2_ERROR_PARTIAL; + break; /* In effect, "return", but see the comment below */ + } + + /* One or more states are active for the next character. */ + + ptr += clen; /* Advance to next subject character */ + } /* Loop to move along the subject string */ + +/* Control gets here from "break" a few lines above. We do it this way because +if we use "return" above, we have compiler trouble. Some compilers warn if +there's nothing here because they think the function doesn't return a value. On +the other hand, if we put a dummy statement here, some more clever compilers +complain that it can't be reached. Sigh. */ + +return match_count; +} + + + +/************************************************* +* Match a pattern using the DFA algorithm * +*************************************************/ + +/* This function matches a compiled pattern to a subject string, using the +alternate matching algorithm that finds all matches at once. + +Arguments: + code points to the compiled pattern + subject subject string + length length of subject string + startoffset where to start matching in the subject + options option bits + match_data points to a match data structure + gcontext points to a match context + workspace pointer to workspace + wscount size of workspace + +Returns: > 0 => number of match offset pairs placed in offsets + = 0 => offsets overflowed; longest matches are present + -1 => failed to match + < -1 => some kind of unexpected problem +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, + PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, + pcre2_match_context *mcontext, int *workspace, size_t wscount) +{ +const pcre2_real_code *re = (const pcre2_real_code *)code; + +PCRE2_SPTR start_match; +PCRE2_SPTR end_subject; +PCRE2_SPTR bumpalong_limit; +PCRE2_SPTR req_cu_ptr; + +BOOL utf, anchored, startline, firstline; + +BOOL has_first_cu = FALSE; +BOOL has_req_cu = FALSE; +PCRE2_UCHAR first_cu = 0; +PCRE2_UCHAR first_cu2 = 0; +PCRE2_UCHAR req_cu = 0; +PCRE2_UCHAR req_cu2 = 0; + +const uint8_t *start_bits = NULL; + +/* We need to have mb pointing to a match block, because the IS_NEWLINE macro +is used below, and it expects NLBLOCK to be defined as a pointer. */ + +dfa_match_block actual_match_block; +dfa_match_block *mb = &actual_match_block; + +/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated +subject string. */ + +if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); + +/* Plausibility checks */ + +if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; +if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL) + return PCRE2_ERROR_NULL; +if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE; +if (start_offset > length) return PCRE2_ERROR_BADOFFSET; + +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE2_ERROR_BADMAGIC. */ + +if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; + +/* Check the code unit width. */ + +if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) + return PCRE2_ERROR_BADMODE; + +/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the +options variable for this function. Users of PCRE2 who are not calling the +function directly would like to have a way of setting these flags, in the same +way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with +constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and +(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be +transferred to the options for this function. The bits are guaranteed to be +adjacent, but do not have the same values. This bit of Boolean trickery assumes +that the match-time bits are not more significant than the flag bits. If by +accident this is not the case, a compile-time division by zero error will +occur. */ + +#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET) +#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART) +options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1))); +#undef FF +#undef OO + +/* If restarting after a partial match, do some sanity checks on the contents +of the workspace. */ + +if ((options & PCRE2_DFA_RESTART) != 0) + { + if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 || + workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK)) + return PCRE2_ERROR_DFA_BADRESTART; + } + +/* Set some local values */ + +utf = (re->overall_options & PCRE2_UTF) != 0; +start_match = subject + start_offset; +end_subject = subject + length; +req_cu_ptr = start_match - 1; +anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 || + (re->overall_options & PCRE2_ANCHORED) != 0; + +/* The "must be at the start of a line" flags are used in a loop when finding +where to start. */ + +startline = (re->flags & PCRE2_STARTLINE) != 0; +firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +bumpalong_limit = end_subject; + +/* Get data from the match context, if present, and fill in the fields in the +match block. It is an error to set an offset limit without setting the flag at +compile time. */ + +if (mcontext == NULL) + { + mb->callout = NULL; + mb->memctl = re->memctl; + } +else + { + if (mcontext->offset_limit != PCRE2_UNSET) + { + if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) + return PCRE2_ERROR_BADOFFSETLIMIT; + bumpalong_limit = subject + mcontext->offset_limit; + } + mb->callout = mcontext->callout; + mb->callout_data = mcontext->callout_data; + mb->memctl = mcontext->memctl; + } + +mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_count * re->name_entry_size; +mb->tables = re->tables; +mb->start_subject = subject; +mb->end_subject = end_subject; +mb->start_offset = start_offset; +mb->moptions = options; +mb->poptions = re->overall_options; + +/* Process the \R and newline settings. */ + +mb->bsr_convention = re->bsr_convention; +mb->nltype = NLTYPE_FIXED; +switch(re->newline_convention) + { + case PCRE2_NEWLINE_CR: + mb->nllen = 1; + mb->nl[0] = CHAR_CR; + break; + + case PCRE2_NEWLINE_LF: + mb->nllen = 1; + mb->nl[0] = CHAR_NL; + break; + + case PCRE2_NEWLINE_CRLF: + mb->nllen = 2; + mb->nl[0] = CHAR_CR; + mb->nl[1] = CHAR_NL; + break; + + case PCRE2_NEWLINE_ANY: + mb->nltype = NLTYPE_ANY; + break; + + case PCRE2_NEWLINE_ANYCRLF: + mb->nltype = NLTYPE_ANYCRLF; + break; + + default: return PCRE2_ERROR_INTERNAL; + } + +/* Check a UTF string for validity if required. For 8-bit and 16-bit strings, +we must also check that a starting offset does not point into the middle of a +multiunit character. We check only the portion of the subject that is going to +be inspected during matching - from the offset minus the maximum back reference +to the given length. This saves time when a small part of a large subject is +being matched by the use of a starting offset. Note that the maximum lookbehind +is a number of characters, not code units. */ + +#ifdef SUPPORT_UNICODE +if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) + { + PCRE2_SPTR check_subject = start_match; /* start_match includes offset */ + + if (start_offset > 0) + { +#if PCRE2_CODE_UNIT_WIDTH != 32 + unsigned int i; + if (start_match < end_subject && NOT_FIRSTCU(*start_match)) + return PCRE2_ERROR_BADUTFOFFSET; + for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--) + { + check_subject--; + while (check_subject > subject && +#if PCRE2_CODE_UNIT_WIDTH == 8 + (*check_subject & 0xc0) == 0x80) +#else /* 16-bit */ + (*check_subject & 0xfc00) == 0xdc00) +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + check_subject--; + } +#else /* In the 32-bit library, one code unit equals one character. */ + check_subject -= re->max_lookbehind; + if (check_subject < subject) check_subject = subject; +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + } + + /* Validate the relevant portion of the subject. After an error, adjust the + offset to be an absolute offset in the whole string. */ + + match_data->rc = PRIV(valid_utf)(check_subject, + length - (check_subject - subject), &(match_data->startchar)); + if (match_data->rc != 0) + { + match_data->startchar += check_subject - subject; + return match_data->rc; + } + } +#endif /* SUPPORT_UNICODE */ + +/* Set up the first code unit to match, if available. The first_codeunit value +is never set for an anchored regular expression, but the anchoring may be +forced at run time, so we have to test for anchoring. The first code unit may +be unset for an unanchored pattern, of course. If there's no first code unit +there may be a bitmap of possible first characters. */ + +if (!anchored) + { + if ((re->flags & PCRE2_FIRSTSET) != 0) + { + has_first_cu = TRUE; + first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit); + if ((re->flags & PCRE2_FIRSTCASELESS) != 0) + { + first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); +#endif + } + } + else + if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0) + start_bits = re->start_bitmap; + } + +/* For anchored or unanchored matches, there may be a "last known required +character" set. */ + +if ((re->flags & PCRE2_LASTSET) != 0) + { + has_req_cu = TRUE; + req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit); + if ((re->flags & PCRE2_LASTCASELESS) != 0) + { + req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); +#endif + } + } + +/* Fill in fields that are always returned in the match data. */ + +match_data->code = re; +match_data->subject = subject; +match_data->mark = NULL; +match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER; + +/* Call the main matching function, looping for a non-anchored regex after a +failed match. If not restarting, perform certain optimizations at the start of +a match. */ + +for (;;) + { + int rc; + + /* ----------------- Start of match optimizations ---------------- */ + + /* There are some optimizations that avoid running the match if a known + starting point is not found, or if a known later code unit is not present. + However, there is an option (settable at compile time) that disables + these, for testing and for ensuring that all callouts do actually occur. + The optimizations must also be avoided when restarting a DFA match. */ + + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && + (options & PCRE2_DFA_RESTART) == 0) + { + PCRE2_SPTR save_end_subject = end_subject; + + /* If firstline is TRUE, the start of the match is constrained to the first + line of a multiline string. That is, the match must be before or at the + first newline. Implement this by temporarily adjusting end_subject so that + we stop the optimization scans at a newline. If the match fails at the + newline, later code breaks this loop. */ + + if (firstline) + { + PCRE2_SPTR t = start_match; +#ifdef SUPPORT_UNICODE + if (utf) + { + while (t < mb->end_subject && !IS_NEWLINE(t)) + { + t++; + ACROSSCHAR(t < end_subject, *t, t++); + } + } + else +#endif + while (t < mb->end_subject && !IS_NEWLINE(t)) t++; + end_subject = t; + } + + /* Advance to a unique first code unit if there is one. */ + + if (has_first_cu) + { + PCRE2_UCHAR smc; + if (first_cu != first_cu2) + while (start_match < end_subject && + (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) + start_match++; + else + while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu) + start_match++; + } + + /* Or to just after a linebreak for a multiline match */ + + else if (startline) + { + if (start_match > mb->start_subject + start_offset) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + { + start_match++; + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); + } + } + else +#endif + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + start_match++; + + /* If we have just passed a CR and the newline option is ANY or + ANYCRLF, and we are now at a LF, advance the match position by one more + code unit. */ + + if (start_match[-1] == CHAR_CR && + (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) && + start_match < end_subject && + UCHAR21TEST(start_match) == CHAR_NL) + start_match++; + } + } + + /* Or to a non-unique first code unit if any have been identified. The + bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all + code units greater than 254 set the 255 bit. */ + + else if (start_bits != NULL) + { + while (start_match < end_subject) + { + register uint32_t c = UCHAR21TEST(start_match); +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) c = 255; +#endif + if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + start_match++; + } + } + + /* Restore fudged end_subject */ + + end_subject = save_end_subject; + + /* The following two optimizations are disabled for partial matching. */ + + if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0) + { + /* The minimum matching length is a lower bound; no actual string of that + length may actually match the pattern. Although the value is, strictly, + in characters, we treat it as code units to avoid spending too much time + in this optimization. */ + + if (end_subject - start_match < re->minlength) return PCRE2_ERROR_NOMATCH; + + /* If req_cu is set, we know that that code unit must appear in the + subject for the match to succeed. If the first code unit is set, req_cu + must be later in the subject; otherwise the test starts at the match + point. This optimization can save a huge amount of backtracking in + patterns with nested unlimited repeats that aren't going to match. + Writing separate code for cased/caseless versions makes it go faster, as + does using an autoincrement and backing off on a match. + + HOWEVER: when the subject string is very, very long, searching to its end + can take a long time, and give bad performance on quite ordinary + patterns. This showed up when somebody was matching something like + /^\d+C/ on a 32-megabyte string... so we don't do this when the string is + sufficiently long. */ + + if (has_req_cu && end_subject - start_match < REQ_CU_MAX) + { + register PCRE2_SPTR p = start_match + (has_first_cu? 1:0); + + /* We don't need to repeat the search if we haven't yet reached the + place we found it at last time. */ + + if (p > req_cu_ptr) + { + if (req_cu != req_cu2) + { + while (p < end_subject) + { + register uint32_t pp = UCHAR21INCTEST(p); + if (pp == req_cu || pp == req_cu2) { p--; break; } + } + } + else + { + while (p < end_subject) + { + if (UCHAR21INCTEST(p) == req_cu) { p--; break; } + } + } + + /* If we can't find the required code unit, break the matching loop, + forcing a match failure. */ + + if (p >= end_subject) break; + + /* If we have found the required code unit, save the point where we + found it, so that we don't search again next time round the loop if + the start hasn't passed this code unit yet. */ + + req_cu_ptr = p; + } + } + } + } + + /* ------------ End of start of match optimizations ------------ */ + + /* Give no match if we have passed the bumpalong limit. */ + + if (start_match > bumpalong_limit) break; + + /* OK, now we can do the business */ + + mb->start_used_ptr = start_match; + mb->last_used_ptr = start_match; + mb->recursive = NULL; + + rc = internal_dfa_match( + mb, /* fixed match data */ + mb->start_code, /* this subexpression's code */ + start_match, /* where we currently are */ + start_offset, /* start offset in subject */ + match_data->ovector, /* offset vector */ + match_data->oveccount * 2, /* actual size of same */ + workspace, /* workspace vector */ + wscount, /* size of same */ + 0); /* function recurse level */ + + /* Anything other than "no match" means we are done, always; otherwise, carry + on only if not anchored. */ + + if (rc != PCRE2_ERROR_NOMATCH || anchored) + { + if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0) + { + match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject); + match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject); + } + match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject); + match_data->rightchar = mb->last_used_ptr - subject; + match_data->startchar = (PCRE2_SIZE)(start_match - subject); + match_data->rc = rc; + return rc; + } + + /* Advance to the next subject character unless we are at the end of a line + and firstline is set. */ + + if (firstline && IS_NEWLINE(start_match)) break; + start_match++; +#ifdef SUPPORT_UNICODE + if (utf) + { + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); + } +#endif + if (start_match > end_subject) break; + + /* If we have just passed a CR and we are now at a LF, and the pattern does + not contain any explicit matches for \r or \n, and the newline option is CRLF + or ANY or ANYCRLF, advance the match position by one more character. */ + + if (UCHAR21TEST(start_match - 1) == CHAR_CR && + start_match < end_subject && + UCHAR21TEST(start_match) == CHAR_NL && + (re->flags & PCRE2_HASCRORLF) == 0 && + (mb->nltype == NLTYPE_ANY || + mb->nltype == NLTYPE_ANYCRLF || + mb->nllen == 2)) + start_match++; + + } /* "Bumpalong" loop */ + + +return PCRE2_ERROR_NOMATCH; +} + +/* End of pcre2_dfa_match.c */ diff --git a/pcre2/src/pcre2_error.c b/pcre2/src/pcre2_error.c new file mode 100644 index 000000000..6b4756aec --- /dev/null +++ b/pcre2/src/pcre2_error.c @@ -0,0 +1,321 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + +#define STRING(a) # a +#define XSTRING(s) STRING(s) + +/* The texts of compile-time error messages. Compile-time error numbers start +at COMPILE_ERROR_BASE (100). + +This used to be a table of strings, but in order to reduce the number of +relocations needed when a shared library is loaded dynamically, it is now one +long string. We cannot use a table of offsets, because the lengths of inserts +such as XSTRING(MAX_NAME_SIZE) are not known. Instead, +pcre2_get_error_message() counts through to the one it wants - this isn't a +performance issue because these strings are used only when there is an error. + +Each substring ends with \0 to insert a null character. This includes the final +substring, so that the whole string ends with \0\0, which can be detected when +counting through. */ + +static const char compile_error_texts[] = + "no error\0" + "\\ at end of pattern\0" + "\\c at end of pattern\0" + "unrecognized character follows \\\0" + "numbers out of order in {} quantifier\0" + /* 5 */ + "number too big in {} quantifier\0" + "missing terminating ] for character class\0" + "invalid escape sequence in character class\0" + "range out of order in character class\0" + "quantifier does not follow a repeatable item\0" + /* 10 */ + "internal error: unexpected repeat\0" + "unrecognized character after (? or (?-\0" + "POSIX named classes are supported only within a class\0" + "POSIX collating elements are not supported\0" + "missing closing parenthesis\0" + /* 15 */ + "reference to non-existent subpattern\0" + "pattern passed as NULL\0" + "unrecognised compile-time option bit(s)\0" + "missing ) after (?# comment\0" + "parentheses are too deeply nested\0" + /* 20 */ + "regular expression is too large\0" + "failed to allocate heap memory\0" + "unmatched closing parenthesis\0" + "internal error: code overflow\0" + "letter or underscore expected after (?< or (?'\0" + /* 25 */ + "lookbehind assertion is not fixed length\0" + "malformed number or name after (?(\0" + "conditional group contains more than two branches\0" + "assertion expected after (?( or (?(?C)\0" + "(?R or (?[+-]digits must be followed by )\0" + /* 30 */ + "unknown POSIX class name\0" + "internal error in pcre2_study(): should not occur\0" + "this version of PCRE2 does not have Unicode support\0" + "parentheses are too deeply nested (stack check)\0" + "character code point value in \\x{} or \\o{} is too large\0" + /* 35 */ + "invalid condition (?(0)\0" + "\\C is not allowed in a lookbehind assertion\0" + "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" + "number after (?C is greater than 255\0" + "closing parenthesis for (?C expected\0" + /* 40 */ + "invalid escape sequence in (*VERB) name\0" + "unrecognized character after (?P\0" + "syntax error in subpattern name (missing terminator)\0" + "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0" + "group name must start with a non-digit\0" + /* 45 */ + "this version of PCRE2 does not have support for \\P, \\p, or \\X\0" + "malformed \\P or \\p sequence\0" + "unknown property name after \\P or \\p\0" + "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0" + "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" + /* 50 */ + "invalid range in character class\0" + "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" + "internal error: overran compiling workspace\0" + "internal error: previously-checked referenced subpattern not found\0" + "DEFINE group contains more than one branch\0" + /* 55 */ + "missing opening brace after \\o\0" + "internal error: unknown newline setting\0" + "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" + "a numbered reference must not be zero\0" + "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" + /* 60 */ + "(*VERB) not recognized or malformed\0" + "number is too big\0" + "subpattern name expected\0" + "digit expected after (?+\0" + "non-octal character in \\o{} (closing brace missing?)\0" + /* 65 */ + "different names for subpatterns of the same number are not allowed\0" + "(*MARK) must have an argument\0" + "non-hex character in \\x{} (closing brace missing?)\0" +#ifndef EBCDIC + "\\c must be followed by a printable ASCII character\0" +#else + "\\c must be followed by a letter or one of [\\]^_?\0" +#endif + "\\k is not followed by a braced, angle-bracketed, or quoted name\0" + /* 70 */ + "internal error: unknown opcode in find_fixedlength()\0" + "\\N is not supported in a class\0" + "SPARE ERROR\0" + "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0" + "using UTF is disabled by the application\0" + /* 75 */ + "using UCP is disabled by the application\0" + "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" + "character code point value in \\u.... sequence is too large\0" + "digits missing in \\x{} or \\o{}\0" + "syntax error in (?(VERSION condition\0" + /* 80 */ + "internal error: unknown opcode in auto_possessify()\0" + "missing terminating delimiter for callout with string argument\0" + "unrecognized string delimiter follows (?C\0" + "using \\C is disabled by the application\0" + "(?| and/or (?J: or (?x: parentheses are too deeply nested\0" + /* 85 */ + "using \\C is disabled in this PCRE2 library\0" + "regular expression is too complicated\0" + "lookbehind assertion is too long\0" + "pattern string is longer than the limit set by the application\0" + ; + +/* Match-time and UTF error texts are in the same format. */ + +static const char match_error_texts[] = + "no error\0" + "no match\0" + "partial match\0" + "UTF-8 error: 1 byte missing at end\0" + "UTF-8 error: 2 bytes missing at end\0" + /* 5 */ + "UTF-8 error: 3 bytes missing at end\0" + "UTF-8 error: 4 bytes missing at end\0" + "UTF-8 error: 5 bytes missing at end\0" + "UTF-8 error: byte 2 top bits not 0x80\0" + "UTF-8 error: byte 3 top bits not 0x80\0" + /* 10 */ + "UTF-8 error: byte 4 top bits not 0x80\0" + "UTF-8 error: byte 5 top bits not 0x80\0" + "UTF-8 error: byte 6 top bits not 0x80\0" + "UTF-8 error: 5-byte character is not allowed (RFC 3629)\0" + "UTF-8 error: 6-byte character is not allowed (RFC 3629)\0" + /* 15 */ + "UTF-8 error: code points greater than 0x10ffff are not defined\0" + "UTF-8 error: code points 0xd800-0xdfff are not defined\0" + "UTF-8 error: overlong 2-byte sequence\0" + "UTF-8 error: overlong 3-byte sequence\0" + "UTF-8 error: overlong 4-byte sequence\0" + /* 20 */ + "UTF-8 error: overlong 5-byte sequence\0" + "UTF-8 error: overlong 6-byte sequence\0" + "UTF-8 error: isolated byte with 0x80 bit set\0" + "UTF-8 error: illegal byte (0xfe or 0xff)\0" + "UTF-16 error: missing low surrogate at end\0" + /* 25 */ + "UTF-16 error: invalid low surrogate\0" + "UTF-16 error: isolated low surrogate\0" + "UTF-32 error: code points 0xd800-0xdfff are not defined\0" + "UTF-32 error: code points greater than 0x10ffff are not defined\0" + "bad data value\0" + /* 30 */ + "patterns do not all use the same character tables\0" + "magic number missing\0" + "pattern compiled in wrong mode: 8/16/32-bit error\0" + "bad offset value\0" + "bad option value\0" + /* 35 */ + "invalid replacement string\0" + "bad offset into UTF string\0" + "callout error code\0" /* Never returned by PCRE2 itself */ + "invalid data in workspace for DFA restart\0" + "too much recursion for DFA matching\0" + /* 40 */ + "backreference condition or recursion test is not supported for DFA matching\0" + "function is not supported for DFA matching\0" + "pattern contains an item that is not supported for DFA matching\0" + "workspace size exceeded in DFA matching\0" + "internal error - pattern overwritten?\0" + /* 45 */ + "bad JIT option\0" + "JIT stack limit reached\0" + "match limit exceeded\0" + "no more memory\0" + "unknown substring\0" + /* 50 */ + "non-unique substring name\0" + "NULL argument passed\0" + "nested recursion at the same subject position\0" + "recursion limit exceeded\0" + "requested value is not available\0" + /* 55 */ + "requested value is not set\0" + "offset limit set without PCRE2_USE_OFFSET_LIMIT\0" + "bad escape sequence in replacement string\0" + "expected closing curly bracket in replacement string\0" + "bad substitution in replacement string\0" + /* 60 */ + "match with end before start is not supported\0" + "too many replacements (more than INT_MAX)\0" + ; + + +/************************************************* +* Return error message * +*************************************************/ + +/* This function copies an error message into a buffer whose units are of an +appropriate width. Error numbers are positive for compile-time errors, and +negative for match-time errors (except for UTF errors), but the numbers are all +distinct. + +Arguments: + enumber error number + buffer where to put the message (zero terminated) + size size of the buffer + +Returns: length of message if all is well + negative on error +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, size_t size) +{ +char xbuff[128]; +const char *message; +size_t i; +uint32_t n; + +if (size == 0) return PCRE2_ERROR_NOMEMORY; + +if (enumber > COMPILE_ERROR_BASE) /* Compile error */ + { + message = compile_error_texts; + n = enumber - COMPILE_ERROR_BASE; + } +else /* Match or UTF error */ + { + message = match_error_texts; + n = -enumber; + } + +for (; n > 0; n--) + { + while (*message++ != CHAR_NULL) {}; + if (*message == CHAR_NULL) + { + sprintf(xbuff, "No text for error %d", enumber); + break; + } + } + +for (i = 0; *message != 0; i++) + { + if (i >= size - 1) + { + buffer[i] = 0; /* Terminate partial message */ + return PCRE2_ERROR_NOMEMORY; + } + buffer[i] = *message++; + } + +buffer[i] = 0; +return i; +} + +/* End of pcre2_error.c */ diff --git a/pcre2/src/pcre2_find_bracket.c b/pcre2/src/pcre2_find_bracket.c new file mode 100644 index 000000000..803e71976 --- /dev/null +++ b/pcre2/src/pcre2_find_bracket.c @@ -0,0 +1,218 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains a single function that scans through a compiled pattern +until it finds a capturing bracket with the given number, or, if the number is +negative, an instance of OP_REVERSE for a lookbehind. The function is called +from pcre2_compile.c and also from pcre2_study.c when finding the minimum +matching length. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + +/************************************************* +* Scan compiled regex for specific bracket * +*************************************************/ + +/* +Arguments: + code points to start of expression + utf TRUE in UTF mode + number the required bracket number or negative to find a lookbehind + +Returns: pointer to the opcode for the bracket, or NULL if not found +*/ + +PCRE2_SPTR +PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number) +{ +for (;;) + { + register PCRE2_UCHAR c = *code; + + if (c == OP_END) return NULL; + + /* XCLASS is used for classes that cannot be represented just by a bit map. + This includes negated single high-valued characters. CALLOUT_STR is used for + callouts with string arguments. In both cases the length in the table is + zero; the actual length is stored in the compiled code. */ + + if (c == OP_XCLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + + /* Handle lookbehind */ + + else if (c == OP_REVERSE) + { + if (number < 0) return (PCRE2_UCHAR *)code; + code += PRIV(OP_lengths)[c]; + } + + /* Handle capturing bracket */ + + else if (c == OP_CBRA || c == OP_SCBRA || + c == OP_CBRAPOS || c == OP_SCBRAPOS) + { + int n = (int)GET2(code, 1+LINK_SIZE); + if (n == number) return (PCRE2_UCHAR *)code; + code += PRIV(OP_lengths)[c]; + } + + /* Otherwise, we can get the item's length from the table, except that for + repeated character types, we have to test for \p and \P, which have an extra + two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we + must add in its length. */ + + else + { + switch(c) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be + followed by a multi-byte character. The length in the table is a minimum, so + we have to arrange to skip the extra bytes. */ + +#ifdef MAYBE_UTF_MULTI + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_PLUS: + case OP_PLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif /* MAYBE_UTF_MULTI */ + } + } +} + +/* End of pcre2_find_bracket.c */ diff --git a/pcre2/src/pcre2_internal.h b/pcre2/src/pcre2_internal.h new file mode 100644 index 000000000..7c9f66cc0 --- /dev/null +++ b/pcre2/src/pcre2_internal.h @@ -0,0 +1,1944 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* We do not support both EBCDIC and Unicode at the same time. The "configure" +script prevents both being selected, but not everybody uses "configure". EBCDIC +is only supported for the 8-bit library, but the check for this has to be later +in this file, because the first part is not width-dependent, and is included by +pcre2test.c with CODE_UNIT_WIDTH == 0. */ + +#if defined EBCDIC && defined SUPPORT_UNICODE +#error The use of both EBCDIC and SUPPORT_UNICODE is not supported. +#endif + +/* Standard C headers */ + +#include +#include +#include +#include +#include +#include + +/* Macros to make boolean values more obvious. The #ifndef is to pacify +compiler warnings in environments where these macros are defined elsewhere. +Unfortunately, there is no way to do the same for the typedef. */ + +typedef int BOOL; +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +/* Valgrind (memcheck) support */ + +#ifdef SUPPORT_VALGRIND +#include +#endif + +/* When compiling a DLL for Windows, the exported symbols have to be declared +using some MS magic. I found some useful information on this web page: +http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the +information there, using __declspec(dllexport) without "extern" we have a +definition; with "extern" we have a declaration. The settings here override the +setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL, +which is all that is needed for applications (they just import the symbols). We +use: + + PCRE2_EXP_DECL for declarations + PCRE2_EXP_DEFN for definitions + +The reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test, +which is an application, but needs to import this file in order to "peek" at +internals, can #include pcre2.h first to get an application's-eye view. + +In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon, +special-purpose environments) might want to stick other stuff in front of +exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN +only if it is not already set. */ + +#ifndef PCRE2_EXP_DECL +# ifdef _WIN32 +# ifndef PCRE2_STATIC +# define PCRE2_EXP_DECL extern __declspec(dllexport) +# define PCRE2_EXP_DEFN __declspec(dllexport) +# else +# define PCRE2_EXP_DECL extern +# define PCRE2_EXP_DEFN +# endif +# else +# ifdef __cplusplus +# define PCRE2_EXP_DECL extern "C" +# else +# define PCRE2_EXP_DECL extern +# endif +# ifndef PCRE2_EXP_DEFN +# define PCRE2_EXP_DEFN PCRE2_EXP_DECL +# endif +# endif +#endif + +/* Include the public PCRE2 header and the definitions of UCP character +property values. This must follow the setting of PCRE2_EXP_DECL above. */ + +#include "pcre2.h" +#include "pcre2_ucp.h" + +/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced +with a custom type. This makes it possible, for example, to allow pcre2_match() +to process subject strings that are discontinuous by using a smart pointer +class. It must always be possible to inspect all of the subject string in +pcre2_match() because of the way it backtracks. */ + +/* WARNING: This is as yet untested for PCRE2. */ + +#ifdef CUSTOM_SUBJECT_PTR +#undef PCRE2_SPTR +#define PCRE2_SPTR CUSTOM_SUBJECT_PTR +#endif + +/* When compiling with the MSVC compiler, it is sometimes necessary to include +a "calling convention" before exported function names. (This is secondhand +information; I know nothing about MSVC myself). For example, something like + + void __cdecl function(....) + +might be needed. In order so make this easy, all the exported functions have +PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not +set, we ensure here that it has no effect. */ + +#ifndef PCRE2_CALL_CONVENTION +#define PCRE2_CALL_CONVENTION +#endif + +/* When checking for integer overflow in pcre2_compile(), we need to handle +large integers. If a 64-bit integer type is available, we can use that. +Otherwise we have to cast to double, which of course requires floating point +arithmetic. Handle this by defining a macro for the appropriate type. If +stdint.h is available, include it; it may define INT64_MAX. Systems that do not +have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set +by "configure". */ + +#if defined HAVE_STDINT_H +#include +#elif defined HAVE_INTTYPES_H +#include +#endif + +#if defined INT64_MAX || defined int64_t +#define INT64_OR_DOUBLE int64_t +#else +#define INT64_OR_DOUBLE double +#endif + +/* When compiling for use with the Virtual Pascal compiler, these functions +need to have their names changed. PCRE must be compiled with the -DVPCOMPAT +option on the command line. */ + +#ifdef VPCOMPAT +#define strlen(s) _strlen(s) +#define strncmp(s1,s2,m) _strncmp(s1,s2,m) +#define memcmp(s,c,n) _memcmp(s,c,n) +#define memcpy(d,s,n) _memcpy(d,s,n) +#define memmove(d,s,n) _memmove(d,s,n) +#define memset(s,c,n) _memset(s,c,n) +#else /* VPCOMPAT */ + +/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), +define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY +is set. Otherwise, include an emulating function for those systems that have +neither (there some non-Unix environments where this is the case). */ + +#ifndef HAVE_MEMMOVE +#undef memmove /* some systems may have a macro */ +#ifdef HAVE_BCOPY +#define memmove(a, b, c) bcopy(b, a, c) +#else /* HAVE_BCOPY */ +static void * +pcre_memmove(void *d, const void *s, size_t n) +{ +size_t i; +unsigned char *dest = (unsigned char *)d; +const unsigned char *src = (const unsigned char *)s; +if (dest > src) + { + dest += n; + src += n; + for (i = 0; i < n; ++i) *(--dest) = *(--src); + return (void *)dest; + } +else + { + for (i = 0; i < n; ++i) *dest++ = *src++; + return (void *)(dest - n); + } +} +#define memmove(a, b, c) pcre_memmove(a, b, c) +#endif /* not HAVE_BCOPY */ +#endif /* not HAVE_MEMMOVE */ +#endif /* not VPCOMPAT */ + +/* External (in the C sense) functions and tables that are private to the +libraries are always referenced using the PRIV macro. This makes it possible +for pcre2test.c to include some of the source files from the libraries using a +different PRIV definition to avoid name clashes. It also makes it clear in the +code that a non-static object is being referenced. */ + +#ifndef PRIV +#define PRIV(name) _pcre2_##name +#endif + +/* This is an unsigned int value that no UTF character can ever have, as +Unicode doesn't go beyond 0x0010ffff. */ + +#define NOTACHAR 0xffffffff + +/* This is the largest valid UTF/Unicode code point. */ + +#define MAX_UTF_CODE_POINT 0x10ffff + +/* Compile-time errors are added to this value. As they are documented, it +should probably never be changed. */ + +#define COMPILE_ERROR_BASE 100 + +/* Define the default BSR convention. */ + +#ifdef BSR_ANYCRLF +#define BSR_DEFAULT PCRE2_BSR_ANYCRLF +#else +#define BSR_DEFAULT PCRE2_BSR_UNICODE +#endif + + +/* ---------------- Basic UTF-8 macros ---------------- */ + +/* These UTF-8 macros are always defined because they are used in pcre2test for +handling wide characters in 16-bit and 32-bit modes, even if an 8-bit library +is not supported. */ + +/* Tests whether a UTF-8 code point needs extra bytes to decode. */ + +#define HASUTF8EXTRALEN(c) ((c) >= 0xc0) + +/* The following macros were originally written in the form of loops that used +data from the tables whose names start with PRIV(utf8_table). They were +rewritten by a user so as not to use loops, because in some environments this +gives a significant performance advantage, and it seems never to do any harm. +*/ + +/* Base macro to pick up the remaining bytes of a UTF-8 character, not +advancing the pointer. */ + +#define GETUTF8(c, eptr) \ + { \ + if ((c & 0x20) == 0) \ + c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ + else if ((c & 0x10) == 0) \ + c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + else if ((c & 0x08) == 0) \ + c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ + ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ + else if ((c & 0x04) == 0) \ + c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ + ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ + (eptr[4] & 0x3f); \ + else \ + c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ + ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ + ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + } + +/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing +the pointer. */ + +#define GETUTF8INC(c, eptr) \ + { \ + if ((c & 0x20) == 0) \ + c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \ + else if ((c & 0x10) == 0) \ + { \ + c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \ + eptr += 2; \ + } \ + else if ((c & 0x08) == 0) \ + { \ + c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \ + ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + eptr += 3; \ + } \ + else if ((c & 0x04) == 0) \ + { \ + c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \ + ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \ + (eptr[3] & 0x3f); \ + eptr += 4; \ + } \ + else \ + { \ + c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \ + ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \ + ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \ + eptr += 5; \ + } \ + } + +/* Base macro to pick up the remaining bytes of a UTF-8 character, not +advancing the pointer, incrementing the length. */ + +#define GETUTF8LEN(c, eptr, len) \ + { \ + if ((c & 0x20) == 0) \ + { \ + c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ + len++; \ + } \ + else if ((c & 0x10) == 0) \ + { \ + c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + len += 2; \ + } \ + else if ((c & 0x08) == 0) \ + {\ + c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ + ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ + len += 3; \ + } \ + else if ((c & 0x04) == 0) \ + { \ + c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ + ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ + (eptr[4] & 0x3f); \ + len += 4; \ + } \ + else \ + {\ + c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ + ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ + ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + len += 5; \ + } \ + } + +/* --------------- Whitespace macros ---------------- */ + +/* Tests for Unicode horizontal and vertical whitespace characters must check a +number of different values. Using a switch statement for this generates the +fastest code (no loop, no memory access), and there are several places in the +interpreter code where this happens. In order to ensure that all the case lists +remain in step, we use macros so that there is only one place where the lists +are defined. + +These values are also required as lists in pcre2_compile.c when processing \h, +\H, \v and \V in a character class. The lists are defined in pcre2_tables.c, +but macros that define the values are here so that all the definitions are +together. The lists must be in ascending character order, terminated by +NOTACHAR (which is 0xffffffff). + +Any changes should ensure that the various macros are kept in step with each +other. NOTE: The values also appear in pcre2_jit_compile.c. */ + +/* -------------- ASCII/Unicode environments -------------- */ + +#ifndef EBCDIC + +/* Character U+180E (Mongolian Vowel Separator) is not included in the list of +spaces in the Unicode file PropList.txt, and Perl does not recognize it as a +space. However, in many other sources it is listed as a space and has been in +PCRE for a long time. */ + +#define HSPACE_LIST \ + CHAR_HT, CHAR_SPACE, CHAR_NBSP, \ + 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \ + 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \ + NOTACHAR + +#define HSPACE_MULTIBYTE_CASES \ + case 0x1680: /* OGHAM SPACE MARK */ \ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \ + case 0x2000: /* EN QUAD */ \ + case 0x2001: /* EM QUAD */ \ + case 0x2002: /* EN SPACE */ \ + case 0x2003: /* EM SPACE */ \ + case 0x2004: /* THREE-PER-EM SPACE */ \ + case 0x2005: /* FOUR-PER-EM SPACE */ \ + case 0x2006: /* SIX-PER-EM SPACE */ \ + case 0x2007: /* FIGURE SPACE */ \ + case 0x2008: /* PUNCTUATION SPACE */ \ + case 0x2009: /* THIN SPACE */ \ + case 0x200A: /* HAIR SPACE */ \ + case 0x202f: /* NARROW NO-BREAK SPACE */ \ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \ + case 0x3000 /* IDEOGRAPHIC SPACE */ + +#define HSPACE_BYTE_CASES \ + case CHAR_HT: \ + case CHAR_SPACE: \ + case CHAR_NBSP + +#define HSPACE_CASES \ + HSPACE_BYTE_CASES: \ + HSPACE_MULTIBYTE_CASES + +#define VSPACE_LIST \ + CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR + +#define VSPACE_MULTIBYTE_CASES \ + case 0x2028: /* LINE SEPARATOR */ \ + case 0x2029 /* PARAGRAPH SEPARATOR */ + +#define VSPACE_BYTE_CASES \ + case CHAR_LF: \ + case CHAR_VT: \ + case CHAR_FF: \ + case CHAR_CR: \ + case CHAR_NEL + +#define VSPACE_CASES \ + VSPACE_BYTE_CASES: \ + VSPACE_MULTIBYTE_CASES + +/* -------------- EBCDIC environments -------------- */ + +#else +#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR + +#define HSPACE_BYTE_CASES \ + case CHAR_HT: \ + case CHAR_SPACE: \ + case CHAR_NBSP + +#define HSPACE_CASES HSPACE_BYTE_CASES + +#ifdef EBCDIC_NL25 +#define VSPACE_LIST \ + CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR +#else +#define VSPACE_LIST \ + CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR +#endif + +#define VSPACE_BYTE_CASES \ + case CHAR_LF: \ + case CHAR_VT: \ + case CHAR_FF: \ + case CHAR_CR: \ + case CHAR_NEL + +#define VSPACE_CASES VSPACE_BYTE_CASES +#endif /* EBCDIC */ + +/* -------------- End of whitespace macros -------------- */ + + +/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF, +"any" and "anycrlf" at present). The following macros are used to package up +testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various +modules to indicate in which datablock the parameters exist, and what the +start/end of string field names are. */ + +#define NLTYPE_FIXED 0 /* Newline is a fixed length string */ +#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */ +#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */ + +/* This macro checks for a newline at the given position */ + +#define IS_NEWLINE(p) \ + ((NLBLOCK->nltype != NLTYPE_FIXED)? \ + ((p) < NLBLOCK->PSEND && \ + PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ + &(NLBLOCK->nllen), utf)) \ + : \ + ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ + UCHAR21TEST(p) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \ + ) \ + ) + +/* This macro checks for a newline immediately preceding the given position */ + +#define WAS_NEWLINE(p) \ + ((NLBLOCK->nltype != NLTYPE_FIXED)? \ + ((p) > NLBLOCK->PSSTART && \ + PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ + &(NLBLOCK->nllen), utf)) \ + : \ + ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ + UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ + ) \ + ) + +/* Private flags containing information about the compiled pattern. The first +three must not be changed, because whichever is set is actually the number of +bytes in a code unit in that mode. */ + +#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */ +#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */ +#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */ +#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */ +#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */ +#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */ +#define PCRE2_LASTSET 0x00000080 /* last code unit is set */ +#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */ +#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */ +#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */ +#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */ +#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */ +#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */ +#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */ +#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */ +#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */ +#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */ +#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */ +#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */ +#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */ +#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */ +#define PCRE2_HASBKC 0x00400000 /* contains \C */ + +#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32) + +/* Values for the matchedby field in a match data block. */ + +enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */ + PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */ + PCRE2_MATCHEDBY_JIT }; /* pcre2_jit_match() */ + +/* Magic number to provide a small check against being handed junk. */ + +#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ + +/* The maximum remaining length of subject we are prepared to search for a +req_unit match. */ + +#define REQ_CU_MAX 1000 + +/* Bit definitions for entries in the pcre_ctypes table. */ + +#define ctype_space 0x01 +#define ctype_letter 0x02 +#define ctype_digit 0x04 +#define ctype_xdigit 0x08 +#define ctype_word 0x10 /* alphanumeric or '_' */ +#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ + +/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set +of bits for a class map. Some classes are built by combining these tables. */ + +#define cbit_space 0 /* [:space:] or \s */ +#define cbit_xdigit 32 /* [:xdigit:] */ +#define cbit_digit 64 /* [:digit:] or \d */ +#define cbit_upper 96 /* [:upper:] */ +#define cbit_lower 128 /* [:lower:] */ +#define cbit_word 160 /* [:word:] or \w */ +#define cbit_graph 192 /* [:graph:] */ +#define cbit_print 224 /* [:print:] */ +#define cbit_punct 256 /* [:punct:] */ +#define cbit_cntrl 288 /* [:cntrl:] */ +#define cbit_length 320 /* Length of the cbits table */ + +/* Offsets of the various tables from the base tables pointer, and +total length. */ + +#define lcc_offset 0 +#define fcc_offset 256 +#define cbits_offset 512 +#define ctypes_offset (cbits_offset + cbit_length) +#define tables_length (ctypes_offset + 256) + + +/* -------------------- Character and string names ------------------------ */ + +/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal +character constants like '*' because the compiler would emit their EBCDIC code, +which is different from their ASCII/UTF-8 code. Instead we define macros for +the characters so that they always use the ASCII/UTF-8 code when UTF-8 support +is enabled. When UTF-8 support is not enabled, the definitions use character +literals. Both character and string versions of each character are needed, and +there are some longer strings as well. + +This means that, on EBCDIC platforms, the PCRE library can handle either +EBCDIC, or UTF-8, but not both. To support both in the same compiled library +would need different lookups depending on whether PCRE2_UTF was set or not. +This would make it impossible to use characters in switch/case statements, +which would reduce performance. For a theoretical use (which nobody has asked +for) in a minority area (EBCDIC platforms), this is not sensible. Any +application that did need both could compile two versions of the library, using +macros to give the functions distinct names. */ + +#ifndef SUPPORT_UNICODE + +/* UTF-8 support is not enabled; use the platform-dependent character literals +so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF +mode. Newline characters are problematic in EBCDIC. Though it has CR and LF +characters, a common practice has been to use its NL (0x15) character as the +line terminator in C-like processing environments. However, sometimes the LF +(0x25) character is used instead, according to this Unicode document: + +http://unicode.org/standard/reports/tr13/tr13-5.html + +PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 +instead. Whichever is *not* chosen is defined as NEL. + +In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the +same code point. */ + +#ifdef EBCDIC + +#ifndef EBCDIC_NL25 +#define CHAR_NL '\x15' +#define CHAR_NEL '\x25' +#define STR_NL "\x15" +#define STR_NEL "\x25" +#else +#define CHAR_NL '\x25' +#define CHAR_NEL '\x15' +#define STR_NL "\x25" +#define STR_NEL "\x15" +#endif + +#define CHAR_LF CHAR_NL +#define STR_LF STR_NL + +#define CHAR_ESC '\047' +#define CHAR_DEL '\007' +#define CHAR_NBSP ((unsigned char)'\x41') +#define STR_ESC "\047" +#define STR_DEL "\007" + +#else /* Not EBCDIC */ + +/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for +compatibility. NEL is the Unicode newline character; make sure it is +a positive value. */ + +#define CHAR_LF '\n' +#define CHAR_NL CHAR_LF +#define CHAR_NEL ((unsigned char)'\x85') +#define CHAR_ESC '\033' +#define CHAR_DEL '\177' +#define CHAR_NBSP ((unsigned char)'\xa0') + +#define STR_LF "\n" +#define STR_NL STR_LF +#define STR_NEL "\x85" +#define STR_ESC "\033" +#define STR_DEL "\177" + +#endif /* EBCDIC */ + +/* The remaining definitions work in both environments. */ + +#define CHAR_NULL '\0' +#define CHAR_HT '\t' +#define CHAR_VT '\v' +#define CHAR_FF '\f' +#define CHAR_CR '\r' +#define CHAR_BS '\b' +#define CHAR_BEL '\a' + +#define CHAR_SPACE ' ' +#define CHAR_EXCLAMATION_MARK '!' +#define CHAR_QUOTATION_MARK '"' +#define CHAR_NUMBER_SIGN '#' +#define CHAR_DOLLAR_SIGN '$' +#define CHAR_PERCENT_SIGN '%' +#define CHAR_AMPERSAND '&' +#define CHAR_APOSTROPHE '\'' +#define CHAR_LEFT_PARENTHESIS '(' +#define CHAR_RIGHT_PARENTHESIS ')' +#define CHAR_ASTERISK '*' +#define CHAR_PLUS '+' +#define CHAR_COMMA ',' +#define CHAR_MINUS '-' +#define CHAR_DOT '.' +#define CHAR_SLASH '/' +#define CHAR_0 '0' +#define CHAR_1 '1' +#define CHAR_2 '2' +#define CHAR_3 '3' +#define CHAR_4 '4' +#define CHAR_5 '5' +#define CHAR_6 '6' +#define CHAR_7 '7' +#define CHAR_8 '8' +#define CHAR_9 '9' +#define CHAR_COLON ':' +#define CHAR_SEMICOLON ';' +#define CHAR_LESS_THAN_SIGN '<' +#define CHAR_EQUALS_SIGN '=' +#define CHAR_GREATER_THAN_SIGN '>' +#define CHAR_QUESTION_MARK '?' +#define CHAR_COMMERCIAL_AT '@' +#define CHAR_A 'A' +#define CHAR_B 'B' +#define CHAR_C 'C' +#define CHAR_D 'D' +#define CHAR_E 'E' +#define CHAR_F 'F' +#define CHAR_G 'G' +#define CHAR_H 'H' +#define CHAR_I 'I' +#define CHAR_J 'J' +#define CHAR_K 'K' +#define CHAR_L 'L' +#define CHAR_M 'M' +#define CHAR_N 'N' +#define CHAR_O 'O' +#define CHAR_P 'P' +#define CHAR_Q 'Q' +#define CHAR_R 'R' +#define CHAR_S 'S' +#define CHAR_T 'T' +#define CHAR_U 'U' +#define CHAR_V 'V' +#define CHAR_W 'W' +#define CHAR_X 'X' +#define CHAR_Y 'Y' +#define CHAR_Z 'Z' +#define CHAR_LEFT_SQUARE_BRACKET '[' +#define CHAR_BACKSLASH '\\' +#define CHAR_RIGHT_SQUARE_BRACKET ']' +#define CHAR_CIRCUMFLEX_ACCENT '^' +#define CHAR_UNDERSCORE '_' +#define CHAR_GRAVE_ACCENT '`' +#define CHAR_a 'a' +#define CHAR_b 'b' +#define CHAR_c 'c' +#define CHAR_d 'd' +#define CHAR_e 'e' +#define CHAR_f 'f' +#define CHAR_g 'g' +#define CHAR_h 'h' +#define CHAR_i 'i' +#define CHAR_j 'j' +#define CHAR_k 'k' +#define CHAR_l 'l' +#define CHAR_m 'm' +#define CHAR_n 'n' +#define CHAR_o 'o' +#define CHAR_p 'p' +#define CHAR_q 'q' +#define CHAR_r 'r' +#define CHAR_s 's' +#define CHAR_t 't' +#define CHAR_u 'u' +#define CHAR_v 'v' +#define CHAR_w 'w' +#define CHAR_x 'x' +#define CHAR_y 'y' +#define CHAR_z 'z' +#define CHAR_LEFT_CURLY_BRACKET '{' +#define CHAR_VERTICAL_LINE '|' +#define CHAR_RIGHT_CURLY_BRACKET '}' +#define CHAR_TILDE '~' + +#define STR_HT "\t" +#define STR_VT "\v" +#define STR_FF "\f" +#define STR_CR "\r" +#define STR_BS "\b" +#define STR_BEL "\a" + +#define STR_SPACE " " +#define STR_EXCLAMATION_MARK "!" +#define STR_QUOTATION_MARK "\"" +#define STR_NUMBER_SIGN "#" +#define STR_DOLLAR_SIGN "$" +#define STR_PERCENT_SIGN "%" +#define STR_AMPERSAND "&" +#define STR_APOSTROPHE "'" +#define STR_LEFT_PARENTHESIS "(" +#define STR_RIGHT_PARENTHESIS ")" +#define STR_ASTERISK "*" +#define STR_PLUS "+" +#define STR_COMMA "," +#define STR_MINUS "-" +#define STR_DOT "." +#define STR_SLASH "/" +#define STR_0 "0" +#define STR_1 "1" +#define STR_2 "2" +#define STR_3 "3" +#define STR_4 "4" +#define STR_5 "5" +#define STR_6 "6" +#define STR_7 "7" +#define STR_8 "8" +#define STR_9 "9" +#define STR_COLON ":" +#define STR_SEMICOLON ";" +#define STR_LESS_THAN_SIGN "<" +#define STR_EQUALS_SIGN "=" +#define STR_GREATER_THAN_SIGN ">" +#define STR_QUESTION_MARK "?" +#define STR_COMMERCIAL_AT "@" +#define STR_A "A" +#define STR_B "B" +#define STR_C "C" +#define STR_D "D" +#define STR_E "E" +#define STR_F "F" +#define STR_G "G" +#define STR_H "H" +#define STR_I "I" +#define STR_J "J" +#define STR_K "K" +#define STR_L "L" +#define STR_M "M" +#define STR_N "N" +#define STR_O "O" +#define STR_P "P" +#define STR_Q "Q" +#define STR_R "R" +#define STR_S "S" +#define STR_T "T" +#define STR_U "U" +#define STR_V "V" +#define STR_W "W" +#define STR_X "X" +#define STR_Y "Y" +#define STR_Z "Z" +#define STR_LEFT_SQUARE_BRACKET "[" +#define STR_BACKSLASH "\\" +#define STR_RIGHT_SQUARE_BRACKET "]" +#define STR_CIRCUMFLEX_ACCENT "^" +#define STR_UNDERSCORE "_" +#define STR_GRAVE_ACCENT "`" +#define STR_a "a" +#define STR_b "b" +#define STR_c "c" +#define STR_d "d" +#define STR_e "e" +#define STR_f "f" +#define STR_g "g" +#define STR_h "h" +#define STR_i "i" +#define STR_j "j" +#define STR_k "k" +#define STR_l "l" +#define STR_m "m" +#define STR_n "n" +#define STR_o "o" +#define STR_p "p" +#define STR_q "q" +#define STR_r "r" +#define STR_s "s" +#define STR_t "t" +#define STR_u "u" +#define STR_v "v" +#define STR_w "w" +#define STR_x "x" +#define STR_y "y" +#define STR_z "z" +#define STR_LEFT_CURLY_BRACKET "{" +#define STR_VERTICAL_LINE "|" +#define STR_RIGHT_CURLY_BRACKET "}" +#define STR_TILDE "~" + +#define STRING_ACCEPT0 "ACCEPT\0" +#define STRING_COMMIT0 "COMMIT\0" +#define STRING_F0 "F\0" +#define STRING_FAIL0 "FAIL\0" +#define STRING_MARK0 "MARK\0" +#define STRING_PRUNE0 "PRUNE\0" +#define STRING_SKIP0 "SKIP\0" +#define STRING_THEN "THEN" + +#define STRING_alpha0 "alpha\0" +#define STRING_lower0 "lower\0" +#define STRING_upper0 "upper\0" +#define STRING_alnum0 "alnum\0" +#define STRING_ascii0 "ascii\0" +#define STRING_blank0 "blank\0" +#define STRING_cntrl0 "cntrl\0" +#define STRING_digit0 "digit\0" +#define STRING_graph0 "graph\0" +#define STRING_print0 "print\0" +#define STRING_punct0 "punct\0" +#define STRING_space0 "space\0" +#define STRING_word0 "word\0" +#define STRING_xdigit "xdigit" + +#define STRING_DEFINE "DEFINE" +#define STRING_VERSION "VERSION" +#define STRING_WEIRD_STARTWORD "[:<:]]" +#define STRING_WEIRD_ENDWORD "[:>:]]" + +#define STRING_CR_RIGHTPAR "CR)" +#define STRING_LF_RIGHTPAR "LF)" +#define STRING_CRLF_RIGHTPAR "CRLF)" +#define STRING_ANY_RIGHTPAR "ANY)" +#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" +#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" +#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" +#define STRING_UTF8_RIGHTPAR "UTF8)" +#define STRING_UTF16_RIGHTPAR "UTF16)" +#define STRING_UTF32_RIGHTPAR "UTF32)" +#define STRING_UTF_RIGHTPAR "UTF)" +#define STRING_UCP_RIGHTPAR "UCP)" +#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)" +#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)" +#define STRING_NO_JIT_RIGHTPAR "NO_JIT)" +#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" +#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)" +#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)" +#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" +#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION=" +#define STRING_MARK "MARK" + +#else /* SUPPORT_UNICODE */ + +/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This +works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode +only. */ + +#define CHAR_HT '\011' +#define CHAR_VT '\013' +#define CHAR_FF '\014' +#define CHAR_CR '\015' +#define CHAR_LF '\012' +#define CHAR_NL CHAR_LF +#define CHAR_NEL ((unsigned char)'\x85') +#define CHAR_BS '\010' +#define CHAR_BEL '\007' +#define CHAR_ESC '\033' +#define CHAR_DEL '\177' + +#define CHAR_NULL '\0' +#define CHAR_SPACE '\040' +#define CHAR_EXCLAMATION_MARK '\041' +#define CHAR_QUOTATION_MARK '\042' +#define CHAR_NUMBER_SIGN '\043' +#define CHAR_DOLLAR_SIGN '\044' +#define CHAR_PERCENT_SIGN '\045' +#define CHAR_AMPERSAND '\046' +#define CHAR_APOSTROPHE '\047' +#define CHAR_LEFT_PARENTHESIS '\050' +#define CHAR_RIGHT_PARENTHESIS '\051' +#define CHAR_ASTERISK '\052' +#define CHAR_PLUS '\053' +#define CHAR_COMMA '\054' +#define CHAR_MINUS '\055' +#define CHAR_DOT '\056' +#define CHAR_SLASH '\057' +#define CHAR_0 '\060' +#define CHAR_1 '\061' +#define CHAR_2 '\062' +#define CHAR_3 '\063' +#define CHAR_4 '\064' +#define CHAR_5 '\065' +#define CHAR_6 '\066' +#define CHAR_7 '\067' +#define CHAR_8 '\070' +#define CHAR_9 '\071' +#define CHAR_COLON '\072' +#define CHAR_SEMICOLON '\073' +#define CHAR_LESS_THAN_SIGN '\074' +#define CHAR_EQUALS_SIGN '\075' +#define CHAR_GREATER_THAN_SIGN '\076' +#define CHAR_QUESTION_MARK '\077' +#define CHAR_COMMERCIAL_AT '\100' +#define CHAR_A '\101' +#define CHAR_B '\102' +#define CHAR_C '\103' +#define CHAR_D '\104' +#define CHAR_E '\105' +#define CHAR_F '\106' +#define CHAR_G '\107' +#define CHAR_H '\110' +#define CHAR_I '\111' +#define CHAR_J '\112' +#define CHAR_K '\113' +#define CHAR_L '\114' +#define CHAR_M '\115' +#define CHAR_N '\116' +#define CHAR_O '\117' +#define CHAR_P '\120' +#define CHAR_Q '\121' +#define CHAR_R '\122' +#define CHAR_S '\123' +#define CHAR_T '\124' +#define CHAR_U '\125' +#define CHAR_V '\126' +#define CHAR_W '\127' +#define CHAR_X '\130' +#define CHAR_Y '\131' +#define CHAR_Z '\132' +#define CHAR_LEFT_SQUARE_BRACKET '\133' +#define CHAR_BACKSLASH '\134' +#define CHAR_RIGHT_SQUARE_BRACKET '\135' +#define CHAR_CIRCUMFLEX_ACCENT '\136' +#define CHAR_UNDERSCORE '\137' +#define CHAR_GRAVE_ACCENT '\140' +#define CHAR_a '\141' +#define CHAR_b '\142' +#define CHAR_c '\143' +#define CHAR_d '\144' +#define CHAR_e '\145' +#define CHAR_f '\146' +#define CHAR_g '\147' +#define CHAR_h '\150' +#define CHAR_i '\151' +#define CHAR_j '\152' +#define CHAR_k '\153' +#define CHAR_l '\154' +#define CHAR_m '\155' +#define CHAR_n '\156' +#define CHAR_o '\157' +#define CHAR_p '\160' +#define CHAR_q '\161' +#define CHAR_r '\162' +#define CHAR_s '\163' +#define CHAR_t '\164' +#define CHAR_u '\165' +#define CHAR_v '\166' +#define CHAR_w '\167' +#define CHAR_x '\170' +#define CHAR_y '\171' +#define CHAR_z '\172' +#define CHAR_LEFT_CURLY_BRACKET '\173' +#define CHAR_VERTICAL_LINE '\174' +#define CHAR_RIGHT_CURLY_BRACKET '\175' +#define CHAR_TILDE '\176' +#define CHAR_NBSP ((unsigned char)'\xa0') + +#define STR_HT "\011" +#define STR_VT "\013" +#define STR_FF "\014" +#define STR_CR "\015" +#define STR_NL "\012" +#define STR_BS "\010" +#define STR_BEL "\007" +#define STR_ESC "\033" +#define STR_DEL "\177" + +#define STR_SPACE "\040" +#define STR_EXCLAMATION_MARK "\041" +#define STR_QUOTATION_MARK "\042" +#define STR_NUMBER_SIGN "\043" +#define STR_DOLLAR_SIGN "\044" +#define STR_PERCENT_SIGN "\045" +#define STR_AMPERSAND "\046" +#define STR_APOSTROPHE "\047" +#define STR_LEFT_PARENTHESIS "\050" +#define STR_RIGHT_PARENTHESIS "\051" +#define STR_ASTERISK "\052" +#define STR_PLUS "\053" +#define STR_COMMA "\054" +#define STR_MINUS "\055" +#define STR_DOT "\056" +#define STR_SLASH "\057" +#define STR_0 "\060" +#define STR_1 "\061" +#define STR_2 "\062" +#define STR_3 "\063" +#define STR_4 "\064" +#define STR_5 "\065" +#define STR_6 "\066" +#define STR_7 "\067" +#define STR_8 "\070" +#define STR_9 "\071" +#define STR_COLON "\072" +#define STR_SEMICOLON "\073" +#define STR_LESS_THAN_SIGN "\074" +#define STR_EQUALS_SIGN "\075" +#define STR_GREATER_THAN_SIGN "\076" +#define STR_QUESTION_MARK "\077" +#define STR_COMMERCIAL_AT "\100" +#define STR_A "\101" +#define STR_B "\102" +#define STR_C "\103" +#define STR_D "\104" +#define STR_E "\105" +#define STR_F "\106" +#define STR_G "\107" +#define STR_H "\110" +#define STR_I "\111" +#define STR_J "\112" +#define STR_K "\113" +#define STR_L "\114" +#define STR_M "\115" +#define STR_N "\116" +#define STR_O "\117" +#define STR_P "\120" +#define STR_Q "\121" +#define STR_R "\122" +#define STR_S "\123" +#define STR_T "\124" +#define STR_U "\125" +#define STR_V "\126" +#define STR_W "\127" +#define STR_X "\130" +#define STR_Y "\131" +#define STR_Z "\132" +#define STR_LEFT_SQUARE_BRACKET "\133" +#define STR_BACKSLASH "\134" +#define STR_RIGHT_SQUARE_BRACKET "\135" +#define STR_CIRCUMFLEX_ACCENT "\136" +#define STR_UNDERSCORE "\137" +#define STR_GRAVE_ACCENT "\140" +#define STR_a "\141" +#define STR_b "\142" +#define STR_c "\143" +#define STR_d "\144" +#define STR_e "\145" +#define STR_f "\146" +#define STR_g "\147" +#define STR_h "\150" +#define STR_i "\151" +#define STR_j "\152" +#define STR_k "\153" +#define STR_l "\154" +#define STR_m "\155" +#define STR_n "\156" +#define STR_o "\157" +#define STR_p "\160" +#define STR_q "\161" +#define STR_r "\162" +#define STR_s "\163" +#define STR_t "\164" +#define STR_u "\165" +#define STR_v "\166" +#define STR_w "\167" +#define STR_x "\170" +#define STR_y "\171" +#define STR_z "\172" +#define STR_LEFT_CURLY_BRACKET "\173" +#define STR_VERTICAL_LINE "\174" +#define STR_RIGHT_CURLY_BRACKET "\175" +#define STR_TILDE "\176" + +#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" +#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" +#define STRING_F0 STR_F "\0" +#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" +#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" +#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" +#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" +#define STRING_THEN STR_T STR_H STR_E STR_N + +#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" +#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" +#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" +#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" +#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" +#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" +#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" +#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" +#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" +#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" +#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" +#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" +#define STRING_word0 STR_w STR_o STR_r STR_d "\0" +#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t + +#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E +#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N +#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET +#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET + +#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS +#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS +#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS +#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS +#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS +#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS +#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS +#define STRING_NO_JIT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS +#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS +#define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS +#define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS +#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN +#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN +#define STRING_MARK STR_M STR_A STR_R STR_K + +#endif /* SUPPORT_UNICODE */ + +/* -------------------- End of character and string names -------------------*/ + +/* -------------------- Definitions for compiled patterns -------------------*/ + +/* Codes for different types of Unicode property */ + +#define PT_ANY 0 /* Any property - matches all chars */ +#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ +#define PT_GC 2 /* Specified general characteristic (e.g. L) */ +#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ +#define PT_SC 4 /* Script (e.g. Han) */ +#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ +#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */ +#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ +#define PT_WORD 8 /* Word - L plus N plus underscore */ +#define PT_CLIST 9 /* Pseudo-property: match character list */ +#define PT_UCNC 10 /* Universal Character nameable character */ +#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */ + +/* The following special properties are used only in XCLASS items, when POSIX +classes are specified and PCRE_UCP is set - in other words, for Unicode +handling of these classes. They are not available via the \p or \P escapes like +those in the above list, and so they do not take part in the autopossessifying +table. */ + +#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */ +#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */ +#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */ + +/* Flag bits and data types for the extended class (OP_XCLASS) for classes that +contain characters with values greater than 255. */ + +#define XCL_NOT 0x01 /* Flag: this is a negative class */ +#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ +#define XCL_HASPROP 0x04 /* Flag: property checks are present. */ + +#define XCL_END 0 /* Marks end of individual items */ +#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ +#define XCL_RANGE 2 /* A range (two multibyte chars) follows */ +#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ +#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ + +/* Escape items that are just an encoding of a particular data value. These +appear in the escapes[] table in pcre2_compile.c as positive numbers. */ + +#ifndef ESC_a +#define ESC_a CHAR_BEL +#endif + +#ifndef ESC_e +#define ESC_e CHAR_ESC +#endif + +#ifndef ESC_f +#define ESC_f CHAR_FF +#endif + +#ifndef ESC_n +#define ESC_n CHAR_LF +#endif + +#ifndef ESC_r +#define ESC_r CHAR_CR +#endif + +/* We can't officially use ESC_t because it is a POSIX reserved identifier +(presumably because of all the others like size_t). */ + +#ifndef ESC_tee +#define ESC_tee CHAR_HT +#endif + +/* These are escaped items that aren't just an encoding of a particular data +value such as \n. They must have non-zero values, as check_escape() returns 0 +for a data character. In the escapes[] table in pcre2_compile.c their values +are negated in order to distinguish them from data values. + +They must appear here in the same order as in the opcode definitions below, up +to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL +mode rather than an escape sequence. It is also used for [^] in JavaScript +compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves +like \N. + +The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. +when PCRE_UCP is set and replacement of \d etc by \p sequences is required. +They must be contiguous, and remain in order so that the replacements can be +looked up from a table. + +Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in +check_escape(). There are two tests in the code for an escape +greater than ESC_b and less than ESC_Z to detect the types that may be +repeated. These are the types that consume characters. If any new escapes are +put in between that don't consume a character, that code will have to change. +*/ + +enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, + ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, + ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, + ESC_E, ESC_Q, ESC_g, ESC_k, + ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu }; + + +/********************** Opcode definitions ******************/ + +/****** NOTE NOTE NOTE ****** + +Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in +order to the list of escapes immediately above. Furthermore, values up to +OP_DOLLM must not be changed without adjusting the table called autoposstab in +pcre_compile.c + +Whenever this list is updated, the two macro definitions that follow must be +updated to match. The possessification table called "opcode_possessify" in +pcre_compile.c must also be updated, and also the tables called "coptable" +and "poptable" in pcre_dfa_exec.c. + +****** NOTE NOTE NOTE ******/ + + +/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive, +are used in a table for deciding whether a repeated character type can be +auto-possessified. */ + +#define FIRST_AUTOTAB_OP OP_NOT_DIGIT +#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI +#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM + +enum { + OP_END, /* 0 End of pattern */ + + /* Values corresponding to backslashed metacharacters */ + + OP_SOD, /* 1 Start of data: \A */ + OP_SOM, /* 2 Start of match (subject + offset): \G */ + OP_SET_SOM, /* 3 Set start of match (\K) */ + OP_NOT_WORD_BOUNDARY, /* 4 \B */ + OP_WORD_BOUNDARY, /* 5 \b */ + OP_NOT_DIGIT, /* 6 \D */ + OP_DIGIT, /* 7 \d */ + OP_NOT_WHITESPACE, /* 8 \S */ + OP_WHITESPACE, /* 9 \s */ + OP_NOT_WORDCHAR, /* 10 \W */ + OP_WORDCHAR, /* 11 \w */ + + OP_ANY, /* 12 Match any character except newline (\N) */ + OP_ALLANY, /* 13 Match any character */ + OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ + OP_NOTPROP, /* 15 \P (not Unicode property) */ + OP_PROP, /* 16 \p (Unicode property) */ + OP_ANYNL, /* 17 \R (any newline sequence) */ + OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */ + OP_HSPACE, /* 19 \h (horizontal whitespace) */ + OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */ + OP_VSPACE, /* 21 \v (vertical whitespace) */ + OP_EXTUNI, /* 22 \X (extended Unicode sequence */ + OP_EODN, /* 23 End of data or \n at end of data (\Z) */ + OP_EOD, /* 24 End of data (\z) */ + + /* Line end assertions */ + + OP_DOLL, /* 25 End of line - not multiline */ + OP_DOLLM, /* 26 End of line - multiline */ + OP_CIRC, /* 27 Start of line - not multiline */ + OP_CIRCM, /* 28 Start of line - multiline */ + + /* Single characters; caseful must precede the caseless ones */ + + OP_CHAR, /* 29 Match one character, casefully */ + OP_CHARI, /* 30 Match one character, caselessly */ + OP_NOT, /* 31 Match one character, not the given one, casefully */ + OP_NOTI, /* 32 Match one character, not the given one, caselessly */ + + /* The following sets of 13 opcodes must always be kept in step because + the offset from the first one is used to generate the others. */ + + /* Repeated characters; caseful must precede the caseless ones */ + + OP_STAR, /* 33 The maximizing and minimizing versions of */ + OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ + OP_PLUS, /* 35 the minimizing one second. */ + OP_MINPLUS, /* 36 */ + OP_QUERY, /* 37 */ + OP_MINQUERY, /* 38 */ + + OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/ + OP_MINUPTO, /* 40 */ + OP_EXACT, /* 41 Exactly n matches */ + + OP_POSSTAR, /* 42 Possessified star, caseful */ + OP_POSPLUS, /* 43 Possessified plus, caseful */ + OP_POSQUERY, /* 44 Posesssified query, caseful */ + OP_POSUPTO, /* 45 Possessified upto, caseful */ + + /* Repeated characters; caseless must follow the caseful ones */ + + OP_STARI, /* 46 */ + OP_MINSTARI, /* 47 */ + OP_PLUSI, /* 48 */ + OP_MINPLUSI, /* 49 */ + OP_QUERYI, /* 50 */ + OP_MINQUERYI, /* 51 */ + + OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */ + OP_MINUPTOI, /* 53 */ + OP_EXACTI, /* 54 */ + + OP_POSSTARI, /* 55 Possessified star, caseless */ + OP_POSPLUSI, /* 56 Possessified plus, caseless */ + OP_POSQUERYI, /* 57 Posesssified query, caseless */ + OP_POSUPTOI, /* 58 Possessified upto, caseless */ + + /* The negated ones must follow the non-negated ones, and match them */ + /* Negated repeated character, caseful; must precede the caseless ones */ + + OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ + OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ + OP_NOTPLUS, /* 61 the minimizing one second. They must be in */ + OP_NOTMINPLUS, /* 62 exactly the same order as those above. */ + OP_NOTQUERY, /* 63 */ + OP_NOTMINQUERY, /* 64 */ + + OP_NOTUPTO, /* 65 From 0 to n matches, caseful */ + OP_NOTMINUPTO, /* 66 */ + OP_NOTEXACT, /* 67 Exactly n matches */ + + OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */ + OP_NOTPOSPLUS, /* 69 */ + OP_NOTPOSQUERY, /* 70 */ + OP_NOTPOSUPTO, /* 71 */ + + /* Negated repeated character, caseless; must follow the caseful ones */ + + OP_NOTSTARI, /* 72 */ + OP_NOTMINSTARI, /* 73 */ + OP_NOTPLUSI, /* 74 */ + OP_NOTMINPLUSI, /* 75 */ + OP_NOTQUERYI, /* 76 */ + OP_NOTMINQUERYI, /* 77 */ + + OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */ + OP_NOTMINUPTOI, /* 79 */ + OP_NOTEXACTI, /* 80 Exactly n matches */ + + OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */ + OP_NOTPOSPLUSI, /* 82 */ + OP_NOTPOSQUERYI, /* 83 */ + OP_NOTPOSUPTOI, /* 84 */ + + /* Character types */ + + OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ + OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ + OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */ + OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */ + OP_TYPEQUERY, /* 89 */ + OP_TYPEMINQUERY, /* 90 */ + + OP_TYPEUPTO, /* 91 From 0 to n matches */ + OP_TYPEMINUPTO, /* 92 */ + OP_TYPEEXACT, /* 93 Exactly n matches */ + + OP_TYPEPOSSTAR, /* 94 Possessified versions */ + OP_TYPEPOSPLUS, /* 95 */ + OP_TYPEPOSQUERY, /* 96 */ + OP_TYPEPOSUPTO, /* 97 */ + + /* These are used for character classes and back references; only the + first six are the same as the sets above. */ + + OP_CRSTAR, /* 98 The maximizing and minimizing versions of */ + OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */ + OP_CRPLUS, /* 100 the minimizing one second. These codes must */ + OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */ + OP_CRQUERY, /* 102 */ + OP_CRMINQUERY, /* 103 */ + + OP_CRRANGE, /* 104 These are different to the three sets above. */ + OP_CRMINRANGE, /* 105 */ + + OP_CRPOSSTAR, /* 106 Possessified versions */ + OP_CRPOSPLUS, /* 107 */ + OP_CRPOSQUERY, /* 108 */ + OP_CRPOSRANGE, /* 109 */ + + /* End of quantifier opcodes */ + + OP_CLASS, /* 110 Match a character class, chars < 256 only */ + OP_NCLASS, /* 111 Same, but the bitmap was created from a negative + class - the difference is relevant only when a + character > 255 is encountered. */ + OP_XCLASS, /* 112 Extended class for handling > 255 chars within the + class. This does both positive and negative. */ + OP_REF, /* 113 Match a back reference, casefully */ + OP_REFI, /* 114 Match a back reference, caselessly */ + OP_DNREF, /* 115 Match a duplicate name backref, casefully */ + OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */ + OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 118 Call out to external function if provided */ + OP_CALLOUT_STR, /* 119 Call out with string argument */ + + OP_ALT, /* 120 Start of alternation */ + OP_KET, /* 121 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 122 These two must remain together and in this */ + OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 124 Possessive unlimited repeat. */ + + /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four + asserts must remain in order. */ + + OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ + OP_ASSERT, /* 126 Positive lookahead */ + OP_ASSERT_NOT, /* 127 Negative lookahead */ + OP_ASSERTBACK, /* 128 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ + + /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately + after the assertions, with ONCE first, as there's a test for >= ONCE for a + subpattern that isn't an assertion. The POS versions must immediately follow + the non-POS versions in each case. */ + + OP_ONCE, /* 130 Atomic group, contains captures */ + OP_ONCE_NC, /* 131 Atomic group containing no captures */ + OP_BRA, /* 132 Start of non-capturing bracket */ + OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 134 Start of capturing bracket */ + OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 136 Conditional group */ + + /* These five must follow the previous five, in the same order. There's a + check for >= SBRA to distinguish the two sets. */ + + OP_SBRA, /* 137 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 139 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 141 Conditional group, check empty */ + + /* The next two pairs must (respectively) be kept together. */ + + OP_CREF, /* 142 Used to hold a capture number as condition */ + OP_DNCREF, /* 143 Used to point to duplicate names as a condition */ + OP_RREF, /* 144 Used to hold a recursion number as condition */ + OP_DNRREF, /* 145 Used to point to duplicate names as a condition */ + OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 147 Always true (used by VERSION) */ + + OP_BRAZERO, /* 148 These two must remain together and in this */ + OP_BRAMINZERO, /* 149 order. */ + OP_BRAPOSZERO, /* 150 */ + + /* These are backtracking control verbs */ + + OP_MARK, /* 151 always has an argument */ + OP_PRUNE, /* 152 */ + OP_PRUNE_ARG, /* 153 same, but with argument */ + OP_SKIP, /* 154 */ + OP_SKIP_ARG, /* 155 same, but with argument */ + OP_THEN, /* 156 */ + OP_THEN_ARG, /* 157 same, but with argument */ + OP_COMMIT, /* 158 */ + + /* These are forced failure and success verbs */ + + OP_FAIL, /* 159 */ + OP_ACCEPT, /* 160 */ + OP_ASSERT_ACCEPT, /* 161 Used inside assertions */ + OP_CLOSE, /* 162 Used before OP_ACCEPT to close open captures */ + + /* This is used to skip a subpattern with a {0} quantifier */ + + OP_SKIPZERO, /* 163 */ + + /* This is used to identify a DEFINE group during compilation so that it can + be checked for having only one branch. It is changed to OP_FALSE before + compilation finishes. */ + + OP_DEFINE, /* 164 */ + + /* This is not an opcode, but is used to check that tables indexed by opcode + are the correct length, in order to catch updating errors - there have been + some in the past. */ + + OP_TABLE_LENGTH + +}; + +/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro +definitions that follow must also be updated to match. There are also tables +called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in +pcre2_dfa_exec.c that must be updated. */ + + +/* This macro defines textual names for all the opcodes. These are used only +for debugging, and some of them are only partial names. The macro is referenced +only in pcre2_printint.c, which fills out the full names in many cases (and in +some cases doesn't actually use these names at all). */ + +#define OP_NAME_LIST \ + "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ + "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ + "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ + "extuni", "\\Z", "\\z", \ + "$", "$", "^", "^", "char", "chari", "not", "noti", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", \ + "*+","++", "?+", "{", \ + "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ + "Recurse", "Callout", "CalloutStr", \ + "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ + "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ + "Once", "Once_NC", \ + "Bra", "BraPos", "CBra", "CBraPos", \ + "Cond", \ + "SBra", "SBraPos", "SCBra", "SCBraPos", \ + "SCond", \ + "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \ + "Cond false", "Cond true", \ + "Brazero", "Braminzero", "Braposzero", \ + "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ + "*THEN", "*THEN", "*COMMIT", "*FAIL", \ + "*ACCEPT", "*ASSERT_ACCEPT", \ + "Close", "Skip zero", "Define" + + +/* This macro defines the length of fixed length operations in the compiled +regex. The lengths are used when searching for specific things, and also in the +debugging printing of a compiled regex. We use a macro so that it can be +defined close to the definitions of the opcodes themselves. + +As things have been extended, some of these are no longer fixed lenths, but are +minima instead. For example, the length of a single-character repeat may vary +in UTF-8 mode. The code that uses this table must know about such things. */ + +#define OP_LENGTHS \ + 1, /* End */ \ + 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \ + 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \ + 1, 1, 1, /* Any, AllAny, Anybyte */ \ + 3, 3, /* \P, \p */ \ + 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ + 1, /* \X */ \ + 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \ + 2, /* Char - the minimum length */ \ + 2, /* Chari - the minimum length */ \ + 2, /* not */ \ + 2, /* noti */ \ + /* Positive single-char repeats ** These are */ \ + 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \ + 2+IMM2_SIZE, /* exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \ + 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \ + 2+IMM2_SIZE, /* exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \ + /* Negative single-char repeats - only for chars < 256 */ \ + 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \ + 2+IMM2_SIZE, /* NOT exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \ + 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \ + 2+IMM2_SIZE, /* NOT exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \ + /* Positive type repeats */ \ + 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \ + 2+IMM2_SIZE, /* Type exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \ + /* Character class & ref repeats */ \ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ + 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ + 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \ + 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \ + 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \ + 0, /* XCLASS - variable length */ \ + 1+IMM2_SIZE, /* REF */ \ + 1+IMM2_SIZE, /* REFI */ \ + 1+2*IMM2_SIZE, /* DNREF */ \ + 1+2*IMM2_SIZE, /* DNREFI */ \ + 1+LINK_SIZE, /* RECURSE */ \ + 1+2*LINK_SIZE+1, /* CALLOUT */ \ + 0, /* CALLOUT_STR - variable length */ \ + 1+LINK_SIZE, /* Alt */ \ + 1+LINK_SIZE, /* Ket */ \ + 1+LINK_SIZE, /* KetRmax */ \ + 1+LINK_SIZE, /* KetRmin */ \ + 1+LINK_SIZE, /* KetRpos */ \ + 1+LINK_SIZE, /* Reverse */ \ + 1+LINK_SIZE, /* Assert */ \ + 1+LINK_SIZE, /* Assert not */ \ + 1+LINK_SIZE, /* Assert behind */ \ + 1+LINK_SIZE, /* Assert behind not */ \ + 1+LINK_SIZE, /* ONCE */ \ + 1+LINK_SIZE, /* ONCE_NC */ \ + 1+LINK_SIZE, /* BRA */ \ + 1+LINK_SIZE, /* BRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ + 1+LINK_SIZE, /* COND */ \ + 1+LINK_SIZE, /* SBRA */ \ + 1+LINK_SIZE, /* SBRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ + 1+LINK_SIZE, /* SCOND */ \ + 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \ + 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \ + 1, 1, /* FALSE, TRUE */ \ + 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ + 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ + 1, 3, /* SKIP, SKIP_ARG */ \ + 1, 3, /* THEN, THEN_ARG */ \ + 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ + 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \ + 1 /* DEFINE */ + +/* A magic value for OP_RREF to indicate the "any recursion" condition. */ + +#define RREF_ANY 0xffff + + +/* ---------- Private structures that are mode-independent. ---------- */ + +/* Structure to hold data for custom memory management. */ + +typedef struct pcre2_memctl { + void * (*malloc)(size_t, void *); + void (*free)(void *, void *); + void *memory_data; +} pcre2_memctl; + +/* Structure for building a chain of open capturing subpatterns during +compiling, so that instructions to close them can be compiled when (*ACCEPT) is +encountered. This is also used to identify subpatterns that contain recursive +back references to themselves, so that they can be made atomic. */ + +typedef struct open_capitem { + struct open_capitem *next; /* Chain link */ + uint16_t number; /* Capture number */ + uint16_t flag; /* Set TRUE if recursive back ref */ +} open_capitem; + +/* Layout of the UCP type table that translates property names into types and +codes. Each entry used to point directly to a name, but to reduce the number of +relocations in shared libraries, it now has an offset into a single string +instead. */ + +typedef struct { + uint16_t name_offset; + uint16_t type; + uint16_t value; +} ucp_type_table; + +/* Unicode character database (UCD) record format */ + +typedef struct { + uint8_t script; /* ucp_Arabic, etc. */ + uint8_t chartype; /* ucp_Cc, etc. (general categories) */ + uint8_t gbprop; /* ucp_gbControl, etc. (grapheme break property) */ + uint8_t caseset; /* offset to multichar other cases or zero */ + int32_t other_case; /* offset to other case, or zero if none */ +} ucd_record; + +/* UCD access macros */ + +#define UCD_BLOCK_SIZE 128 +#define GET_UCD(ch) (PRIV(ucd_records) + \ + PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \ + UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE]) + +#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype +#define UCD_SCRIPT(ch) GET_UCD(ch)->script +#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] +#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop +#define UCD_CASESET(ch) GET_UCD(ch)->caseset +#define UCD_OTHERCASE(ch) ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case))) + +/* Header for serialized pcre2 codes. */ + +typedef struct pcre2_serialized_data { + uint32_t magic; + uint32_t version; + uint32_t config; + int32_t number_of_codes; +} pcre2_serialized_data; + + + +/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */ + +/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as +0, so the following items are omitted. */ + +#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0 + +/* EBCDIC is supported only for the 8-bit library. */ + +#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8 +#error EBCDIC is not supported for the 16-bit or 32-bit libraries +#endif + +/* This is the largest non-UTF code point. */ + +#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH)) + +/* Internal shared data tables and variables. These are used by more than one +of the exported public functions. They have to be "external" in the C sense, +but are not part of the PCRE2 public API. Although the data for some of them is +identical in all libraries, they must have different names so that multiple +libraries can be simultaneously linked to a single application. However, UTF-8 +tables are needed only when compiling the 8-bit library. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +extern const int PRIV(utf8_table1)[]; +extern const int PRIV(utf8_table1_size); +extern const int PRIV(utf8_table2)[]; +extern const int PRIV(utf8_table3)[]; +extern const uint8_t PRIV(utf8_table4)[]; +#endif + +#define _pcre2_OP_lengths PCRE2_SUFFIX(_pcre2_OP_lengths_) +#define _pcre2_callout_end_delims PCRE2_SUFFIX(_pcre2_callout_end_delims_) +#define _pcre2_callout_start_delims PCRE2_SUFFIX(_pcre2_callout_start_delims_) +#define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_) +#define _pcre2_default_match_context PCRE2_SUFFIX(_pcre2_default_match_context_) +#define _pcre2_default_tables PCRE2_SUFFIX(_pcre2_default_tables_) +#define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_) +#define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) +#define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) +#define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_) +#define _pcre2_ucd_stage1 PCRE2_SUFFIX(_pcre2_ucd_stage1_) +#define _pcre2_ucd_stage2 PCRE2_SUFFIX(_pcre2_ucd_stage2_) +#define _pcre2_ucp_gbtable PCRE2_SUFFIX(_pcre2_ucp_gbtable_) +#define _pcre2_ucp_gentype PCRE2_SUFFIX(_pcre2_ucp_gentype_) +#define _pcre2_ucp_typerange PCRE2_SUFFIX(_pcre2_ucp_typerange_) +#define _pcre2_unicode_version PCRE2_SUFFIX(_pcre2_unicode_version_) +#define _pcre2_utt PCRE2_SUFFIX(_pcre2_utt_) +#define _pcre2_utt_names PCRE2_SUFFIX(_pcre2_utt_names_) +#define _pcre2_utt_size PCRE2_SUFFIX(_pcre2_utt_size_) + +extern const uint8_t PRIV(OP_lengths)[]; +extern const uint32_t PRIV(callout_end_delims)[]; +extern const uint32_t PRIV(callout_start_delims)[]; +extern const pcre2_compile_context PRIV(default_compile_context); +extern const pcre2_match_context PRIV(default_match_context); +extern const uint8_t PRIV(default_tables)[]; +extern const uint32_t PRIV(hspace_list)[]; +extern const uint32_t PRIV(vspace_list)[]; +extern const uint32_t PRIV(ucd_caseless_sets)[]; +extern const ucd_record PRIV(ucd_records)[]; +extern const uint8_t PRIV(ucd_stage1)[]; +extern const uint16_t PRIV(ucd_stage2)[]; +extern const uint32_t PRIV(ucp_gbtable)[]; +extern const uint32_t PRIV(ucp_gentype)[]; +#ifdef SUPPORT_JIT +extern const int PRIV(ucp_typerange)[]; +#endif +extern const char *PRIV(unicode_version); +extern const ucp_type_table PRIV(utt)[]; +extern const char PRIV(utt_names)[]; +extern const size_t PRIV(utt_size); + +/* Mode-dependent macros and hidden and private structures are defined in a +separate file so that pcre2test can include them at all supported widths. When +compiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can +include them at the appropriate width, after setting up suffix macros for the +private structures. */ + +#define branch_chain PCRE2_SUFFIX(branch_chain_) +#define compile_block PCRE2_SUFFIX(compile_block_) +#define dfa_match_block PCRE2_SUFFIX(dfa_match_block_) +#define match_block PCRE2_SUFFIX(match_block_) +#define named_group PCRE2_SUFFIX(named_group_) + +#include "pcre2_intmodedep.h" + +/* Private "external" functions. These are internal functions that are called +from modules other than the one in which they are defined. They have to be +"external" in the C sense, but are not part of the PCRE public API. They are +not referenced from pcre2test, and must not be defined when no code unit width +is available. */ + +#define _pcre2_auto_possessify PCRE2_SUFFIX(_pcre2_auto_possessify_) +#define _pcre2_check_escape PCRE2_SUFFIX(_pcre2_check_escape_) +#define _pcre2_find_bracket PCRE2_SUFFIX(_pcre2_find_bracket_) +#define _pcre2_is_newline PCRE2_SUFFIX(_pcre2_is_newline_) +#define _pcre2_jit_free_rodata PCRE2_SUFFIX(_pcre2_jit_free_rodata_) +#define _pcre2_jit_free PCRE2_SUFFIX(_pcre2_jit_free_) +#define _pcre2_jit_get_size PCRE2_SUFFIX(_pcre2_jit_get_size_) +#define _pcre2_jit_get_target PCRE2_SUFFIX(_pcre2_jit_get_target_) +#define _pcre2_memctl_malloc PCRE2_SUFFIX(_pcre2_memctl_malloc_) +#define _pcre2_ord2utf PCRE2_SUFFIX(_pcre2_ord2utf_) +#define _pcre2_strcmp PCRE2_SUFFIX(_pcre2_strcmp_) +#define _pcre2_strcmp_c8 PCRE2_SUFFIX(_pcre2_strcmp_c8_) +#define _pcre2_strcpy_c8 PCRE2_SUFFIX(_pcre2_strcpy_c8_) +#define _pcre2_strlen PCRE2_SUFFIX(_pcre2_strlen_) +#define _pcre2_strncmp PCRE2_SUFFIX(_pcre2_strncmp_) +#define _pcre2_strncmp_c8 PCRE2_SUFFIX(_pcre2_strncmp_c8_) +#define _pcre2_study PCRE2_SUFFIX(_pcre2_study_) +#define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_) +#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_) +#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_) + +extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL, + const compile_block *); +extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, + int *, uint32_t, BOOL, compile_block *); +extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int); +extern BOOL _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, + uint32_t *, BOOL); +extern void _pcre2_jit_free_rodata(void *, void *); +extern void _pcre2_jit_free(void *, pcre2_memctl *); +extern size_t _pcre2_jit_get_size(void *); +const char * _pcre2_jit_get_target(void); +extern void * _pcre2_memctl_malloc(size_t, pcre2_memctl *); +extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *); +extern int _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR); +extern int _pcre2_strcmp_c8(PCRE2_SPTR, const char *); +extern PCRE2_SIZE _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *); +extern PCRE2_SIZE _pcre2_strlen(PCRE2_SPTR); +extern int _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t); +extern int _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t); +extern int _pcre2_study(pcre2_real_code *); +extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *); +extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, + uint32_t *, BOOL); +extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL); +#endif /* PCRE2_CODE_UNIT_WIDTH */ + +/* End of pcre2_internal.h */ diff --git a/pcre2/src/pcre2_intmodedep.h b/pcre2/src/pcre2_intmodedep.h new file mode 100644 index 000000000..90b7959e0 --- /dev/null +++ b/pcre2/src/pcre2_intmodedep.h @@ -0,0 +1,852 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains mode-dependent macro and structure definitions. The +file is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined. +These mode-dependent items are kept in a separate file so that they can also be +#included multiple times for different code unit widths by pcre2test in order +to have access to the hidden structures at all supported widths. + +Some of the mode-dependent macros are required at different widths for +different parts of the pcre2test code (in particular, the included +pcre_printint.c file). We undefine them here so that they can be re-defined for +multiple inclusions. Not all of these are used in pcre2test, but it's easier +just to undefine them all. */ + +#undef ACROSSCHAR +#undef BACKCHAR +#undef BYTES2CU +#undef CU2BYTES +#undef FORWARDCHAR +#undef FORWARDCHARTEST +#undef GET +#undef GET2 +#undef GETCHAR +#undef GETCHARINC +#undef GETCHARINCTEST +#undef GETCHARLEN +#undef GETCHARLENTEST +#undef GETCHARTEST +#undef GET_EXTRALEN +#undef HAS_EXTRALEN +#undef IMM2_SIZE +#undef MAX_255 +#undef MAX_MARK +#undef MAX_PATTERN_SIZE +#undef MAX_UTF_SINGLE_CU +#undef NOT_FIRSTCU +#undef PUT +#undef PUT2 +#undef PUT2INC +#undef PUTCHAR +#undef PUTINC +#undef TABLE_GET + + + +/* -------------------------- MACROS ----------------------------- */ + +/* PCRE keeps offsets in its compiled code as at least 16-bit quantities +(always stored in big-endian order in 8-bit mode) by default. These are used, +for example, to link from the start of a subpattern to its alternatives and its +end. The use of 16 bits per offset limits the size of an 8-bit compiled regex +to around 64K, which is big enough for almost everybody. However, I received a +request for an even bigger limit. For this reason, and also to make the code +easier to maintain, the storing and loading of offsets from the compiled code +unit string is now handled by the macros that are defined here. + +The macros are controlled by the value of LINK_SIZE. This defaults to 2, but +values of 2 or 4 are also supported. */ + +/* ------------------- 8-bit support ------------------ */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 + +#if LINK_SIZE == 2 +#define PUT(a,n,d) \ + (a[n] = (d) >> 8), \ + (a[(n)+1] = (d) & 255) +#define GET(a,n) \ + (((a)[n] << 8) | (a)[(n)+1]) +#define MAX_PATTERN_SIZE (1 << 16) + +#elif LINK_SIZE == 3 +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) >> 8), \ + (a[(n)+2] = (d) & 255) +#define GET(a,n) \ + (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) +#define MAX_PATTERN_SIZE (1 << 24) + +#elif LINK_SIZE == 4 +#define PUT(a,n,d) \ + (a[n] = (d) >> 24), \ + (a[(n)+1] = (d) >> 16), \ + (a[(n)+2] = (d) >> 8), \ + (a[(n)+3] = (d) & 255) +#define GET(a,n) \ + (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) +#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ + +#else +#error LINK_SIZE must be 2, 3, or 4 +#endif + + +/* ------------------- 16-bit support ------------------ */ + +#elif PCRE2_CODE_UNIT_WIDTH == 16 + +#if LINK_SIZE == 2 +#undef LINK_SIZE +#define LINK_SIZE 1 +#define PUT(a,n,d) \ + (a[n] = (d)) +#define GET(a,n) \ + (a[n]) +#define MAX_PATTERN_SIZE (1 << 16) + +#elif LINK_SIZE == 3 || LINK_SIZE == 4 +#undef LINK_SIZE +#define LINK_SIZE 2 +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) & 65535) +#define GET(a,n) \ + (((a)[n] << 16) | (a)[(n)+1]) +#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ + +#else +#error LINK_SIZE must be 2, 3, or 4 +#endif + + +/* ------------------- 32-bit support ------------------ */ + +#elif PCRE2_CODE_UNIT_WIDTH == 32 +#undef LINK_SIZE +#define LINK_SIZE 1 +#define PUT(a,n,d) \ + (a[n] = (d)) +#define GET(a,n) \ + (a[n]) +#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ + +#else +#error Unsupported compiling mode +#endif + + +/* --------------- Other mode-specific macros ----------------- */ + +/* PCRE uses some other (at least) 16-bit quantities that do not change when +the size of offsets changes. There are used for repeat counts and for other +things such as capturing parenthesis numbers in back references. + +Define the number of code units required to hold a 16-bit count/offset, and +macros to load and store such a value. For reasons that I do not understand, +the expression in the 8-bit GET2 macro is treated by gcc as a signed +expression, even when a is declared as unsigned. It seems that any kind of +arithmetic results in a signed value. Hence the cast. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define IMM2_SIZE 2 +#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1]) +#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255 + +#else /* Code units are 16 or 32 bits */ +#define IMM2_SIZE 1 +#define GET2(a,n) a[n] +#define PUT2(a,n,d) a[n] = d +#endif + +/* Other macros that are different for 8-bit mode. The MAX_255 macro checks +whether its argument is less than 256. The maximum length of a MARK name must +fit in one code unit; currently it is set to 255 or 65535. The TABLE_GET macro +is used to access elements of tables containing exactly 256 items. When code +points can be greater than 255, a check is needed before accessing these +tables. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define MAX_255(c) TRUE +#define MAX_MARK ((1u << 8) - 1) +#ifdef SUPPORT_UNICODE +#define SUPPORT_WIDE_CHARS +#endif /* SUPPORT_UNICODE */ +#define TABLE_GET(c, table, default) ((table)[c]) + +#else /* Code units are 16 or 32 bits */ +#define MAX_255(c) ((c) <= 255u) +#define MAX_MARK ((1u << 16) - 1) +#define SUPPORT_WIDE_CHARS +#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) +#endif + + + +/* ----------------- Character-handling macros ----------------- */ + +/* There is a proposed future special "UTF-21" mode, in which only the lowest +21 bits of a 32-bit character are interpreted as UTF, with the remaining 11 +high-order bits available to the application for other uses. In preparation for +the future implementation of this mode, there are macros that load a data item +and, if in this special mode, mask it to 21 bits. These macros all have names +starting with UCHAR21. In all other modes, including the normal 32-bit +library, the macros all have the same simple definitions. When the new mode is +implemented, it is expected that these definitions will be varied appropriately +using #ifdef when compiling the library that supports the special mode. */ + +#define UCHAR21(eptr) (*(eptr)) +#define UCHAR21TEST(eptr) (*(eptr)) +#define UCHAR21INC(eptr) (*(eptr)++) +#define UCHAR21INCTEST(eptr) (*(eptr)++) + +/* When UTF encoding is being used, a character is no longer just a single +byte in 8-bit mode or a single short in 16-bit mode. The macros for character +handling generate simple sequences when used in the basic mode, and more +complicated ones for UTF characters. GETCHARLENTEST and other macros are not +used when UTF is not supported. To make sure they can never even appear when +UTF support is omitted, we don't even define them. */ + +#ifndef SUPPORT_UNICODE + +/* #define MAX_UTF_SINGLE_CU */ +/* #define HAS_EXTRALEN(c) */ +/* #define GET_EXTRALEN(c) */ +/* #define NOT_FIRSTCU(c) */ +#define GETCHAR(c, eptr) c = *eptr; +#define GETCHARTEST(c, eptr) c = *eptr; +#define GETCHARINC(c, eptr) c = *eptr++; +#define GETCHARINCTEST(c, eptr) c = *eptr++; +#define GETCHARLEN(c, eptr, len) c = *eptr; +#define PUTCHAR(c, p) (*p = c, 1) +/* #define GETCHARLENTEST(c, eptr, len) */ +/* #define BACKCHAR(eptr) */ +/* #define FORWARDCHAR(eptr) */ +/* #define FORWARCCHARTEST(eptr,end) */ +/* #define ACROSSCHAR(condition, eptr, action) */ + +#else /* SUPPORT_UNICODE */ + +/* ------------------- 8-bit support ------------------ */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */ + +/* The largest UTF code point that can be encoded as a single code unit. */ + +#define MAX_UTF_SINGLE_CU 127 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) + +/* Returns TRUE, if the given value is not the first code unit of a UTF +sequence. */ + +#define NOT_FIRSTCU(c) (((c) & 0xc0) == 0x80) + +/* Get the next UTF-8 character, not advancing the pointer. This is called when +we know we are in UTF-8 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if (c >= 0xc0) GETUTF8(c, eptr); + +/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && c >= 0xc0) GETUTF8(c, eptr); + +/* Get the next UTF-8 character, advancing the pointer. This is called when we +know we are in UTF-8 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if (c >= 0xc0) GETUTF8INC(c, eptr); + +/* Get the next character, testing for UTF-8 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-8 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *eptr++; \ + if (utf && c >= 0xc0) GETUTF8INC(c, eptr); + +/* Get the next UTF-8 character, not advancing the pointer, incrementing length +if there are extra bytes. This is called when we know we are in UTF-8 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if (c >= 0xc0) GETUTF8LEN(c, eptr, len); + +/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the +pointer, incrementing length if there are extra bytes. This is called when we +do not know if we are in UTF-8 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + c = *eptr; \ + if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-8 mode - we don't put a test within the macro +because almost all calls are already within a block of UTF-8 only code. */ + +#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- + +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ +#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0) == 0x80) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + while((condition) && ((eptr) & 0xc0) == 0x80) action + +/* Deposit a character into memory, returning the number of code units. */ + +#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \ + PRIV(ord2utf)(c,p) : (*p = c, 1)) + + +/* ------------------- 16-bit support ------------------ */ + +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */ + +/* The largest UTF code point that can be encoded as a single code unit. */ + +#define MAX_UTF_SINGLE_CU 65535 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) 1 + +/* Returns TRUE, if the given value is not the first code unit of a UTF +sequence. */ + +#define NOT_FIRSTCU(c) (((c) & 0xfc00) == 0xdc00) + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer. */ + +#define GETUTF16(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, not advancing the pointer. This is called when +we know we are in UTF-16 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, advancing +the pointer. */ + +#define GETUTF16INC(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, advancing the pointer. This is called when we +know we are in UTF-16 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Get the next character, testing for UTF-16 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-16 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *eptr++; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer, incrementing the length. */ + +#define GETUTF16LEN(c, eptr, len) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } + +/* Get the next UTF-16 character, not advancing the pointer, incrementing +length if there is a low surrogate. This is called when we know we are in +UTF-16 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the +pointer, incrementing length if there is a low surrogate. This is called when +we do not know if we are in UTF-16 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-16 mode - we don't put a test within the +macro because almost all calls are already within a block of UTF-16 only +code. */ + +#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- + +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ +#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00) == 0xdc00) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action + +/* Deposit a character into memory, returning the number of code units. */ + +#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \ + PRIV(ord2utf)(c,p) : (*p = c, 1)) + + +/* ------------------- 32-bit support ------------------ */ + +#else + +/* These are trivial for the 32-bit library, since all UTF-32 characters fit +into one PCRE2_UCHAR unit. */ + +#define MAX_UTF_SINGLE_CU (0x10ffffu) +#define HAS_EXTRALEN(c) (0) +#define GET_EXTRALEN(c) (0) +#define NOT_FIRSTCU(c) (0) + +/* Get the next UTF-32 character, not advancing the pointer. This is called when +we know we are in UTF-32 mode. */ + +#define GETCHAR(c, eptr) \ + c = *(eptr); + +/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *(eptr); + +/* Get the next UTF-32 character, advancing the pointer. This is called when we +know we are in UTF-32 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *((eptr)++); + +/* Get the next character, testing for UTF-32 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-32 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *((eptr)++); + +/* Get the next UTF-32 character, not advancing the pointer, not incrementing +length (since all UTF-32 is of length 1). This is called when we know we are in +UTF-32 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + GETCHAR(c, eptr) + +/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the +pointer, not incrementing the length (since all UTF-32 is of length 1). +This is called when we do not know if we are in UTF-32 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + GETCHARTEST(c, eptr) + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-32 mode - we don't put a test within the +macro because almost all calls are already within a block of UTF-32 only +code. + +These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */ + +#define BACKCHAR(eptr) do { } while (0) + +/* Same as above, just in the other direction. */ + +#define FORWARDCHAR(eptr) do { } while (0) +#define FORWARDCHARTEST(eptr,end) do { } while (0) + +/* Same as above, but it allows a fully customizable form. */ + +#define ACROSSCHAR(condition, eptr, action) do { } while (0) + +/* Deposit a character into memory, returning the number of code units. */ + +#define PUTCHAR(c, p) (*p = c, 1) + +#endif /* UTF-32 character handling */ +#endif /* SUPPORT_UNICODE */ + + +/* Mode-dependent macros that have the same definition in all modes. */ + +#define CU2BYTES(x) ((x)*((PCRE2_CODE_UNIT_WIDTH/8))) +#define BYTES2CU(x) ((x)/((PCRE2_CODE_UNIT_WIDTH/8))) +#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE +#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE + + +/* ----------------------- HIDDEN STRUCTURES ----------------------------- */ + +/* NOTE: All these structures *must* start with a pcre2_memctl structure. The +code that uses them is simpler because it assumes this. */ + +/* The real general context structure. At present it holds only data for custom +memory control. */ + +typedef struct pcre2_real_general_context { + pcre2_memctl memctl; +} pcre2_real_general_context; + +/* The real compile context structure */ + +typedef struct pcre2_real_compile_context { + pcre2_memctl memctl; + int (*stack_guard)(uint32_t, void *); + void *stack_guard_data; + const uint8_t *tables; + PCRE2_SIZE max_pattern_length; + uint16_t bsr_convention; + uint16_t newline_convention; + uint32_t parens_nest_limit; +} pcre2_real_compile_context; + +/* The real match context structure. */ + +typedef struct pcre2_real_match_context { + pcre2_memctl memctl; +#ifdef HEAP_MATCH_RECURSE + pcre2_memctl stack_memctl; +#endif +#ifdef SUPPORT_JIT + pcre2_jit_callback jit_callback; + void *jit_callback_data; +#endif + int (*callout)(pcre2_callout_block *, void *); + void *callout_data; + PCRE2_SIZE offset_limit; + uint32_t match_limit; + uint32_t recursion_limit; +} pcre2_real_match_context; + +/* The real compiled code structure. The type for the blocksize field is +defined specially because it is required in pcre2_serialize_decode() when +copying the size from possibly unaligned memory into a variable of the same +type. Use a macro rather than a typedef to avoid compiler warnings when this +file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the +largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit +argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field +here.) */ + +#undef CODE_BLOCKSIZE_TYPE +#define CODE_BLOCKSIZE_TYPE size_t + +#undef LOOKBEHIND_MAX +#define LOOKBEHIND_MAX UINT16_MAX + +typedef struct pcre2_real_code { + pcre2_memctl memctl; /* Memory control fields */ + const uint8_t *tables; /* The character tables */ + void *executable_jit; /* Pointer to JIT code */ + uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */ + CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */ + uint32_t magic_number; /* Paranoid and endianness check */ + uint32_t compile_options; /* Options passed to pcre2_compile() */ + uint32_t overall_options; /* Options after processing the pattern */ + uint32_t flags; /* Various state flags */ + uint32_t limit_match; /* Limit set in the pattern */ + uint32_t limit_recursion; /* Limit set in the pattern */ + uint32_t first_codeunit; /* Starting code unit */ + uint32_t last_codeunit; /* This codeunit must be seen */ + uint16_t bsr_convention; /* What \R matches */ + uint16_t newline_convention; /* What is a newline? */ + uint16_t max_lookbehind; /* Longest lookbehind (characters) */ + uint16_t minlength; /* Minimum length of match */ + uint16_t top_bracket; /* Highest numbered group */ + uint16_t top_backref; /* Highest numbered back reference */ + uint16_t name_entry_size; /* Size (code units) of table entries */ + uint16_t name_count; /* Number of name entries in the table */ +} pcre2_real_code; + +/* The real match data structure. */ + +typedef struct pcre2_real_match_data { + pcre2_memctl memctl; + const pcre2_real_code *code; /* The pattern used for the match */ + PCRE2_SPTR subject; /* The subject that was matched */ + PCRE2_SPTR mark; /* Pointer to last mark */ + PCRE2_SIZE leftchar; /* Offset to leftmost code unit */ + PCRE2_SIZE rightchar; /* Offset to rightmost code unit */ + PCRE2_SIZE startchar; /* Offset to starting code unit */ + uint16_t matchedby; /* Type of match (normal, JIT, DFA) */ + uint16_t oveccount; /* Number of pairs */ + int rc; /* The return code from the match */ + PCRE2_SIZE ovector[1]; /* The first field */ +} pcre2_real_match_data; + + +/* ----------------------- PRIVATE STRUCTURES ----------------------------- */ + +/* These structures are not needed for pcre2test. */ + +#ifndef PCRE2_PCRE2TEST + +/* Structure for checking for mutual recursion when scanning compiled code. */ + +typedef struct recurse_check { + struct recurse_check *prev; + PCRE2_SPTR group; +} recurse_check; + +/* Structure for building a cache when filling in recursion offsets. */ + +typedef struct recurse_cache { + PCRE2_SPTR group; + int recno; +} recurse_cache; + +/* Structure for maintaining a chain of pointers to the currently incomplete +branches, for testing for left recursion while compiling. */ + +typedef struct branch_chain { + struct branch_chain *outer; + PCRE2_UCHAR *current_branch; +} branch_chain; + +/* Structure for building a list of named groups during the first pass of +compiling. */ + +typedef struct named_group { + PCRE2_SPTR name; /* Points to the name in the pattern */ + uint32_t number; /* Group number */ + uint16_t length; /* Length of the name */ + uint16_t isdup; /* TRUE if a duplicate */ +} named_group; + +/* Structure for passing "static" information around between the functions +doing the compiling, so that they are thread-safe. */ + +typedef struct compile_block { + pcre2_real_compile_context *cx; /* Points to the compile context */ + const uint8_t *lcc; /* Points to lower casing table */ + const uint8_t *fcc; /* Points to case-flipping table */ + const uint8_t *cbits; /* Points to character type table */ + const uint8_t *ctypes; /* Points to table of type maps */ + PCRE2_SPTR start_workspace; /* The start of working space */ + PCRE2_SPTR start_code; /* The start of the compiled code */ + PCRE2_SPTR start_pattern; /* The start of the pattern */ + PCRE2_SPTR end_pattern; /* The end of the pattern */ + PCRE2_SPTR nestptr[2]; /* Pointer(s) saved for string substitution */ + PCRE2_UCHAR *name_table; /* The name/number table */ + size_t workspace_size; /* Size of workspace */ + uint16_t names_found; /* Number of entries so far */ + uint16_t name_entry_size; /* Size of each entry */ + open_capitem *open_caps; /* Chain of open capture items */ + named_group *named_groups; /* Points to vector in pre-compile */ + uint32_t named_group_list_size; /* Number of entries in the list */ + uint32_t external_options; /* External (initial) options */ + uint32_t external_flags; /* External flag bits to be set */ + uint32_t bracount; /* Count of capturing parens as we compile */ + uint32_t final_bracount; /* Saved value after first pass */ + uint32_t *groupinfo; /* Group info vector */ + uint32_t top_backref; /* Maximum back reference */ + uint32_t backref_map; /* Bitmap of low back refs */ + uint32_t nltype; /* Newline type */ + uint32_t nllen; /* Newline string length */ + PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ + int max_lookbehind; /* Maximum lookbehind (characters) */ + int parens_depth; /* Depth of nested parentheses */ + int assert_depth; /* Depth of nested assertions */ + int req_varyopt; /* "After variable item" flag for reqbyte */ + BOOL had_accept; /* (*ACCEPT) encountered */ + BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ + BOOL had_recurse; /* Had a recursion or subroutine call */ + BOOL check_lookbehind; /* Lookbehinds need later checking */ + BOOL dupnames; /* Duplicate names exist */ + BOOL iscondassert; /* Next assert is a condition */ +} compile_block; + +/* Structure for keeping the properties of the in-memory stack used +by the JIT matcher. */ + +typedef struct pcre2_real_jit_stack { + pcre2_memctl memctl; + void* stack; +} pcre2_real_jit_stack; + +/* Structure for keeping a chain of heap blocks used for saving ovectors +during pattern recursion when the ovector is larger than can be saved on +the system stack. */ + +typedef struct ovecsave_frame { + struct ovecsave_frame *next; /* Next frame on free chain */ + PCRE2_SIZE saved_ovec[1]; /* First vector element */ +} ovecsave_frame; + +/* Structure for items in a linked list that represents an explicit recursive +call within the pattern; used by pcre_match(). */ + +typedef struct recursion_info { + struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ + unsigned int group_num; /* Number of group that was called */ + PCRE2_SIZE *ovec_save; /* Pointer to saved ovector frame */ + uint32_t saved_capture_last; /* Last capture number */ + PCRE2_SPTR subject_position; /* Position at start of recursion */ +} recursion_info; + +/* A similar structure for pcre_dfa_match(). */ + +typedef struct dfa_recursion_info { + struct dfa_recursion_info *prevrec; + PCRE2_SPTR subject_position; + uint32_t group_num; +} dfa_recursion_info; + +/* Structure for building a chain of data for holding the values of the subject +pointer at the start of each subpattern, so as to detect when an empty string +has been matched by a subpattern - to break infinite loops; used by +pcre2_match(). */ + +typedef struct eptrblock { + struct eptrblock *epb_prev; + PCRE2_SPTR epb_saved_eptr; +} eptrblock; + +/* Structure for passing "static" information around between the functions +doing traditional NFA matching (pcre2_match() and friends). */ + +typedef struct match_block { + pcre2_memctl memctl; /* For general use */ +#ifdef HEAP_MATCH_RECURSE + pcre2_memctl stack_memctl; /* For "stack" frames */ +#endif + uint32_t match_call_count; /* As it says */ + uint32_t match_limit; /* As it says */ + uint32_t match_limit_recursion; /* As it says */ + BOOL hitend; /* Hit the end of the subject at some point */ + BOOL hasthen; /* Pattern contains (*THEN) */ + const uint8_t *lcc; /* Points to lower casing table */ + const uint8_t *fcc; /* Points to case-flipping table */ + const uint8_t *ctypes; /* Points to table of type maps */ + PCRE2_SIZE *ovector; /* Pointer to the offset vector */ + PCRE2_SIZE offset_end; /* One past the end */ + PCRE2_SIZE offset_max; /* The maximum usable for return data */ + PCRE2_SIZE start_offset; /* The start offset value */ + PCRE2_SIZE end_offset_top; /* Highwater mark at end of match */ + uint16_t partial; /* PARTIAL options */ + uint16_t bsr_convention; /* \R interpretation */ + uint16_t name_count; /* Number of names in name table */ + uint16_t name_entry_size; /* Size of entry in names table */ + PCRE2_SPTR name_table; /* Table of group names */ + PCRE2_SPTR start_code; /* For use when recursing */ + PCRE2_SPTR start_subject; /* Start of the subject string */ + PCRE2_SPTR end_subject; /* End of the subject string */ + PCRE2_SPTR start_match_ptr; /* Start of matched string */ + PCRE2_SPTR end_match_ptr; /* Subject position at end match */ + PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ + PCRE2_SPTR last_used_ptr; /* Latest consulted character */ + PCRE2_SPTR mark; /* Mark pointer to pass back on success */ + PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */ + PCRE2_SPTR once_target; /* Where to back up to for atomic groups */ + uint32_t moptions; /* Match options */ + uint32_t poptions; /* Pattern options */ + uint32_t capture_last; /* Most recent capture number + overflow flag */ + uint32_t skip_arg_count; /* For counting SKIP_ARGs */ + uint32_t ignore_skip_arg; /* For re-run when SKIP arg name not found */ + uint32_t match_function_type; /* Set for certain special calls of match() */ + uint32_t nltype; /* Newline type */ + uint32_t nllen; /* Newline string length */ + PCRE2_UCHAR nl[4]; /* Newline string when fixed */ + eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ + recursion_info *recursive; /* Linked list of recursion data */ + ovecsave_frame *ovecsave_chain; /* Linked list of free ovecsave blocks */ + void *callout_data; /* To pass back to callouts */ + int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ +#ifdef HEAP_MATCH_RECURSE + void *match_frames_base; /* For remembering malloc'd frames */ +#endif +} match_block; + +/* A similar structure is used for the same purpose by the DFA matching +functions. */ + +typedef struct dfa_match_block { + pcre2_memctl memctl; /* For general use */ + PCRE2_SPTR start_code; /* Start of the compiled pattern */ + PCRE2_SPTR start_subject ; /* Start of the subject string */ + PCRE2_SPTR end_subject; /* End of subject string */ + PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ + PCRE2_SPTR last_used_ptr; /* Latest consulted character */ + const uint8_t *tables; /* Character tables */ + PCRE2_SIZE start_offset; /* The start offset value */ + uint32_t moptions; /* Match options */ + uint32_t poptions; /* Pattern options */ + uint32_t nltype; /* Newline type */ + uint32_t nllen; /* Newline string length */ + PCRE2_UCHAR nl[4]; /* Newline string when fixed */ + uint16_t bsr_convention; /* \R interpretation */ + void *callout_data; /* To pass back to callouts */ + int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ + dfa_recursion_info *recursive; /* Linked list of recursion data */ +} dfa_match_block; + +#endif /* PCRE2_PCRE2TEST */ + +/* End of pcre2_intmodedep.h */ diff --git a/pcre2/src/pcre2_jit_compile.c b/pcre2/src/pcre2_jit_compile.c new file mode 100644 index 000000000..b46f4e394 --- /dev/null +++ b/pcre2/src/pcre2_jit_compile.c @@ -0,0 +1,11503 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + +#ifdef SUPPORT_JIT + +/* All-in-one: Since we use the JIT compiler only from here, +we just include it. This way we don't need to touch the build +system files. */ + +#define SLJIT_CONFIG_AUTO 1 +#define SLJIT_CONFIG_STATIC 1 +#define SLJIT_VERBOSE 0 + +#ifdef PCRE2_DEBUG +#define SLJIT_DEBUG 1 +#else +#define SLJIT_DEBUG 0 +#endif + +#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data) +#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data) + +static void * pcre2_jit_malloc(size_t size, void *allocator_data) +{ +pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data); +return allocator->malloc(size, allocator->memory_data); +} + +static void pcre2_jit_free(void *ptr, void *allocator_data) +{ +pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data); +allocator->free(ptr, allocator->memory_data); +} + +#include "sljit/sljitLir.c" + +#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED +#error Unsupported architecture +#endif + +/* Defines for debugging purposes. */ + +/* 1 - Use unoptimized capturing brackets. + 2 - Enable capture_last_ptr (includes option 1). */ +/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */ + +/* 1 - Always have a control head. */ +/* #define DEBUG_FORCE_CONTROL_HEAD 1 */ + +/* Allocate memory for the regex stack on the real machine stack. +Fast, but limited size. */ +#define MACHINE_STACK_SIZE 32768 + +/* Growth rate for stack allocated by the OS. Should be the multiply +of page size. */ +#define STACK_GROWTH_RATE 8192 + +/* Enable to check that the allocation could destroy temporaries. */ +#if defined SLJIT_DEBUG && SLJIT_DEBUG +#define DESTROY_REGISTERS 1 +#endif + +/* +Short summary about the backtracking mechanism empolyed by the jit code generator: + +The code generator follows the recursive nature of the PERL compatible regular +expressions. The basic blocks of regular expressions are condition checkers +whose execute different commands depending on the result of the condition check. +The relationship between the operators can be horizontal (concatenation) and +vertical (sub-expression) (See struct backtrack_common for more details). + + 'ab' - 'a' and 'b' regexps are concatenated + 'a+' - 'a' is the sub-expression of the '+' operator + +The condition checkers are boolean (true/false) checkers. Machine code is generated +for the checker itself and for the actions depending on the result of the checker. +The 'true' case is called as the matching path (expected path), and the other is called as +the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken +branches on the matching path. + + Greedy star operator (*) : + Matching path: match happens. + Backtrack path: match failed. + Non-greedy star operator (*?) : + Matching path: no need to perform a match. + Backtrack path: match is required. + +The following example shows how the code generated for a capturing bracket +with two alternatives. Let A, B, C, D are arbirary regular expressions, and +we have the following regular expression: + + A(B|C)D + +The generated code will be the following: + + A matching path + '(' matching path (pushing arguments to the stack) + B matching path + ')' matching path (pushing arguments to the stack) + D matching path + return with successful match + + D backtrack path + ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") + B backtrack path + C expected path + jump to D matching path + C backtrack path + A backtrack path + + Notice, that the order of backtrack code paths are the opposite of the fast + code paths. In this way the topmost value on the stack is always belong + to the current backtrack code path. The backtrack path must check + whether there is a next alternative. If so, it needs to jump back to + the matching path eventually. Otherwise it needs to clear out its own stack + frame and continue the execution on the backtrack code paths. +*/ + +/* +Saved stack frames: + +Atomic blocks and asserts require reloading the values of private data +when the backtrack mechanism performed. Because of OP_RECURSE, the data +are not necessarly known in compile time, thus we need a dynamic restore +mechanism. + +The stack frames are stored in a chain list, and have the following format: +([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] + +Thus we can restore the private data to a particular point in the stack. +*/ + +typedef struct jit_arguments { + /* Pointers first. */ + struct sljit_stack *stack; + PCRE2_SPTR str; + PCRE2_SPTR begin; + PCRE2_SPTR end; + pcre2_match_data *match_data; + PCRE2_SPTR startchar_ptr; + PCRE2_UCHAR *mark_ptr; + int (*callout)(pcre2_callout_block *, void *); + void *callout_data; + /* Everything else after. */ + sljit_uw offset_limit; + sljit_ui limit_match; + uint32_t oveccount; + uint32_t options; +} jit_arguments; + +#define JIT_NUMBER_OF_COMPILE_MODES 3 + +typedef struct executable_functions { + void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; + void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES]; + sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; + sljit_ui top_bracket; + sljit_ui limit_match; +} executable_functions; + +typedef struct jump_list { + struct sljit_jump *jump; + struct jump_list *next; +} jump_list; + +typedef struct stub_list { + struct sljit_jump *start; + struct sljit_label *quit; + struct stub_list *next; +} stub_list; + +typedef struct label_addr_list { + struct sljit_label *label; + sljit_uw *update_addr; + struct label_addr_list *next; +} label_addr_list; + +enum frame_types { + no_frame = -1, + no_stack = -2 +}; + +enum control_types { + type_mark = 0, + type_then_trap = 1 +}; + +typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); + +/* The following structure is the key data type for the recursive +code generator. It is allocated by compile_matchingpath, and contains +the arguments for compile_backtrackingpath. Must be the first member +of its descendants. */ +typedef struct backtrack_common { + /* Concatenation stack. */ + struct backtrack_common *prev; + jump_list *nextbacktracks; + /* Internal stack (for component operators). */ + struct backtrack_common *top; + jump_list *topbacktracks; + /* Opcode pointer. */ + PCRE2_SPTR cc; +} backtrack_common; + +typedef struct assert_backtrack { + backtrack_common common; + jump_list *condfailed; + /* Less than 0 if a frame is not needed. */ + int framesize; + /* Points to our private memory word on the stack. */ + int private_data_ptr; + /* For iterators. */ + struct sljit_label *matchingpath; +} assert_backtrack; + +typedef struct bracket_backtrack { + backtrack_common common; + /* Where to coninue if an alternative is successfully matched. */ + struct sljit_label *alternative_matchingpath; + /* For rmin and rmax iterators. */ + struct sljit_label *recursive_matchingpath; + /* For greedy ? operator. */ + struct sljit_label *zero_matchingpath; + /* Contains the branches of a failed condition. */ + union { + /* Both for OP_COND, OP_SCOND. */ + jump_list *condfailed; + assert_backtrack *assert; + /* For OP_ONCE. Less than 0 if not needed. */ + int framesize; + } u; + /* Points to our private memory word on the stack. */ + int private_data_ptr; +} bracket_backtrack; + +typedef struct bracketpos_backtrack { + backtrack_common common; + /* Points to our private memory word on the stack. */ + int private_data_ptr; + /* Reverting stack is needed. */ + int framesize; + /* Allocated stack size. */ + int stacksize; +} bracketpos_backtrack; + +typedef struct braminzero_backtrack { + backtrack_common common; + struct sljit_label *matchingpath; +} braminzero_backtrack; + +typedef struct char_iterator_backtrack { + backtrack_common common; + /* Next iteration. */ + struct sljit_label *matchingpath; + union { + jump_list *backtracks; + struct { + unsigned int othercasebit; + PCRE2_UCHAR chr; + BOOL enabled; + } charpos; + } u; +} char_iterator_backtrack; + +typedef struct ref_iterator_backtrack { + backtrack_common common; + /* Next iteration. */ + struct sljit_label *matchingpath; +} ref_iterator_backtrack; + +typedef struct recurse_entry { + struct recurse_entry *next; + /* Contains the function entry. */ + struct sljit_label *entry; + /* Collects the calls until the function is not created. */ + jump_list *calls; + /* Points to the starting opcode. */ + sljit_sw start; +} recurse_entry; + +typedef struct recurse_backtrack { + backtrack_common common; + BOOL inlined_pattern; +} recurse_backtrack; + +#define OP_THEN_TRAP OP_TABLE_LENGTH + +typedef struct then_trap_backtrack { + backtrack_common common; + /* If then_trap is not NULL, this structure contains the real + then_trap for the backtracking path. */ + struct then_trap_backtrack *then_trap; + /* Points to the starting opcode. */ + sljit_sw start; + /* Exit point for the then opcodes of this alternative. */ + jump_list *quit; + /* Frame size of the current alternative. */ + int framesize; +} then_trap_backtrack; + +#define MAX_RANGE_SIZE 4 + +typedef struct compiler_common { + /* The sljit ceneric compiler. */ + struct sljit_compiler *compiler; + /* First byte code. */ + PCRE2_SPTR start; + /* Maps private data offset to each opcode. */ + sljit_si *private_data_ptrs; + /* Chain list of read-only data ptrs. */ + void *read_only_data_head; + /* Tells whether the capturing bracket is optimized. */ + sljit_ub *optimized_cbracket; + /* Tells whether the starting offset is a target of then. */ + sljit_ub *then_offsets; + /* Current position where a THEN must jump. */ + then_trap_backtrack *then_trap; + /* Starting offset of private data for capturing brackets. */ + sljit_si cbra_ptr; + /* Output vector starting point. Must be divisible by 2. */ + sljit_si ovector_start; + /* Points to the starting character of the current match. */ + sljit_si start_ptr; + /* Last known position of the requested byte. */ + sljit_si req_char_ptr; + /* Head of the last recursion. */ + sljit_si recursive_head_ptr; + /* First inspected character for partial matching. + (Needed for avoiding zero length partial matches.) */ + sljit_si start_used_ptr; + /* Starting pointer for partial soft matches. */ + sljit_si hit_start; + /* Pointer of the match end position. */ + sljit_si match_end_ptr; + /* Points to the marked string. */ + sljit_si mark_ptr; + /* Recursive control verb management chain. */ + sljit_si control_head_ptr; + /* Points to the last matched capture block index. */ + sljit_si capture_last_ptr; + /* Fast forward skipping byte code pointer. */ + PCRE2_SPTR fast_forward_bc_ptr; + /* Locals used by fast fail optimization. */ + sljit_si fast_fail_start_ptr; + sljit_si fast_fail_end_ptr; + + /* Flipped and lower case tables. */ + const sljit_ub *fcc; + sljit_sw lcc; + /* Mode can be PCRE2_JIT_COMPLETE and others. */ + int mode; + /* TRUE, when minlength is greater than 0. */ + BOOL might_be_empty; + /* \K is found in the pattern. */ + BOOL has_set_som; + /* (*SKIP:arg) is found in the pattern. */ + BOOL has_skip_arg; + /* (*THEN) is found in the pattern. */ + BOOL has_then; + /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */ + BOOL has_skip_in_assert_back; + /* Currently in recurse or negative assert. */ + BOOL local_exit; + /* Currently in a positive assert. */ + BOOL positive_assert; + /* Newline control. */ + int nltype; + sljit_ui nlmax; + sljit_ui nlmin; + int newline; + int bsr_nltype; + sljit_ui bsr_nlmax; + sljit_ui bsr_nlmin; + /* Dollar endonly. */ + int endonly; + /* Tables. */ + sljit_sw ctypes; + /* Named capturing brackets. */ + PCRE2_SPTR name_table; + sljit_sw name_count; + sljit_sw name_entry_size; + + /* Labels and jump lists. */ + struct sljit_label *partialmatchlabel; + struct sljit_label *quit_label; + struct sljit_label *forced_quit_label; + struct sljit_label *accept_label; + struct sljit_label *ff_newline_shortcut; + stub_list *stubs; + label_addr_list *label_addrs; + recurse_entry *entries; + recurse_entry *currententry; + jump_list *partialmatch; + jump_list *quit; + jump_list *positive_assert_quit; + jump_list *forced_quit; + jump_list *accept; + jump_list *calllimit; + jump_list *stackalloc; + jump_list *revertframes; + jump_list *wordboundary; + jump_list *anynewline; + jump_list *hspace; + jump_list *vspace; + jump_list *casefulcmp; + jump_list *caselesscmp; + jump_list *reset_match; + BOOL unset_backref; + BOOL alt_circumflex; +#ifdef SUPPORT_UNICODE + BOOL utf; + BOOL use_ucp; + jump_list *getucd; +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump_list *utfreadchar; + jump_list *utfreadchar16; + jump_list *utfreadtype8; +#endif +#endif /* SUPPORT_UNICODE */ +} compiler_common; + +/* For byte_sequence_compare. */ + +typedef struct compare_context { + int length; + int sourcereg; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + int ucharptr; + union { + sljit_si asint; + sljit_uh asushort; +#if PCRE2_CODE_UNIT_WIDTH == 8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + sljit_uh asuchars[2]; +#elif PCRE2_CODE_UNIT_WIDTH == 32 + sljit_ui asuchars[1]; +#endif + } c; + union { + sljit_si asint; + sljit_uh asushort; +#if PCRE2_CODE_UNIT_WIDTH == 8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + sljit_uh asuchars[2]; +#elif PCRE2_CODE_UNIT_WIDTH == 32 + sljit_ui asuchars[1]; +#endif + } oc; +#endif +} compare_context; + +/* Undefine sljit macros. */ +#undef CMP + +/* Used for accessing the elements of the stack. */ +#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw)) + +#define TMP1 SLJIT_R0 +#define TMP2 SLJIT_R2 +#define TMP3 SLJIT_R3 +#define STR_PTR SLJIT_S0 +#define STR_END SLJIT_S1 +#define STACK_TOP SLJIT_R1 +#define STACK_LIMIT SLJIT_S2 +#define COUNT_MATCH SLJIT_S3 +#define ARGUMENTS SLJIT_S4 +#define RETURN_ADDR SLJIT_R4 + +/* Local space layout. */ +/* These two locals can be used by the current opcode. */ +#define LOCALS0 (0 * sizeof(sljit_sw)) +#define LOCALS1 (1 * sizeof(sljit_sw)) +/* Two local variables for possessive quantifiers (char1 cannot use them). */ +#define POSSESSIVE0 (2 * sizeof(sljit_sw)) +#define POSSESSIVE1 (3 * sizeof(sljit_sw)) +/* Max limit of recursions. */ +#define LIMIT_MATCH (4 * sizeof(sljit_sw)) +/* The output vector is stored on the stack, and contains pointers +to characters. The vector data is divided into two groups: the first +group contains the start / end character pointers, and the second is +the start pointers when the end of the capturing group has not yet reached. */ +#define OVECTOR_START (common->ovector_start) +#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw)) +#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw)) +#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define MOV_UCHAR SLJIT_MOV_UB +#define MOVU_UCHAR SLJIT_MOVU_UB +#define IN_UCHARS(x) (x) +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define MOV_UCHAR SLJIT_MOV_UH +#define MOVU_UCHAR SLJIT_MOVU_UH +#define UCHAR_SHIFT (1) +#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#elif PCRE2_CODE_UNIT_WIDTH == 32 +#define MOV_UCHAR SLJIT_MOV_UI +#define MOVU_UCHAR SLJIT_MOVU_UI +#define UCHAR_SHIFT (2) +#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#else +#error Unsupported compiling mode +#endif + +/* Shortcuts. */ +#define DEFINE_COMPILER \ + struct sljit_compiler *compiler = common->compiler +#define OP1(op, dst, dstw, src, srcw) \ + sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) +#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ + sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) +#define LABEL() \ + sljit_emit_label(compiler) +#define JUMP(type) \ + sljit_emit_jump(compiler, (type)) +#define JUMPTO(type, label) \ + sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) +#define JUMPHERE(jump) \ + sljit_set_label((jump), sljit_emit_label(compiler)) +#define SET_LABEL(jump, label) \ + sljit_set_label((jump), (label)) +#define CMP(type, src1, src1w, src2, src2w) \ + sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) +#define CMPTO(type, src1, src1w, src2, src2w, label) \ + sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) +#define OP_FLAGS(op, dst, dstw, src, srcw, type) \ + sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type)) +#define GET_LOCAL_BASE(dst, dstw, offset) \ + sljit_get_local_base(compiler, (dst), (dstw), (offset)) + +#define READ_CHAR_MAX 0x7fffffff + +static PCRE2_SPTR bracketend(PCRE2_SPTR cc) +{ +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +do cc += GET(cc, 1); while (*cc == OP_ALT); +SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); +cc += 1 + LINK_SIZE; +return cc; +} + +static int no_alternatives(PCRE2_SPTR cc) +{ +int count = 0; +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +do + { + cc += GET(cc, 1); + count++; + } +while (*cc == OP_ALT); +SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); +return count; +} + +/* Functions whose might need modification for all new supported opcodes: + next_opcode + check_opcode_types + set_private_data_ptrs + get_framesize + init_frame + get_private_data_copy_length + copy_private_data + compile_matchingpath + compile_backtrackingpath +*/ + +static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc) +{ +SLJIT_UNUSED_ARG(common); +switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_NOTPROP: + case OP_PROP: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + case OP_CRPOSRANGE: + case OP_CLASS: + case OP_NCLASS: + case OP_REF: + case OP_REFI: + case OP_DNREF: + case OP_DNREFI: + case OP_RECURSE: + case OP_CALLOUT: + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_REVERSE: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_CBRA: + case OP_CBRAPOS: + case OP_COND: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + case OP_SCOND: + case OP_CREF: + case OP_DNCREF: + case OP_RREF: + case OP_DNRREF: + case OP_FALSE: + case OP_TRUE: + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + case OP_PRUNE: + case OP_SKIP: + case OP_THEN: + case OP_COMMIT: + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_CLOSE: + case OP_SKIPZERO: + return cc + PRIV(OP_lengths)[*cc]; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + cc += PRIV(OP_lengths)[*cc]; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + return cc; + + /* Special cases. */ + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + return cc + PRIV(OP_lengths)[*cc] - 1; + + case OP_ANYBYTE: +#ifdef SUPPORT_UNICODE + if (common->utf) return NULL; +#endif + return cc + 1; + + case OP_CALLOUT_STR: + return cc + GET(cc, 1 + 2*LINK_SIZE); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + return cc + GET(cc, 1); +#endif + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + return cc + 1 + 2 + cc[1]; + + default: + /* All opcodes are supported now! */ + SLJIT_ASSERT_STOP(); + return NULL; + } +} + +static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend) +{ +int count; +PCRE2_SPTR slot; +PCRE2_SPTR assert_back_end = cc - 1; + +/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ +while (cc < ccend) + { + switch(*cc) + { + case OP_SET_SOM: + common->has_set_som = TRUE; + common->might_be_empty = TRUE; + cc += 1; + break; + + case OP_REF: + case OP_REFI: + common->optimized_cbracket[GET2(cc, 1)] = 0; + cc += 1 + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + case OP_SCOND: + /* Only AUTO_CALLOUT can insert this opcode. We do + not intend to support this case. */ + if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR) + return FALSE; + cc += 1 + LINK_SIZE; + break; + + case OP_CREF: + common->optimized_cbracket[GET2(cc, 1)] = 0; + cc += 1 + IMM2_SIZE; + break; + + case OP_DNREF: + case OP_DNREFI: + case OP_DNCREF: + count = GET2(cc, 1 + IMM2_SIZE); + slot = common->name_table + GET2(cc, 1) * common->name_entry_size; + while (count-- > 0) + { + common->optimized_cbracket[GET2(slot, 0)] = 0; + slot += common->name_entry_size; + } + cc += 1 + 2 * IMM2_SIZE; + break; + + case OP_RECURSE: + /* Set its value only once. */ + if (common->recursive_head_ptr == 0) + { + common->recursive_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + LINK_SIZE; + break; + + case OP_CALLOUT: + case OP_CALLOUT_STR: + if (common->capture_last_ptr == 0) + { + common->capture_last_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE); + break; + + case OP_ASSERTBACK: + slot = bracketend(cc); + if (slot > assert_back_end) + assert_back_end = slot; + cc += 1 + LINK_SIZE; + break; + + case OP_THEN_ARG: + common->has_then = TRUE; + common->control_head_ptr = 1; + /* Fall through. */ + + case OP_PRUNE_ARG: + case OP_MARK: + if (common->mark_ptr == 0) + { + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + 2 + cc[1]; + break; + + case OP_THEN: + common->has_then = TRUE; + common->control_head_ptr = 1; + cc += 1; + break; + + case OP_SKIP: + if (cc < assert_back_end) + common->has_skip_in_assert_back = TRUE; + cc += 1; + break; + + case OP_SKIP_ARG: + common->control_head_ptr = 1; + common->has_skip_arg = TRUE; + if (cc < assert_back_end) + common->has_skip_in_assert_back = TRUE; + cc += 1 + 2 + cc[1]; + break; + + default: + cc = next_opcode(common, cc); + if (cc == NULL) + return FALSE; + break; + } + } +return TRUE; +} + +static BOOL is_accelerated_repeat(PCRE2_SPTR cc) +{ +switch(*cc) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI); + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSSTAR: + case OP_POSPLUS: + + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSSTARI: + case OP_POSPLUSI: + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + return TRUE; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR))); +#else + cc += (1 + (32 / sizeof(PCRE2_UCHAR))); +#endif + + switch(*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + return TRUE; + } + break; + } +return FALSE; +} + +static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start) +{ +PCRE2_SPTR cc = common->start; +PCRE2_SPTR end; + +/* Skip not repeated brackets. */ +while (TRUE) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + } + + if (*cc != OP_BRA && *cc != OP_CBRA) + break; + + end = cc + GET(cc, 1); + if (*end != OP_KET || PRIVATE_DATA(end) != 0) + return FALSE; + if (*cc == OP_CBRA) + { + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + return FALSE; + cc += IMM2_SIZE; + } + cc += 1 + LINK_SIZE; + } + +if (is_accelerated_repeat(cc)) + { + common->fast_forward_bc_ptr = cc; + common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; + *private_data_start += sizeof(sljit_sw); + return TRUE; + } +return FALSE; +} + +static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_si depth) +{ + PCRE2_SPTR next_alt; + + SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA); + + if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + return; + + next_alt = bracketend(cc) - (1 + LINK_SIZE); + if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0) + return; + + do + { + next_alt = cc + GET(cc, 1); + + cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0); + + while (TRUE) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + } + break; + } + + if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA)) + detect_fast_fail(common, cc, private_data_start, depth - 1); + + if (is_accelerated_repeat(cc)) + { + common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; + + if (common->fast_fail_start_ptr == 0) + common->fast_fail_start_ptr = *private_data_start; + + *private_data_start += sizeof(sljit_sw); + common->fast_fail_end_ptr = *private_data_start; + + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return; + } + + cc = next_alt; + } + while (*cc == OP_ALT); +} + +static int get_class_iterator_size(PCRE2_SPTR cc) +{ +sljit_ui min; +sljit_ui max; +switch(*cc) + { + case OP_CRSTAR: + case OP_CRPLUS: + return 2; + + case OP_CRMINSTAR: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + return 1; + + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(cc, 1); + max = GET2(cc, 1 + IMM2_SIZE); + if (max == 0) + return (*cc == OP_CRRANGE) ? 2 : 1; + max -= min; + if (max > 2) + max = 2; + return max; + + default: + return 0; + } +} + +static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin) +{ +PCRE2_SPTR end = bracketend(begin); +PCRE2_SPTR next; +PCRE2_SPTR next_end; +PCRE2_SPTR max_end; +PCRE2_UCHAR type; +sljit_sw length = end - begin; +sljit_si min, max, i; + +/* Detect fixed iterations first. */ +if (end[-(1 + LINK_SIZE)] != OP_KET) + return FALSE; + +/* Already detected repeat. */ +if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0) + return TRUE; + +next = end; +min = 1; +while (1) + { + if (*next != *begin) + break; + next_end = bracketend(next); + if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0) + break; + next = next_end; + min++; + } + +if (min == 2) + return FALSE; + +max = 0; +max_end = next; +if (*next == OP_BRAZERO || *next == OP_BRAMINZERO) + { + type = *next; + while (1) + { + if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin) + break; + next_end = bracketend(next + 2 + LINK_SIZE); + if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0) + break; + next = next_end; + max++; + } + + if (next[0] == type && next[1] == *begin && max >= 1) + { + next_end = bracketend(next + 1); + if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0) + { + for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE) + if (*next_end != OP_KET) + break; + + if (i == max) + { + common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end; + common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO; + /* +2 the original and the last. */ + common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2; + if (min == 1) + return TRUE; + min--; + max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE); + } + } + } + } + +if (min >= 3) + { + common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end; + common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT; + common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min; + return TRUE; + } + +return FALSE; +} + +#define CASE_ITERATOR_PRIVATE_DATA_1 \ + case OP_MINSTAR: \ + case OP_MINPLUS: \ + case OP_QUERY: \ + case OP_MINQUERY: \ + case OP_MINSTARI: \ + case OP_MINPLUSI: \ + case OP_QUERYI: \ + case OP_MINQUERYI: \ + case OP_NOTMINSTAR: \ + case OP_NOTMINPLUS: \ + case OP_NOTQUERY: \ + case OP_NOTMINQUERY: \ + case OP_NOTMINSTARI: \ + case OP_NOTMINPLUSI: \ + case OP_NOTQUERYI: \ + case OP_NOTMINQUERYI: + +#define CASE_ITERATOR_PRIVATE_DATA_2A \ + case OP_STAR: \ + case OP_PLUS: \ + case OP_STARI: \ + case OP_PLUSI: \ + case OP_NOTSTAR: \ + case OP_NOTPLUS: \ + case OP_NOTSTARI: \ + case OP_NOTPLUSI: + +#define CASE_ITERATOR_PRIVATE_DATA_2B \ + case OP_UPTO: \ + case OP_MINUPTO: \ + case OP_UPTOI: \ + case OP_MINUPTOI: \ + case OP_NOTUPTO: \ + case OP_NOTMINUPTO: \ + case OP_NOTUPTOI: \ + case OP_NOTMINUPTOI: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ + case OP_TYPEMINSTAR: \ + case OP_TYPEMINPLUS: \ + case OP_TYPEQUERY: \ + case OP_TYPEMINQUERY: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ + case OP_TYPESTAR: \ + case OP_TYPEPLUS: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ + case OP_TYPEUPTO: \ + case OP_TYPEMINUPTO: + +static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend) +{ +PCRE2_SPTR cc = common->start; +PCRE2_SPTR alternative; +PCRE2_SPTR end = NULL; +int private_data_ptr = *private_data_start; +int space, size, bracketlen; +BOOL repeat_check = TRUE; + +while (cc < ccend) + { + space = 0; + size = 0; + bracketlen = 0; + if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) + break; + + if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)) + { + if (detect_repeat(common, cc)) + { + /* These brackets are converted to repeats, so no global + based single character repeat is allowed. */ + if (cc >= end) + end = bracketend(cc); + } + } + repeat_check = TRUE; + + switch(*cc) + { + case OP_KET: + if (common->private_data_ptrs[cc + 1 - common->start] != 0) + { + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + cc += common->private_data_ptrs[cc + 1 - common->start]; + } + cc += 1 + LINK_SIZE; + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + } + bracketlen = 1 + LINK_SIZE; + break; + + case OP_BRA: + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + repeat_check = FALSE; + size = 1; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + space = 1; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + space = 2; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + space = 2; + size = -(2 + IMM2_SIZE); + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + space = 1; + size = 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) + space = 2; + size = 1; + break; + + case OP_TYPEUPTO: + if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) + space = 2; + size = 1 + IMM2_SIZE; + break; + + case OP_TYPEMINUPTO: + space = 2; + size = 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: + size = 1 + 32 / sizeof(PCRE2_UCHAR); + space = get_class_iterator_size(cc + size); + break; + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + size = GET(cc, 1); + space = get_class_iterator_size(cc + size); + break; +#endif + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + + /* Character iterators, which are not inside a repeated bracket, + gets a private slot instead of allocating it on the stack. */ + if (space > 0 && cc >= end) + { + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw) * space; + } + + if (size != 0) + { + if (size < 0) + { + cc += -size; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + } + else + cc += size; + } + + if (bracketlen > 0) + { + if (cc >= end) + { + end = bracketend(cc); + if (end[-1 - LINK_SIZE] == OP_KET) + end = NULL; + } + cc += bracketlen; + } + } +*private_data_start = private_data_ptr; +} + +/* Returns with a frame_types (always < 0) if no need for frame. */ +static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head) +{ +int length = 0; +int possessive = 0; +BOOL stack_restore = FALSE; +BOOL setsom_found = recursive; +BOOL setmark_found = recursive; +/* The last capture is a local variable even for recursions. */ +BOOL capture_last_found = FALSE; + +#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD +SLJIT_ASSERT(common->control_head_ptr != 0); +*needs_control_head = TRUE; +#else +*needs_control_head = FALSE; +#endif + +if (ccend == NULL) + { + ccend = bracketend(cc) - (1 + LINK_SIZE); + if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) + { + possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; + /* This is correct regardless of common->capture_last_ptr. */ + capture_last_found = TRUE; + } + cc = next_opcode(common, cc); + } + +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + SLJIT_ASSERT(common->has_set_som); + stack_restore = TRUE; + if (!setsom_found) + { + length += 2; + setsom_found = TRUE; + } + cc += 1; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_THEN_ARG: + SLJIT_ASSERT(common->mark_ptr != 0); + stack_restore = TRUE; + if (!setmark_found) + { + length += 2; + setmark_found = TRUE; + } + if (common->control_head_ptr != 0) + *needs_control_head = TRUE; + cc += 1 + 2 + cc[1]; + break; + + case OP_RECURSE: + stack_restore = TRUE; + if (common->has_set_som && !setsom_found) + { + length += 2; + setsom_found = TRUE; + } + if (common->mark_ptr != 0 && !setmark_found) + { + length += 2; + setmark_found = TRUE; + } + if (common->capture_last_ptr != 0 && !capture_last_found) + { + length += 2; + capture_last_found = TRUE; + } + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + stack_restore = TRUE; + if (common->capture_last_ptr != 0 && !capture_last_found) + { + length += 2; + capture_last_found = TRUE; + } + length += 3; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_THEN: + stack_restore = TRUE; + if (common->control_head_ptr != 0) + *needs_control_head = TRUE; + cc ++; + break; + + default: + stack_restore = TRUE; + /* Fall through. */ + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_NOTPROP: + case OP_PROP: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + + case OP_CALLOUT: + case OP_CALLOUT_STR: + + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +/* Possessive quantifiers can use a special case. */ +if (SLJIT_UNLIKELY(possessive == length)) + return stack_restore ? no_frame : no_stack; + +if (length > 0) + return length + 1; +return stack_restore ? no_frame : no_stack; +} + +static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop, BOOL recursive) +{ +DEFINE_COMPILER; +BOOL setsom_found = recursive; +BOOL setmark_found = recursive; +/* The last capture is a local variable even for recursions. */ +BOOL capture_last_found = FALSE; +int offset; + +/* >= 1 + shortest item size (2) */ +SLJIT_UNUSED_ARG(stacktop); +SLJIT_ASSERT(stackpos >= stacktop + 2); + +stackpos = STACK(stackpos); +if (ccend == NULL) + { + ccend = bracketend(cc) - (1 + LINK_SIZE); + if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) + cc = next_opcode(common, cc); + } + +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + SLJIT_ASSERT(common->has_set_som); + if (!setsom_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + setsom_found = TRUE; + } + cc += 1; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_THEN_ARG: + SLJIT_ASSERT(common->mark_ptr != 0); + if (!setmark_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + setmark_found = TRUE; + } + cc += 1 + 2 + cc[1]; + break; + + case OP_RECURSE: + if (common->has_set_som && !setsom_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + setsom_found = TRUE; + } + if (common->mark_ptr != 0 && !setmark_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + setmark_found = TRUE; + } + if (common->capture_last_ptr != 0 && !capture_last_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + capture_last_found = TRUE; + } + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + if (common->capture_last_ptr != 0 && !capture_last_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + capture_last_found = TRUE; + } + offset = (GET2(cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); + stackpos += (int)sizeof(sljit_sw); + + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0); +SLJIT_ASSERT(stackpos == STACK(stacktop)); +} + +static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL needs_control_head) +{ +int private_data_length = needs_control_head ? 3 : 2; +int size; +PCRE2_SPTR alternative; +/* Calculate the sum of the private machine words. */ +while (cc < ccend) + { + size = 0; + switch(*cc) + { + case OP_KET: + if (PRIVATE_DATA(cc) != 0) + { + private_data_length++; + SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); + cc += PRIVATE_DATA(cc + 1); + } + cc += 1 + LINK_SIZE; + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + private_data_length++; + SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + private_data_length++; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + private_data_length += 2; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + private_data_length++; + cc += 1 + LINK_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + private_data_length++; + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + private_data_length++; + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); +#else + size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); +#endif + if (PRIVATE_DATA(cc)) + private_data_length += get_class_iterator_size(cc + size); + cc += size; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +SLJIT_ASSERT(cc == ccend); +return private_data_length; +} + +static void copy_private_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, + BOOL save, int stackptr, int stacktop, BOOL needs_control_head) +{ +DEFINE_COMPILER; +int srcw[2]; +int count, size; +BOOL tmp1next = TRUE; +BOOL tmp1empty = TRUE; +BOOL tmp2empty = TRUE; +PCRE2_SPTR alternative; +enum { + start, + loop, + end +} status; + +status = save ? start : loop; +stackptr = STACK(stackptr - 2); +stacktop = STACK(stacktop - 1); + +if (!save) + { + stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw); + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + tmp1empty = FALSE; + } + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + tmp2empty = FALSE; + } + /* The tmp1next must be TRUE in either way. */ + } + +do + { + count = 0; + switch(status) + { + case start: + SLJIT_ASSERT(save && common->recursive_head_ptr != 0); + count = 1; + srcw[0] = common->recursive_head_ptr; + if (needs_control_head) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + count = 2; + srcw[1] = common->control_head_ptr; + } + status = loop; + break; + + case loop: + if (cc >= ccend) + { + status = end; + break; + } + + switch(*cc) + { + case OP_KET: + if (PRIVATE_DATA(cc) != 0) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); + cc += PRIVATE_DATA(cc + 1); + } + cc += 1 + LINK_SIZE; + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + count = 1; + srcw[0] = PRIVATE_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + { + count = 1; + srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + } + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0); + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + } + cc += 1 + LINK_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + } + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); + } + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); + } + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + } + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + } + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + } + cc += 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); +#else + size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); +#endif + if (PRIVATE_DATA(cc)) + switch(get_class_iterator_size(cc + size)) + { + case 1: + count = 1; + srcw[0] = PRIVATE_DATA(cc); + break; + + case 2: + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += size; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + break; + + case end: + SLJIT_ASSERT_STOP(); + break; + } + + while (count > 0) + { + count--; + if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_sw); + } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); + tmp1empty = FALSE; + tmp1next = FALSE; + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_sw); + } + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); + tmp2empty = FALSE; + tmp1next = TRUE; + } + } + else + { + if (tmp1next) + { + SLJIT_ASSERT(!tmp1empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0); + tmp1empty = stackptr >= stacktop; + if (!tmp1empty) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + } + tmp1next = FALSE; + } + else + { + SLJIT_ASSERT(!tmp2empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0); + tmp2empty = stackptr >= stacktop; + if (!tmp2empty) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + } + tmp1next = TRUE; + } + } + } + } +while (status != end); + +if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_sw); + } + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_sw); + } + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_sw); + } + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_sw); + } + } + } +SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); +} + +static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_ub *current_offset) +{ +PCRE2_SPTR end = bracketend(cc); +BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; + +/* Assert captures then. */ +if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) + current_offset = NULL; +/* Conditional block does not. */ +if (*cc == OP_COND || *cc == OP_SCOND) + has_alternatives = FALSE; + +cc = next_opcode(common, cc); +if (has_alternatives) + current_offset = common->then_offsets + (cc - common->start); + +while (cc < end) + { + if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) + cc = set_then_offsets(common, cc, current_offset); + else + { + if (*cc == OP_ALT && has_alternatives) + current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) + *current_offset = 1; + cc = next_opcode(common, cc); + } + } + +return end; +} + +#undef CASE_ITERATOR_PRIVATE_DATA_1 +#undef CASE_ITERATOR_PRIVATE_DATA_2A +#undef CASE_ITERATOR_PRIVATE_DATA_2B +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1 +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + +static SLJIT_INLINE BOOL is_powerof2(unsigned int value) +{ +return (value & (value - 1)) == 0; +} + +static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) +{ +while (list) + { + /* sljit_set_label is clever enough to do nothing + if either the jump or the label is NULL. */ + SET_LABEL(list->jump, label); + list = list->next; + } +} + +static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump) +{ +jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); +if (list_item) + { + list_item->next = *list; + list_item->jump = jump; + *list = list_item; + } +} + +static void add_stub(compiler_common *common, struct sljit_jump *start) +{ +DEFINE_COMPILER; +stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); + +if (list_item) + { + list_item->start = start; + list_item->quit = LABEL(); + list_item->next = common->stubs; + common->stubs = list_item; + } +} + +static void flush_stubs(compiler_common *common) +{ +DEFINE_COMPILER; +stub_list *list_item = common->stubs; + +while (list_item) + { + JUMPHERE(list_item->start); + add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); + JUMPTO(SLJIT_JUMP, list_item->quit); + list_item = list_item->next; + } +common->stubs = NULL; +} + +static void add_label_addr(compiler_common *common, sljit_uw *update_addr) +{ +DEFINE_COMPILER; +label_addr_list *label_addr; + +label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list)); +if (label_addr == NULL) + return; +label_addr->label = LABEL(); +label_addr->update_addr = update_addr; +label_addr->next = common->label_addrs; +common->label_addrs = label_addr; +} + +static SLJIT_INLINE void count_match(compiler_common *common) +{ +DEFINE_COMPILER; + +OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); +add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO)); +} + +static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) +{ +/* May destroy all locals and registers except TMP2. */ +DEFINE_COMPILER; + +SLJIT_ASSERT(size > 0); +OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); +#ifdef DESTROY_REGISTERS +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); +OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); +#endif +add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); +} + +static SLJIT_INLINE void free_stack(compiler_common *common, int size) +{ +DEFINE_COMPILER; +SLJIT_ASSERT(size > 0); +OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); +} + +static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size) +{ +DEFINE_COMPILER; +sljit_uw *result; + +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + +result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data); +if (SLJIT_UNLIKELY(result == NULL)) + { + sljit_set_compiler_memory_error(compiler); + return NULL; + } + +*(void**)result = common->read_only_data_head; +common->read_only_data_head = (void *)result; +return result + 1; +} + +static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +sljit_si i; + +/* At this point we can freely use all temporary registers. */ +SLJIT_ASSERT(length > 1); +/* TMP1 returns with begin - 1. */ +OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); +if (length < 8) + { + for (i = 1; i < length; i++) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0); + } +else + { + GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START); + OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, loop); + } +} + +static SLJIT_INLINE void reset_fast_fail(compiler_common *common) +{ +DEFINE_COMPILER; +sljit_si i; + +SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr); + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw)) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0); +} + +static SLJIT_INLINE void do_reset_match(compiler_common *common, int length) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +int i; + +SLJIT_ASSERT(length > 1); +/* OVECTOR(1) contains the "string begin - 1" constant. */ +if (length > 2) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); +if (length < 8) + { + for (i = 2; i < length; i++) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0); + } +else + { + GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, loop); + } + +OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); +if (common->control_head_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); +} + +static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg) +{ +while (current != NULL) + { + switch (current[-2]) + { + case type_then_trap: + break; + + case type_mark: + if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[-3]) == 0) + return current[-4]; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + SLJIT_ASSERT(current > (sljit_sw*)current[-1]); + current = (sljit_sw*)current[-1]; + } +return -1; +} + +static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) +{ +DEFINE_COMPILER; +struct sljit_label *loop; + +/* At this point we can freely use all registers. */ +OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0); + +OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); +OP1(SLJIT_MOV_UI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); +OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data), + SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE)); + +GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START); +OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); + +loop = LABEL(); +OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); +OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); +/* Copy the integer value to the output buffer */ +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8); +if (sizeof(PCRE2_SIZE) == 4) + OP1(SLJIT_MOVU_UI, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); +else + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_NOT_ZERO, loop); + +/* Calculate the return value, which is the maximum ovector value. */ +if (topbracket > 1) + { + GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1); + + /* OVECTOR(0) is never equal to SLJIT_S2. */ + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))); + OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0); + } +else + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); +} + +static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) +{ +DEFINE_COMPILER; +sljit_si mov_opcode; + +SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2); +SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 + && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0)); + +OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), + common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL); + +/* Store match begin and end. */ +OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0); +OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data)); + +mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; + +OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0); + +OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S0, 0); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0); + +JUMPTO(SLJIT_JUMP, quit); +} + +static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) +{ +/* May destroy TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + { + /* The value of -1 must be kept for start_used_ptr! */ + OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1); + /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting + is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ + jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +else if (common->mode == PCRE2_JIT_PARTIAL_HARD) + { + jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +} + +static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc) +{ +/* Detects if the character has an othercase. */ +unsigned int c; + +#ifdef SUPPORT_UNICODE +if (common->utf) + { + GETCHAR(c, cc); + if (c > 127) + { + return c != UCD_OTHERCASE(c); + } +#if PCRE2_CODE_UNIT_WIDTH != 8 + return common->fcc[c] != c; +#endif + } +else +#endif + c = *cc; +return MAX_255(c) ? common->fcc[c] != c : FALSE; +} + +static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) +{ +/* Returns with the othercase. */ +#ifdef SUPPORT_UNICODE +if (common->utf && c > 127) + { + return UCD_OTHERCASE(c); + } +#endif +return TABLE_GET(c, common->fcc, c); +} + +static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc) +{ +/* Detects if the character and its othercase has only 1 bit difference. */ +unsigned int c, oc, bit; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +int n; +#endif + +#ifdef SUPPORT_UNICODE +if (common->utf) + { + GETCHAR(c, cc); + if (c <= 127) + oc = common->fcc[c]; + else + { + oc = UCD_OTHERCASE(c); + } + } +else + { + c = *cc; + oc = TABLE_GET(c, common->fcc, c); + } +#else +c = *cc; +oc = TABLE_GET(c, common->fcc, c); +#endif + +SLJIT_ASSERT(c != oc); + +bit = c ^ oc; +/* Optimized for English alphabet. */ +if (c <= 127 && bit == 0x20) + return (0 << 8) | 0x20; + +/* Since c != oc, they must have at least 1 bit difference. */ +if (!is_powerof2(bit)) + return 0; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + +#ifdef SUPPORT_UNICODE +if (common->utf && c > 127) + { + n = GET_EXTRALEN(*cc); + while ((bit & 0x3f) == 0) + { + n--; + bit >>= 6; + } + return (n << 8) | bit; + } +#endif /* SUPPORT_UNICODE */ +return (0 << 8) | bit; + +#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + +#ifdef SUPPORT_UNICODE +if (common->utf && c > 65535) + { + if (bit >= (1 << 10)) + bit >>= 10; + else + return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); + } +#endif /* SUPPORT_UNICODE */ +return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); + +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +} + +static void check_partial(compiler_common *common, BOOL force) +{ +/* Checks whether a partial matching is occurred. Does not modify registers. */ +DEFINE_COMPILER; +struct sljit_jump *jump = NULL; + +SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE); + +if (common->mode == PCRE2_JIT_COMPLETE) + return; + +if (!force) + jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); +else if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); + +if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); +else + { + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } + +if (jump != NULL) + JUMPHERE(jump); +} + +static void check_str_end(compiler_common *common, jump_list **end_reached) +{ +/* Does not affect registers. Usually used in a tight spot. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (common->mode == PCRE2_JIT_COMPLETE) + { + add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + return; + } + +jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + { + add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); + add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); + } +else + { + add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } +JUMPHERE(jump); +} + +static void detect_partial_match(compiler_common *common, jump_list **backtracks) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (common->mode == PCRE2_JIT_COMPLETE) + { + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + return; + } + +/* Partial matching mode. */ +jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); +add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); +if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + } +else + { + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } +JUMPHERE(jump); +} + +static void peek_char(compiler_common *common, sljit_ui max) +{ +/* Reads the character into TMP1, keeps STR_PTR. +Does not check STR_END. TMP2 Destroyed. */ +DEFINE_COMPILER; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_jump *jump; +#endif + +SLJIT_UNUSED_ARG(max); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { + if (max < 128) return; + + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + if (max < 0xd800) return; + + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + /* TMP2 contains the high surrogate. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif +} + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + +static BOOL is_char7_bitset(const sljit_ub *bitset, BOOL nclass) +{ +/* Tells whether the character codes below 128 are enough +to determine a match. */ +const sljit_ub value = nclass ? 0xff : 0; +const sljit_ub *end = bitset + 32; + +bitset += 16; +do + { + if (*bitset++ != value) + return FALSE; + } +while (bitset < end); +return TRUE; +} + +static void read_char7_type(compiler_common *common, BOOL full_read) +{ +/* Reads the precise character type of a character into TMP1, if the character +is less than 128. Otherwise it returns with zero. Does not check STR_END. The +full_read argument tells whether characters above max are accepted or not. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +SLJIT_ASSERT(common->utf); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + +if (full_read) + { + jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +} + +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ + +static void read_char_range(compiler_common *common, sljit_ui min, sljit_ui max, BOOL update_str_ptr) +{ +/* Reads the precise value of a character into TMP1, if the character is +between min and max (c >= min && c <= max). Otherwise it returns with a value +outside the range. Does not check STR_END. */ +DEFINE_COMPILER; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_jump *jump; +#endif +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +struct sljit_jump *jump2; +#endif + +SLJIT_UNUSED_ARG(update_str_ptr); +SLJIT_UNUSED_ARG(min); +SLJIT_UNUSED_ARG(max); +SLJIT_ASSERT(min <= max); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { + if (max < 128 && !update_str_ptr) return; + + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + if (min >= 0x10000) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); + if (update_str_ptr) + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump2); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + else if (min >= 0x800 && max <= 0xffff) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); + if (update_str_ptr) + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump2); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + else if (max >= 0x800) + add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + else if (max < 128) + { + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + } + else + { + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + else + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + JUMPHERE(jump); + } +#endif + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + if (max >= 0x10000) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + /* TMP2 contains the high surrogate. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump); + return; + } + + if (max < 0xd800 && !update_str_ptr) return; + + /* Skip low surrogate if necessary. */ + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (max >= 0xd800) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); + JUMPHERE(jump); + } +#endif +} + +static SLJIT_INLINE void read_char(compiler_common *common) +{ +read_char_range(common, 0, READ_CHAR_MAX, TRUE); +} + +static void read_char8_type(compiler_common *common, BOOL update_str_ptr) +{ +/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ +DEFINE_COMPILER; +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 +struct sljit_jump *jump; +#endif +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +struct sljit_jump *jump2; +#endif + +SLJIT_UNUSED_ARG(update_str_ptr); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { + /* This can be an extra read in some situations, but hopefully + it is needed in most cases. */ + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); + if (!update_str_ptr) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); + jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + JUMPHERE(jump2); + } + else + add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); + return; + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 +/* The ctypes array contains only 256 values. */ +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +#if PCRE2_CODE_UNIT_WIDTH != 8 +JUMPHERE(jump); +#endif + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf && update_str_ptr) + { + /* Skip low surrogate if necessary. */ + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(jump); + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */ +} + +static void skip_char_back(compiler_common *common) +{ +/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ +DEFINE_COMPILER; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +#if PCRE2_CODE_UNIT_WIDTH == 8 +struct sljit_label *label; + +if (common->utf) + { + label = LABEL(); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); + return; + } +#elif PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + /* Skip low surrogate if necessary. */ + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + return; + } +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +} + +static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch) +{ +/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (nltype == NLTYPE_ANY) + { + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + } +else if (nltype == NLTYPE_ANYCRLF) + { + if (jumpifmatch) + { + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + JUMPHERE(jump); + } + } +else + { + SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); + add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } +} + +#ifdef SUPPORT_UNICODE + +#if PCRE2_CODE_UNIT_WIDTH == 8 +static void do_utfreadchar(compiler_common *common) +{ +/* Fast decoding a UTF-8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); +jump = JUMP(SLJIT_NOT_ZERO); +/* Two byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); +jump = JUMP(SLJIT_NOT_ZERO); +/* Three byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +/* Four byte sequence. */ +JUMPHERE(jump); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void do_utfreadchar16(compiler_common *common) +{ +/* Fast decoding a UTF-8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return value in TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); +jump = JUMP(SLJIT_NOT_ZERO); +/* Two byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO); +/* This code runs only in 8 bit mode. No need to shift the value. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +/* Three byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void do_utfreadtype8(compiler_common *common) +{ +/* Fast decoding a UTF-8 character type. TMP2 contains the first byte +of the character (>= 0xc0). Return value in TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_jump *compare; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); +jump = JUMP(SLJIT_NOT_ZERO); +/* Two byte sequence. */ +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); +/* The upper 5 bits are known at this point. */ +compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(compare); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +/* We only have types for characters less than 256. */ +JUMPHERE(jump); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + +/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ +#define UCD_BLOCK_MASK 127 +#define UCD_BLOCK_SHIFT 7 + +static void do_getucd(compiler_common *common) +{ +/* Search the UCD record for the character comes in TMP1. +Returns chartype in TMP1 and UCD offset in TMP2. */ +DEFINE_COMPILER; + +SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); +OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#endif /* SUPPORT_UNICODE */ + +static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, uint32_t overall_options) +{ +DEFINE_COMPILER; +struct sljit_label *mainloop; +struct sljit_label *newlinelabel = NULL; +struct sljit_jump *start; +struct sljit_jump *end = NULL; +struct sljit_jump *end2 = NULL; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_jump *singlechar; +#endif +jump_list *newline = NULL; +BOOL newlinecheck = FALSE; +BOOL readuchar = FALSE; + +if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0) + && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) + newlinecheck = TRUE; + +SLJIT_ASSERT(common->forced_quit_label == NULL); + +if ((overall_options & PCRE2_FIRSTLINE) != 0) + { + /* Search for the end of the first line. */ + SLJIT_ASSERT(common->match_end_ptr != 0); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + mainloop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); + JUMPHERE(end); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + { + end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + mainloop = LABEL(); + /* Continual stores does not cause data dependency. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + check_newlinechar(common, common->nltype, &newline, TRUE); + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop); + JUMPHERE(end); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); + set_jumps(newline, LABEL()); + } + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + } +else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0) + { + /* Check whether offset limit is set and valid. */ + SLJIT_ASSERT(common->match_end_ptr != 0); + + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit)); + OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); + end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); +#if PCRE2_CODE_UNIT_WIDTH == 16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +#elif PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); +#endif + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); + JUMPHERE(end2); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + add_jump(compiler, &common->forced_quit, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0)); + JUMPHERE(end); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0); + } + +start = JUMP(SLJIT_JUMP); + +if (newlinecheck) + { + newlinelabel = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + end2 = JUMP(SLJIT_JUMP); + } + +mainloop = LABEL(); + +/* Increasing the STR_PTR here requires one less jump in the most common case. */ +#ifdef SUPPORT_UNICODE +if (common->utf) readuchar = TRUE; +#endif +if (newlinecheck) readuchar = TRUE; + +if (readuchar) + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if (newlinecheck) + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { + singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlechar); + } +#elif PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlechar); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ +JUMPHERE(start); + +if (newlinecheck) + { + JUMPHERE(end); + JUMPHERE(end2); + } + +return mainloop; +} + +#define MAX_N_CHARS 16 +#define MAX_DIFF_CHARS 6 + +static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, PCRE2_UCHAR *chars) +{ +PCRE2_UCHAR i, len; + +len = chars[0]; +if (len == 255) + return; + +if (len == 0) + { + chars[0] = 1; + chars[1] = chr; + return; + } + +for (i = len; i > 0; i--) + if (chars[i] == chr) + return; + +if (len >= MAX_DIFF_CHARS - 1) + { + chars[0] = 255; + return; + } + +len++; +chars[len] = chr; +chars[0] = len; +} + +static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, uint32_t *rec_count) +{ +/* Recursive function, which scans prefix literals. */ +BOOL last, any, class, caseless; +int len, repeat, len_save, consumed = 0; +sljit_ui chr; /* Any unicode character. */ +sljit_ub *bytes, *bytes_end, byte; +PCRE2_SPTR alternative, cc_save, oc; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +PCRE2_UCHAR othercase[8]; +#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +PCRE2_UCHAR othercase[2]; +#else +PCRE2_UCHAR othercase[1]; +#endif + +repeat = 1; +while (TRUE) + { + if (*rec_count == 0) + return 0; + (*rec_count)--; + + last = TRUE; + any = FALSE; + class = FALSE; + caseless = FALSE; + + switch (*cc) + { + case OP_CHARI: + caseless = TRUE; + case OP_CHAR: + last = FALSE; + cc++; + break; + + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + cc = bracketend(cc); + continue; + + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + caseless = TRUE; + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + cc++; + break; + + case OP_EXACTI: + caseless = TRUE; + case OP_EXACT: + repeat = GET2(cc, 1); + last = FALSE; + cc += 1 + IMM2_SIZE; + break; + + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + caseless = TRUE; + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + len = 1; + cc++; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); +#endif + max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; + last = FALSE; + break; + + case OP_KET: + cc += 1 + LINK_SIZE; + continue; + + case OP_ALT: + cc += GET(cc, 1); + continue; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_CBRA: + case OP_CBRAPOS: + alternative = cc + GET(cc, 1); + while (*alternative == OP_ALT) + { + max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; + alternative += GET(alternative, 1); + } + + if (*cc == OP_CBRA || *cc == OP_CBRAPOS) + cc += IMM2_SIZE; + cc += 1 + LINK_SIZE; + continue; + + case OP_CLASS: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && !is_char7_bitset((const sljit_ub *)(cc + 1), FALSE)) return consumed; +#endif + class = TRUE; + break; + + case OP_NCLASS: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) return consumed; +#endif + class = TRUE; + break; + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc += GET(cc, 1); + break; +#endif + + case OP_DIGIT: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_digit, FALSE)) + return consumed; +#endif + any = TRUE; + cc++; + break; + + case OP_WHITESPACE: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_space, FALSE)) + return consumed; +#endif + any = TRUE; + cc++; + break; + + case OP_WORDCHAR: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_word, FALSE)) + return consumed; +#endif + any = TRUE; + cc++; + break; + + case OP_NOT: + case OP_NOTI: + cc++; + /* Fall through. */ + case OP_NOT_DIGIT: + case OP_NOT_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_ANY: + case OP_ALLANY: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc++; + break; + +#ifdef SUPPORT_UNICODE + case OP_NOTPROP: + case OP_PROP: +#if PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc += 1 + 2; + break; +#endif + + case OP_TYPEEXACT: + repeat = GET2(cc, 1); + cc += 1 + IMM2_SIZE; + continue; + + case OP_NOTEXACT: + case OP_NOTEXACTI: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) return consumed; +#endif + any = TRUE; + repeat = GET2(cc, 1); + cc += 1 + IMM2_SIZE + 1; + break; + + default: + return consumed; + } + + if (any) + { + do + { + chars[0] = 255; + + consumed++; + if (--max_chars == 0) + return consumed; + chars += MAX_DIFF_CHARS; + } + while (--repeat > 0); + + repeat = 1; + continue; + } + + if (class) + { + bytes = (sljit_ub*) (cc + 1); + cc += 1 + 32 / sizeof(PCRE2_UCHAR); + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; + break; + + default: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + repeat = GET2(cc, 1); + if (repeat <= 0) + return consumed; + break; + } + + do + { + if (bytes[31] & 0x80) + chars[0] = 255; + else if (chars[0] != 255) + { + bytes_end = bytes + 32; + chr = 0; + do + { + byte = *bytes++; + SLJIT_ASSERT((chr & 0x7) == 0); + if (byte == 0) + chr += 8; + else + { + do + { + if ((byte & 0x1) != 0) + add_prefix_char(chr, chars); + byte >>= 1; + chr++; + } + while (byte != 0); + chr = (chr + 7) & ~7; + } + } + while (chars[0] != 255 && bytes < bytes_end); + bytes = bytes_end - 32; + } + + consumed++; + if (--max_chars == 0) + return consumed; + chars += MAX_DIFF_CHARS; + } + while (--repeat > 0); + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + return consumed; + + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE)) + return consumed; + cc += 1 + 2 * IMM2_SIZE; + break; + } + + repeat = 1; + continue; + } + + len = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); +#endif + + if (caseless && char_has_othercase(common, cc)) + { +#ifdef SUPPORT_UNICODE + if (common->utf) + { + GETCHAR(chr, cc); + if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) + return consumed; + } + else +#endif + { + chr = *cc; + othercase[0] = TABLE_GET(chr, common->fcc, chr); + } + } + else + { + caseless = FALSE; + othercase[0] = 0; /* Stops compiler warning - PH */ + } + + len_save = len; + cc_save = cc; + while (TRUE) + { + oc = othercase; + do + { + chr = *cc; + add_prefix_char(*cc, chars); + + if (caseless) + add_prefix_char(*oc, chars); + + len--; + consumed++; + if (--max_chars == 0) + return consumed; + chars += MAX_DIFF_CHARS; + cc++; + oc++; + } + while (len > 0); + + if (--repeat == 0) + break; + + len = len_save; + cc = cc_save; + } + + repeat = 1; + if (last) + return consumed; + } +} + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +static sljit_si character_to_int32(PCRE2_UCHAR chr) +{ +sljit_si value = (sljit_si)chr; +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define SSE2_COMPARE_TYPE_INDEX 0 +return (value << 24) | (value << 16) | (value << 8) | value; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define SSE2_COMPARE_TYPE_INDEX 1 +return (value << 16) | value; +#elif PCRE2_CODE_UNIT_WIDTH == 32 +#define SSE2_COMPARE_TYPE_INDEX 2 +return value; +#else +#error "Unsupported unit width" +#endif +} + +static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit[3]; +struct sljit_jump *nomatch; +sljit_ub instruction[8]; +sljit_si tmp1_ind = sljit_get_register_index(TMP1); +sljit_si tmp2_ind = sljit_get_register_index(TMP2); +sljit_si str_ptr_ind = sljit_get_register_index(STR_PTR); +BOOL load_twice = FALSE; +PCRE2_UCHAR bit; + +bit = char1 ^ char2; +if (!is_powerof2(bit)) + bit = 0; + +if ((char1 != char2) && bit == 0) + load_twice = TRUE; + +quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); + +SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1); + +/* MOVD xmm, r/m32 */ +instruction[0] = 0x66; +instruction[1] = 0x0f; +instruction[2] = 0x6e; +instruction[3] = 0xc0 | (2 << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + + /* MOVD xmm, r/m32 */ + instruction[3] = 0xc0 | (3 << 3) | tmp1_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PSHUFD xmm1, xmm2/m128, imm8 */ +instruction[2] = 0x70; +instruction[3] = 0xc0 | (2 << 3) | 2; +instruction[4] = 0; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char1 != char2) + { + /* PSHUFD xmm1, xmm2/m128, imm8 */ + instruction[3] = 0xc0 | (3 << 3) | 3; + instruction[4] = 0; + sljit_emit_op_custom(compiler, instruction, 5); + } + +OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); + +/* MOVDQA xmm1, xmm2/m128 */ +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +if (str_ptr_ind < 8) + { + instruction[2] = 0x6f; + instruction[3] = (0 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + } +else + { + instruction[1] = 0x41; + instruction[2] = 0x0f; + instruction[3] = 0x6f; + instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); + sljit_emit_op_custom(compiler, instruction, 5); + + if (load_twice) + { + instruction[4] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + instruction[1] = 0x0f; + } + +#else + +instruction[2] = 0x6f; +instruction[3] = (0 << 3) | str_ptr_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +#endif + +if (bit != 0) + { + /* POR xmm1, xmm2/m128 */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (0 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PCMPEQB/W/D xmm1, xmm2/m128 */ +instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; +instruction[3] = 0xc0 | (0 << 3) | 2; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (1 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PMOVMSKB reg, xmm */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); + instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; + sljit_emit_op_custom(compiler, instruction, 4); + + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); + } + +OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +nomatch = JUMP(SLJIT_ZERO); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +quit[1] = JUMP(SLJIT_JUMP); + +JUMPHERE(nomatch); + +start = LABEL(); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +/* Second part (aligned) */ + +instruction[0] = 0x66; +instruction[1] = 0x0f; + +/* MOVDQA xmm1, xmm2/m128 */ +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +if (str_ptr_ind < 8) + { + instruction[2] = 0x6f; + instruction[3] = (0 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + } +else + { + instruction[1] = 0x41; + instruction[2] = 0x0f; + instruction[3] = 0x6f; + instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); + sljit_emit_op_custom(compiler, instruction, 5); + + if (load_twice) + { + instruction[4] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + instruction[1] = 0x0f; + } + +#else + +instruction[2] = 0x6f; +instruction[3] = (0 << 3) | str_ptr_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +#endif + +if (bit != 0) + { + /* POR xmm1, xmm2/m128 */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (0 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PCMPEQB/W/D xmm1, xmm2/m128 */ +instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; +instruction[3] = 0xc0 | (0 << 3) | 2; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (1 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PMOVMSKB reg, xmm */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; + sljit_emit_op_custom(compiler, instruction, 4); + + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + } + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +JUMPTO(SLJIT_ZERO, start); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +start = LABEL(); +SET_LABEL(quit[0], start); +SET_LABEL(quit[1], start); +SET_LABEL(quit[2], start); +} + +#undef SSE2_COMPARE_TYPE_INDEX + +#endif + +static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_si offset) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +struct sljit_jump *found; +PCRE2_UCHAR mask; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *utf_start = NULL; +struct sljit_jump *utf_quit = NULL; +#endif +BOOL has_match_end = (common->match_end_ptr != 0); + +if (offset > 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + +if (has_match_end) + { + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + + OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1)); +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + if (sljit_x86_is_cmov_available()) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0); + sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0); + } +#endif + { + quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + JUMPHERE(quit); + } + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + utf_start = LABEL(); +#endif + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* SSE2 accelerated first character search. */ + +if (sljit_x86_is_sse2_available()) + { + fast_forward_first_char2_sse2(common, char1, char2); + + SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0); + if (common->mode == PCRE2_JIT_COMPLETE) + { + /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */ + SLJIT_ASSERT(common->forced_quit_label == NULL); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf && offset > 0) + { + SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); +#else +#error "Unknown code width" +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } +#endif + + if (offset > 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + } + else if (sljit_x86_is_cmov_available()) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); + } + else + { + quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); + JUMPHERE(quit); + } + + if (has_match_end) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + return; + } + +#endif + +quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +start = LABEL(); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if (char1 == char2) + found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1); +else + { + mask = char1 ^ char2; + if (is_powerof2(mask)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); + found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask); + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + found = JUMP(SLJIT_NOT_ZERO); + } + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + utf_quit = JUMP(SLJIT_JUMP); +#endif + +JUMPHERE(found); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); +#else +#error "Unknown code width" +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(utf_quit); + } +#endif + +JUMPHERE(quit); + +if (has_match_end) + { + quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + if (offset > 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + JUMPHERE(quit); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + } + +if (offset > 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); +} + +static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +struct sljit_jump *match; +/* bytes[0] represent the number of characters between 0 +and MAX_N_BYTES - 1, 255 represents any character. */ +PCRE2_UCHAR chars[MAX_N_CHARS * MAX_DIFF_CHARS]; +sljit_si offset; +PCRE2_UCHAR mask; +PCRE2_UCHAR *char_set, *char_set_end; +int i, max, from; +int range_right = -1, range_len; +sljit_ub *update_table = NULL; +BOOL in_range; +uint32_t rec_count; + +for (i = 0; i < MAX_N_CHARS; i++) + chars[i * MAX_DIFF_CHARS] = 0; + +rec_count = 10000; +max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count); + +if (max < 1) + return FALSE; + +in_range = FALSE; +/* Prevent compiler "uninitialized" warning */ +from = 0; +range_len = 4 /* minimum length */ - 1; +for (i = 0; i <= max; i++) + { + if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255)) + { + range_len = i - from; + range_right = i - 1; + } + + if (i < max && chars[i * MAX_DIFF_CHARS] < 255) + { + SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0); + if (!in_range) + { + in_range = TRUE; + from = i; + } + } + else + in_range = FALSE; + } + +if (range_right >= 0) + { + update_table = (sljit_ub *)allocate_read_only_data(common, 256); + if (update_table == NULL) + return TRUE; + memset(update_table, IN_UCHARS(range_len), 256); + + for (i = 0; i < range_len; i++) + { + char_set = chars + ((range_right - i) * MAX_DIFF_CHARS); + SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255); + char_set_end = char_set + char_set[0]; + char_set++; + while (char_set <= char_set_end) + { + if (update_table[(*char_set) & 0xff] > IN_UCHARS(i)) + update_table[(*char_set) & 0xff] = IN_UCHARS(i); + char_set++; + } + } + } + +offset = -1; +/* Scan forward. */ +for (i = 0; i < max; i++) + { + if (offset == -1) + { + if (chars[i * MAX_DIFF_CHARS] <= 2) + offset = i; + } + else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2) + { + if (chars[i * MAX_DIFF_CHARS] == 1) + offset = i; + else + { + mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; + if (!is_powerof2(mask)) + { + mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2]; + if (is_powerof2(mask)) + offset = i; + } + } + } + } + +if (range_right < 0) + { + if (offset < 0) + return FALSE; + SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2); + /* Works regardless the value is 1 or 2. */ + mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]]; + fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset); + return TRUE; + } + +if (range_right == offset) + offset = -1; + +SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2)); + +max -= 1; +SLJIT_ASSERT(max > 0); +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); + JUMPHERE(quit); + } +else + OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + +SLJIT_ASSERT(range_right >= 0); + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); +#endif + +start = LABEL(); +quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); +#else +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); +#endif + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); +#else +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); + +if (offset >= 0) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + if (chars[offset * MAX_DIFF_CHARS] == 1) + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start); + else + { + mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; + if (is_powerof2(mask)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start); + } + else + { + match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start); + JUMPHERE(match); + } + } + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset != 0) + { + if (offset < 0) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start); +#else +#error "Unknown code width" +#endif + if (offset < 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } +#endif + +if (offset >= 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +JUMPHERE(quit); + +if (common->match_end_ptr != 0) + { + if (range_right >= 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + if (range_right >= 0) + { + quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + JUMPHERE(quit); + } + } +else + OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); +return TRUE; +} + +#undef MAX_N_CHARS +#undef MAX_N_BYTES + +static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, PCRE2_UCHAR first_char, BOOL caseless) +{ +PCRE2_UCHAR oc; + +oc = first_char; +if (caseless) + { + oc = TABLE_GET(first_char, common->fcc, first_char); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (first_char > 127 && common->utf) + oc = UCD_OTHERCASE(first_char); +#endif + } + +fast_forward_first_char2(common, first_char, oc, 0); +} + +static SLJIT_INLINE void fast_forward_newline(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *lastchar; +struct sljit_jump *firstchar; +struct sljit_jump *quit; +struct sljit_jump *foundcr = NULL; +struct sljit_jump *notfoundnl; +jump_list *newline = NULL; + +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + } + +if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + + loop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); + + JUMPHERE(quit); + JUMPHERE(firstchar); + JUMPHERE(lastchar); + + if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + return; + } + +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); +skip_char_back(common); + +loop = LABEL(); +common->ff_newline_shortcut = loop; + +read_char_range(common, common->nlmin, common->nlmax, TRUE); +lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); +check_newlinechar(common, common->nltype, &newline, FALSE); +set_jumps(newline, loop); + +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + { + quit = JUMP(SLJIT_JUMP); + JUMPHERE(foundcr); + notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(notfoundnl); + JUMPHERE(quit); + } +JUMPHERE(lastchar); +JUMPHERE(firstchar); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks); + +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_ub *start_bits) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +struct sljit_jump *found = NULL; +jump_list *matches = NULL; +#if PCRE2_CODE_UNIT_WIDTH != 8 +struct sljit_jump *jump; +#endif + +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + } + +start = LABEL(); +quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UNICODE +if (common->utf) + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +#endif + +if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); + JUMPHERE(jump); +#endif + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + found = JUMP(SLJIT_NOT_ZERO); + } + +#ifdef SUPPORT_UNICODE +if (common->utf) + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#elif PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ +#endif /* SUPPORT_UNICODE */ +JUMPTO(SLJIT_JUMP, start); +if (found != NULL) + JUMPHERE(found); +if (matches != NULL) + set_jumps(matches, LABEL()); +JUMPHERE(quit); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); +} + +static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *toolong; +struct sljit_jump *alreadyfound; +struct sljit_jump *found; +struct sljit_jump *foundoc = NULL; +struct sljit_jump *notfound; +sljit_ui oc, bit; + +SLJIT_ASSERT(common->req_char_ptr != 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); +OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX); +toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0); +alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); + +if (has_firstchar) + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +else + OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); + +loop = LABEL(); +notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); +oc = req_char; +if (caseless) + { + oc = TABLE_GET(req_char, common->fcc, req_char); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (req_char > 127 && common->utf) + oc = UCD_OTHERCASE(req_char); +#endif + } +if (req_char == oc) + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); +else + { + bit = req_char ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); + } + else + { + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); + foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc); + } + } +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_JUMP, loop); + +JUMPHERE(found); +if (foundoc) + JUMPHERE(foundoc); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0); +JUMPHERE(alreadyfound); +JUMPHERE(toolong); +return notfound; +} + +static void do_revertframes(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *mainloop; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); +GET_LOCAL_BASE(TMP3, 0, 0); + +/* Drop frames until we reach STACK_TOP. */ +mainloop = LABEL(); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); +OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_SIG_LESS_EQUAL); + +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); +JUMPTO(SLJIT_JUMP, mainloop); + +JUMPHERE(jump); +jump = JUMP(SLJIT_SIG_LESS); +/* End of dropping frames. */ +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); +JUMPTO(SLJIT_JUMP, mainloop); +} + +static void check_wordboundary(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *skipread; +jump_list *skipread_list = NULL; +#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE +struct sljit_jump *jump; +#endif + +SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); + +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +/* Get type of the previous char, and put it to LOCALS1. */ +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); +skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); +skip_char_back(common); +check_start_used_ptr(common); +read_char(common); + +/* Testing char type. */ +#ifdef SUPPORT_UNICODE +if (common->use_ucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); + } +else +#endif + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); +#elif defined SUPPORT_UNICODE + /* Here LOCALS1 has already been zeroed. */ + jump = NULL; + if (common->utf) + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); +#if PCRE2_CODE_UNIT_WIDTH != 8 + JUMPHERE(jump); +#elif defined SUPPORT_UNICODE + if (jump != NULL) + JUMPHERE(jump); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + } +JUMPHERE(skipread); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); +check_str_end(common, &skipread_list); +peek_char(common, READ_CHAR_MAX); + +/* Testing char type. This is a code duplication. */ +#ifdef SUPPORT_UNICODE +if (common->use_ucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + JUMPHERE(jump); + } +else +#endif + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + /* TMP2 may be destroyed by peek_char. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); +#elif defined SUPPORT_UNICODE + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = NULL; + if (common->utf) + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +#if PCRE2_CODE_UNIT_WIDTH != 8 + JUMPHERE(jump); +#elif defined SUPPORT_UNICODE + if (jump != NULL) + JUMPHERE(jump); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + } +set_jumps(skipread_list, LABEL()); + +OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +} + +static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks) +{ +/* May destroy TMP1. */ +DEFINE_COMPILER; +int ranges[MAX_RANGE_SIZE]; +sljit_ub bit, cbit, all; +int i, byte, length = 0; + +bit = bits[0] & 0x1; +/* All bits will be zero or one (since bit is zero or one). */ +all = -bit; + +for (i = 0; i < 256; ) + { + byte = i >> 3; + if ((i & 0x7) == 0 && bits[byte] == all) + i += 8; + else + { + cbit = (bits[byte] >> (i & 0x7)) & 0x1; + if (cbit != bit) + { + if (length >= MAX_RANGE_SIZE) + return FALSE; + ranges[length] = i; + length++; + bit = cbit; + all = -cbit; + } + i++; + } + } + +if (((bit == 0) && nclass) || ((bit == 1) && !nclass)) + { + if (length >= MAX_RANGE_SIZE) + return FALSE; + ranges[length] = 256; + length++; + } + +if (length < 0 || length > 4) + return FALSE; + +bit = bits[0] & 0x1; +if (invert) bit ^= 0x1; + +/* No character is accepted. */ +if (length == 0 && bit == 0) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + +switch(length) + { + case 0: + /* When bit != 0, all characters are accepted. */ + return TRUE; + + case 1: + add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + + case 2: + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + } + else + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + + case 3: + if (bit != 0) + { + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + } + + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); + if (ranges[1] + 1 != ranges[2]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); + return TRUE; + + case 4: + if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) + && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] + && (ranges[1] & (ranges[2] - ranges[0])) == 0 + && is_powerof2(ranges[2] - ranges[0])) + { + SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); + if (ranges[2] + 1 != ranges[3]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); + } + else + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + return TRUE; + } + + if (bit != 0) + { + i = 0; + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + i = ranges[0]; + } + else + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + + if (ranges[2] + 1 != ranges[3]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); + return TRUE; + } + + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); + if (ranges[1] + 1 != ranges[2]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + return TRUE; + + default: + SLJIT_ASSERT_STOP(); + return FALSE; + } +} + +static void check_anynewline(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); +#if PCRE2_CODE_UNIT_WIDTH == 8 + } +#endif +#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_hspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); +#if PCRE2_CODE_UNIT_WIDTH == 8 + } +#endif +#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_vspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); +#if PCRE2_CODE_UNIT_WIDTH == 8 + } +#endif +#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define CHAR1 STR_END +#define CHAR2 STACK_TOP + +static void do_casefulcmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +label = LABEL(); +OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); +OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define LCC_TABLE STACK_LIMIT + +static void do_caselesscmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0); +OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +label = LABEL(); +OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); +OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH != 8 +jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); +#if PCRE2_CODE_UNIT_WIDTH != 8 +JUMPHERE(jump); +jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); +#if PCRE2_CODE_UNIT_WIDTH != 8 +JUMPHERE(jump); +#endif +jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#undef LCC_TABLE +#undef CHAR1 +#undef CHAR2 + +#if defined SUPPORT_UNICODE + +static PCRE2_SPTR SLJIT_CALL do_utf_caselesscmp(PCRE2_SPTR src1, jit_arguments *args, PCRE2_SPTR end1) +{ +/* This function would be ineffective to do in JIT level. */ +sljit_ui c1, c2; +PCRE2_SPTR src2 = args->startchar_ptr; +PCRE2_SPTR end2 = args->end; +const ucd_record *ur; +const sljit_ui *pp; + +while (src1 < end1) + { + if (src2 >= end2) + return (PCRE2_SPTR)1; + GETCHARINC(c1, src1); + GETCHARINC(c2, src2); + ur = GET_UCD(c2); + if (c1 != c2 && c1 != c2 + ur->other_case) + { + pp = PRIV(ucd_caseless_sets) + ur->caseset; + for (;;) + { + if (c1 < *pp) return NULL; + if (c1 == *pp++) break; + } + } + } +return src2; +} + +#endif /* SUPPORT_UNICODE */ + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); + +static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, + compare_context *context, jump_list **backtracks) +{ +DEFINE_COMPILER; +unsigned int othercasebit = 0; +PCRE2_SPTR othercasechar = NULL; +#ifdef SUPPORT_UNICODE +int utflength; +#endif + +if (caseless && char_has_othercase(common, cc)) + { + othercasebit = char_get_othercase_bit(common, cc); + SLJIT_ASSERT(othercasebit); + /* Extracting bit difference info. */ +#if PCRE2_CODE_UNIT_WIDTH == 8 + othercasechar = cc + (othercasebit >> 8); + othercasebit &= 0xff; +#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + /* Note that this code only handles characters in the BMP. If there + ever are characters outside the BMP whose othercase differs in only one + bit from itself (there currently are none), this code will need to be + revised for PCRE2_CODE_UNIT_WIDTH == 32. */ + othercasechar = cc + (othercasebit >> 9); + if ((othercasebit & 0x100) != 0) + othercasebit = (othercasebit & 0xff) << 8; + else + othercasebit &= 0xff; +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + } + +if (context->sourcereg == -1) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 32 + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + context->sourcereg = TMP2; + } + +#ifdef SUPPORT_UNICODE +utflength = 1; +if (common->utf && HAS_EXTRALEN(*cc)) + utflength += GET_EXTRALEN(*cc); + +do + { +#endif + + context->length -= IN_UCHARS(1); +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + + /* Unaligned read is supported. */ + if (othercasebit != 0 && othercasechar == cc) + { + context->c.asuchars[context->ucharptr] = *cc | othercasebit; + context->oc.asuchars[context->ucharptr] = othercasebit; + } + else + { + context->c.asuchars[context->ucharptr] = *cc; + context->oc.asuchars[context->ucharptr] = 0; + } + context->ucharptr++; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) +#else + if (context->ucharptr >= 2 || context->length == 0) +#endif + { + if (context->length >= 4) + OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#if PCRE2_CODE_UNIT_WIDTH == 8 + else if (context->length >= 1) + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + switch(context->ucharptr) + { + case 4 / sizeof(PCRE2_UCHAR): + if (context->oc.asint != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); + break; + + case 2 / sizeof(PCRE2_UCHAR): + if (context->oc.asushort != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); + break; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + case 1: + if (context->oc.asbyte != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); + break; +#endif + + default: + SLJIT_ASSERT_STOP(); + break; + } + context->ucharptr = 0; + } + +#else + + /* Unaligned read is unsupported or in 32 bit mode. */ + if (context->length >= 1) + OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + if (othercasebit != 0 && othercasechar == cc) + { + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); + +#endif + + cc++; +#ifdef SUPPORT_UNICODE + utflength--; + } +while (utflength > 0); +#endif + +return cc; +} + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + +#define SET_TYPE_OFFSET(value) \ + if ((value) != typeoffset) \ + { \ + if ((value) < typeoffset) \ + OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ + else \ + OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ + } \ + typeoffset = (value); + +#define SET_CHAR_OFFSET(value) \ + if ((value) != charoffset) \ + { \ + if ((value) < charoffset) \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ + else \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ + } \ + charoffset = (value); + +static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; +sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; +struct sljit_jump *jump = NULL; +PCRE2_SPTR ccbegin; +int compares, invertcmp, numberofcmps; +#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +BOOL utf = common->utf; +#endif + +#ifdef SUPPORT_UNICODE +BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; +BOOL charsaved = FALSE; +int typereg = TMP1; +const sljit_ui *other_cases; +sljit_uw typeoffset; +#endif + +/* Scanning the necessary info. */ +cc++; +ccbegin = cc; +compares = 0; + +if (cc[-1] & XCL_MAP) + { + min = 0; + cc += 32 / sizeof(PCRE2_UCHAR); + } + +while (*cc != XCL_END) + { + compares++; + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + if (c > max) max = c; + if (c < min) min = c; +#ifdef SUPPORT_UNICODE + needschar = TRUE; +#endif + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + if (c < min) min = c; + GETCHARINCTEST(c, cc); + if (c > max) max = c; +#ifdef SUPPORT_UNICODE + needschar = TRUE; +#endif + } +#ifdef SUPPORT_UNICODE + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_CLIST) + { + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + while (*other_cases != NOTACHAR) + { + if (*other_cases > max) max = *other_cases; + if (*other_cases < min) min = *other_cases; + other_cases++; + } + } + else + { + max = READ_CHAR_MAX; + min = 0; + } + + switch(*cc) + { + case PT_ANY: + /* Any either accepts everything or ignored. */ + if (cc[-1] == XCL_PROP) + { + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } + break; + + case PT_LAMP: + case PT_GC: + case PT_PC: + case PT_ALNUM: + needstype = TRUE; + break; + + case PT_SC: + needsscript = TRUE; + break; + + case PT_SPACE: + case PT_PXSPACE: + case PT_WORD: + case PT_PXGRAPH: + case PT_PXPRINT: + case PT_PXPUNCT: + needstype = TRUE; + needschar = TRUE; + break; + + case PT_CLIST: + case PT_UCNC: + needschar = TRUE; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += 2; + } +#endif + } +SLJIT_ASSERT(compares > 0); + +/* We are not necessary in utf mode even in 8 bit mode. */ +cc = ccbegin; +read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); + +if ((cc[-1] & XCL_HASPROP) == 0) + { + if ((cc[-1] & XCL_MAP) != 0) + { + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (!check_class_ranges(common, (const sljit_ub *)cc, (((const sljit_ub *)cc)[31] & 0x80) != 0, TRUE, &found)) + { + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); + } + + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump); + + cc += 32 / sizeof(PCRE2_UCHAR); + } + else + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); + add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min)); + } + } +else if ((cc[-1] & XCL_MAP) != 0) + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); +#ifdef SUPPORT_UNICODE + charsaved = TRUE; +#endif + if (!check_class_ranges(common, (const sljit_ub *)cc, FALSE, TRUE, list)) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump = NULL; + if (common->utf) +#endif + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf) +#endif + JUMPHERE(jump); + } + + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + cc += 32 / sizeof(PCRE2_UCHAR); + } + +#ifdef SUPPORT_UNICODE +if (needstype || needsscript) + { + if (needschar && !charsaved) + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + + OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); + OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); + + /* Before anything else, we deal with scripts. */ + if (needsscript) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + ccbegin = cc; + + while (*cc != XCL_END) + { + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_SC) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + cc += 2; + } + } + + cc = ccbegin; + } + + if (needschar) + { + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + } + + if (needstype) + { + if (!needschar) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + } + else + { + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + typereg = RETURN_ADDR; + } + } + } +#endif + +/* Generating code. */ +charoffset = 0; +numberofcmps = 0; +#ifdef SUPPORT_UNICODE +typeoffset = 0; +#endif + +while (*cc != XCL_END) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + jump = NULL; + + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + numberofcmps = 0; + } + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + SET_CHAR_OFFSET(c); + GETCHARINCTEST(c, cc); + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + numberofcmps = 0; + } + } +#ifdef SUPPORT_UNICODE + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + if (*cc == XCL_NOTPROP) + invertcmp ^= 0x1; + cc++; + switch(*cc) + { + case PT_ANY: + if (!invertcmp) + jump = JUMP(SLJIT_JUMP); + break; + + case PT_LAMP: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_GC: + c = PRIV(ucp_typerange)[(int)cc[1] * 2]; + SET_TYPE_OFFSET(c); + jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); + break; + + case PT_PC: + jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); + break; + + case PT_SC: + compares++; + /* Do nothing. */ + break; + + case PT_SPACE: + case PT_PXSPACE: + SET_CHAR_OFFSET(9); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + SET_TYPE_OFFSET(ucp_Zl); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_WORD: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + /* Fall through. */ + + case PT_ALNUM: + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); + SET_TYPE_OFFSET(ucp_Nd); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_CLIST: + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + + /* At least three characters are required. + Otherwise this case would be handled by the normal code path. */ + SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); + SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); + + /* Optimizing character pairs, if their difference is power of 2. */ + if (is_powerof2(other_cases[1] ^ other_cases[0])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + other_cases += 2; + } + else if (is_powerof2(other_cases[2] ^ other_cases[1])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); + OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + other_cases += 3; + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + } + + while (*other_cases != NOTACHAR) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); + OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); + } + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_UCNC: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + SET_CHAR_OFFSET(0xa0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + SET_CHAR_OFFSET(0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXGRAPH: + /* C and Z groups are the farthest two groups. */ + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); + + jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPRINT: + /* C and Z groups are the farthest two groups. */ + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); + OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); + + jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPUNCT: + SET_TYPE_OFFSET(ucp_Sc); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f); + OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_TYPE_OFFSET(ucp_Pc); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += 2; + } +#endif + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + +if (found != NULL) + set_jumps(found, LABEL()); +} + +#undef SET_TYPE_OFFSET +#undef SET_CHAR_OFFSET + +#endif + +static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +int length; +struct sljit_jump *jump[4]; +#ifdef SUPPORT_UNICODE +struct sljit_label *label; +#endif /* SUPPORT_UNICODE */ + +switch(type) + { + case OP_SOD: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_SOM: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + + case OP_EODN: + /* Requires rather complex checks. */ + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } + else + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_GREATER); + add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); + /* Equal. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + check_partial(common, FALSE); + return cc; + + case OP_EOD: + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + return cc; + + case OP_CIRC: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + return cc; + + case OP_CIRCM: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); + OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (!common->alt_circumflex) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + skip_char_back(common); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_DOLL: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + + if (!common->endonly) + compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + } + return cc; + + case OP_DOLLM: + jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + check_partial(common, FALSE); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + /* STR_PTR = STR_END - IN_UCHARS(1) */ + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char(common, common->nlmax); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_REVERSE: + length = GET(cc, 0); + if (length == 0) + return cc + LINK_SIZE; + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +#ifdef SUPPORT_UNICODE + if (common->utf) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); + label = LABEL(); + add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); + skip_char_back(common); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else +#endif + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); + } + check_start_used_ptr(common); + return cc + LINK_SIZE; + } +SLJIT_ASSERT_STOP(); +return cc; +} + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) +{ +DEFINE_COMPILER; +int length; +unsigned int c, oc, bit; +compare_context context; +struct sljit_jump *jump[3]; +jump_list *end_list; +#ifdef SUPPORT_UNICODE +struct sljit_label *label; +PCRE2_UCHAR propdata[5]; +#endif /* SUPPORT_UNICODE */ + +switch(type) + { + case OP_NOT_DIGIT: + case OP_DIGIT: + /* Digits are usually 0-9, so it is worth to optimize them. */ + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_digit, FALSE)) + read_char7_type(common, type == OP_NOT_DIGIT); + else +#endif + read_char8_type(common, type == OP_NOT_DIGIT); + /* Flip the starting bit in the negative case. */ + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_space, FALSE)) + read_char7_type(common, type == OP_NOT_WHITESPACE); + else +#endif + read_char8_type(common, type == OP_NOT_WHITESPACE); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); + add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_word, FALSE)) + read_char7_type(common, type == OP_NOT_WORDCHAR); + else +#endif + read_char8_type(common, type == OP_NOT_WORDCHAR); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); + add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_ANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[0]); + } + else + check_newlinechar(common, common->nltype, backtracks, TRUE); + return cc; + + case OP_ALLANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#endif + JUMPHERE(jump[0]); +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ + return cc; + } +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + + case OP_ANYBYTE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + +#ifdef SUPPORT_UNICODE + case OP_NOTPROP: + case OP_PROP: + propdata[0] = XCL_HASPROP; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, propdata, backtracks); + return cc + 2; +#endif + + case OP_ANYNL: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + /* We don't need to handle soft partial matching case. */ + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[2] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[1]); + JUMPHERE(jump[2]); + return cc; + + case OP_NOT_HSPACE: + case OP_HSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + + case OP_NOT_VSPACE: + case OP_VSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + +#ifdef SUPPORT_UNICODE + case OP_EXTUNI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + /* Optimize register allocation: use a real register. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + label = LABEL(); + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); + OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); + OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + JUMPTO(SLJIT_NOT_ZERO, label); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(jump[0]); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + + if (common->mode == PCRE2_JIT_PARTIAL_HARD) + { + jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + /* Since we successfully read a char above, partial matching must occure. */ + check_partial(common, TRUE); + JUMPHERE(jump[0]); + } + return cc; +#endif + + case OP_CHAR: + case OP_CHARI: + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); +#endif + if (common->mode == PCRE2_JIT_COMPLETE && check_str_ptr + && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.length = IN_UCHARS(length); + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); + } + + if (check_str_ptr) + detect_partial_match(common, backtracks); +#ifdef SUPPORT_UNICODE + if (common->utf) + { + GETCHAR(c, cc); + } + else +#endif + c = *cc; + + if (type == OP_CHAR || !char_has_othercase(common, cc)) + { + read_char_range(common, c, c, FALSE); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + return cc + length; + } + oc = char_othercase(common, c); + read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE); + bit = c ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + return cc + length; + } + jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + JUMPHERE(jump[0]); + return cc + length; + + case OP_NOT: + case OP_NOTI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + c = *cc; + if (c < 128) + { + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); + } + /* Skip the variable-length character. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc + 1; + } + else +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + { + GETCHARLEN(c, cc, length); + } + } + else +#endif /* SUPPORT_UNICODE */ + c = *cc; + + if (type == OP_NOT || !char_has_othercase(common, cc)) + { + read_char_range(common, c, c, TRUE); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + } + else + { + oc = char_othercase(common, c); + read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE); + bit = c ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + } + else + { + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + } + } + return cc + length; + + case OP_CLASS: + case OP_NCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + bit = (common->utf && is_char7_bitset((const sljit_ub *)cc, type == OP_NCLASS)) ? 127 : 255; + read_char_range(common, 0, bit, type == OP_NCLASS); +#else + read_char_range(common, 0, 255, type == OP_NCLASS); +#endif + + if (check_class_ranges(common, (const sljit_ub *)cc, type == OP_NCLASS, FALSE, backtracks)) + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + jump[0] = NULL; + if (common->utf) + { + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } + } +#elif PCRE2_CODE_UNIT_WIDTH != 8 + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + if (jump[0] != NULL) + JUMPHERE(jump[0]); +#endif + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + case OP_XCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); + return cc + GET(cc, 0) - 1; +#endif + } +SLJIT_ASSERT_STOP(); +return cc; +} + +static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) +{ +/* This function consumes at least one input character. */ +/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ +DEFINE_COMPILER; +PCRE2_SPTR ccbegin = cc; +compare_context context; +int size; + +context.length = 0; +do + { + if (cc >= ccend) + break; + + if (*cc == OP_CHAR) + { + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); +#endif + } + else if (*cc == OP_CHARI) + { + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) + { + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + else if (HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); + } + else +#endif + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + } + else + size = 0; + + cc += 1 + size; + context.length += IN_UCHARS(size); + } +while (size > 0 && context.length <= 128); + +cc = ccbegin; +if (context.length > 0) + { + /* We have a fixed-length byte sequence. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); + return cc; + } + +/* A non-fixed length character will be checked if length == 0. */ +return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); +} + +/* Forward definitions. */ +static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *); +static void compile_backtrackingpath(compiler_common *, struct backtrack_common *); + +#define PUSH_BACKTRACK(size, ccstart, error) \ + do \ + { \ + backtrack = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return error; \ + memset(backtrack, 0, size); \ + backtrack->prev = parent->top; \ + backtrack->cc = (ccstart); \ + parent->top = backtrack; \ + } \ + while (0) + +#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ + do \ + { \ + backtrack = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + memset(backtrack, 0, size); \ + backtrack->prev = parent->top; \ + backtrack->cc = (ccstart); \ + parent->top = backtrack; \ + } \ + while (0) + +#define BACKTRACK_AS(type) ((type *)backtrack) + +static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) +{ +/* The OVECTOR offset goes to TMP2. */ +DEFINE_COMPILER; +int count = GET2(cc, 1 + IMM2_SIZE); +PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size; +unsigned int offset; +jump_list *found = NULL; + +SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); + +count--; +while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); + add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); + slot += common->name_entry_size; + } + +offset = GET2(slot, 0) << 1; +GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); +if (backtracks != NULL && !common->unset_backref) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); + +set_jumps(found, LABEL()); +} + +static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) +{ +DEFINE_COMPILER; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); +int offset = 0; +struct sljit_jump *jump = NULL; +struct sljit_jump *partial; +struct sljit_jump *nopartial; + +if (ref) + { + offset = GET2(cc, 1) << 1; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + /* OVECTOR(1) contains the "string begin - 1" constant. */ + if (withchecks && !common->unset_backref) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + } +else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + +#if defined SUPPORT_UNICODE +if (common->utf && *cc == OP_REFI) + { + SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2); + if (ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + + if (withchecks) + jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0); + + /* Needed to save important temporary registers. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), STR_PTR, 0); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); + nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); + check_partial(common, FALSE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(nopartial); + } + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + } +else +#endif /* SUPPORT_UNICODE */ + { + if (ref) + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); + else + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); + + if (withchecks) + jump = JUMP(SLJIT_ZERO); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, partial); + + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + + if (common->mode != PCRE2_JIT_COMPLETE) + { + nopartial = JUMP(SLJIT_JUMP); + JUMPHERE(partial); + /* TMP2 -= STR_END - STR_PTR */ + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); + partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + JUMPHERE(partial); + check_partial(common, FALSE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(nopartial); + } + } + +if (jump != NULL) + { + if (emptyfail) + add_jump(compiler, backtracks, jump); + else + JUMPHERE(jump); + } +} + +static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); +backtrack_common *backtrack; +PCRE2_UCHAR type; +int offset = 0; +struct sljit_label *label; +struct sljit_jump *zerolength; +struct sljit_jump *jump = NULL; +PCRE2_SPTR ccbegin = cc; +int min = 0, max = 0; +BOOL minimize; + +PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL); + +if (ref) + offset = GET2(cc, 1) << 1; +else + cc += IMM2_SIZE; +type = cc[1 + IMM2_SIZE]; + +SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); +minimize = (type & 0x1) != 0; +switch(type) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + min = 0; + max = 0; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + max = 0; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRQUERY: + case OP_CRMINQUERY: + min = 0; + max = 1; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(cc, 1 + IMM2_SIZE + 1); + max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); + cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; + break; + default: + SLJIT_ASSERT_STOP(); + break; + } + +if (!minimize) + { + if (min == 0) + { + allocate_stack(common, 2); + if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + /* Temporary release of STR_PTR. */ + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + /* Handles both invalid and empty cases. Since the minimum repeat, + is zero the invalid case is basically the same as an empty case. */ + if (ref) + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + else + { + compile_dnref_search(common, ccbegin, NULL); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + /* Restore if not zero length. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + } + else + { + allocate_stack(common, 1); + if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + if (ref) + { + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + } + else + { + compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + } + + if (min > 1 || max > 1) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); + + label = LABEL(); + if (!ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); + compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); + + if (min > 1 || max > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); + if (min > 1) + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); + if (max > 1) + { + jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + JUMPHERE(jump); + } + } + + if (max == 0) + { + /* Includes min > 1 case as well. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + } + + JUMPHERE(zerolength); + BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); + + count_match(common); + return cc; + } + +allocate_stack(common, ref ? 2 : 3); +if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); +if (type != OP_CRMINSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + +if (min == 0) + { + /* Handles both invalid and empty cases. Since the minimum repeat, + is zero the invalid case is basically the same as an empty case. */ + if (ref) + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + else + { + compile_dnref_search(common, ccbegin, NULL); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + /* Length is non-zero, we can match real repeats. */ + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + jump = JUMP(SLJIT_JUMP); + } +else + { + if (ref) + { + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + } + else + { + compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); + zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + } + +BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); +if (max > 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); + +if (!ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); +compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +if (min > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath); + } +else if (max > 0) + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + +if (jump != NULL) + JUMPHERE(jump); +JUMPHERE(zerolength); + +count_match(common); +return cc; +} + +static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +recurse_entry *entry = common->entries; +recurse_entry *prev = NULL; +sljit_sw start = GET(cc, 1); +PCRE2_SPTR start_cc; +BOOL needs_control_head; + +PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); + +/* Inlining simple patterns. */ +if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) + { + start_cc = common->start + start; + compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); + BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE; + return cc + 1 + LINK_SIZE; + } + +while (entry != NULL) + { + if (entry->start == start) + break; + prev = entry; + entry = entry->next; + } + +if (entry == NULL) + { + entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + entry->next = NULL; + entry->entry = NULL; + entry->calls = NULL; + entry->start = start; + + if (prev != NULL) + prev->next = entry; + else + common->entries = entry; + } + +if (common->has_set_som && common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); + allocate_stack(common, 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + } +else if (common->has_set_som || common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + +if (entry->entry == NULL) + add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); +else + JUMPTO(SLJIT_FAST_CALL, entry->entry); +/* Leave if the match is failed. */ +add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); +return cc + 1 + LINK_SIZE; +} + +static int SLJIT_CALL do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) +{ +PCRE2_SPTR begin = arguments->begin; +PCRE2_SIZE *ovector = arguments->match_data->ovector; +uint32_t oveccount = arguments->oveccount; +uint32_t i; + +if (arguments->callout == NULL) + return 0; + +callout_block->version = 1; + +/* Offsets in subject. */ +callout_block->subject_length = arguments->end - arguments->begin; +callout_block->start_match = (PCRE2_SPTR)callout_block->subject - arguments->begin; +callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - arguments->begin; +callout_block->subject = begin; + +/* Convert and copy the JIT offset vector to the ovector array. */ +callout_block->capture_top = 0; +callout_block->offset_vector = ovector; +for (i = 2; i < oveccount; i += 2) + { + ovector[i] = jit_ovector[i] - begin; + ovector[i + 1] = jit_ovector[i + 1] - begin; + if (jit_ovector[i] >= begin) + callout_block->capture_top = i; + } + +callout_block->capture_top = (callout_block->capture_top >> 1) + 1; +ovector[0] = PCRE2_UNSET; +ovector[1] = PCRE2_UNSET; +return (arguments->callout)(callout_block, arguments->callout_data); +} + +/* Aligning to 8 byte. */ +#define CALLOUT_ARG_SIZE \ + (((int)sizeof(pcre2_callout_block) + 7) & ~7) + +#define CALLOUT_ARG_OFFSET(arg) \ + (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(pcre2_callout_block, arg)) + +static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +sljit_si mov_opcode; +unsigned int callout_length = (*cc == OP_CALLOUT) + ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE); +sljit_sw value1; +sljit_sw value2; +sljit_sw value3; + +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); + +allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); + +SLJIT_ASSERT(common->capture_last_ptr != 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0; +OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1); +OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); + +/* These pointer sized fields temporarly stores internal variables. */ +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); + +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); +mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; +OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1)); +OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE)); + +if (*cc == OP_CALLOUT) + { + value1 = 0; + value2 = 0; + value3 = 0; + } +else + { + value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1); + value2 = (callout_length - (1 + 4*LINK_SIZE + 2)); + value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE)); + } + +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1); +OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2); +OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0); + +/* Needed to save important temporary registers. */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); +OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); +GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); +sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); +OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); + +/* Check return value. */ +OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER)); +if (common->forced_quit_label == NULL) + add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS)); +else + JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label); +return cc + callout_length; +} + +#undef CALLOUT_ARG_SIZE +#undef CALLOUT_ARG_OFFSET + +static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc) +{ +while (TRUE) + { + switch (*cc) + { + case OP_CALLOUT_STR: + cc += GET(cc, 1 + 2*LINK_SIZE); + break; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_CALLOUT: + case OP_ALT: + cc += PRIV(OP_lengths)[*cc]; + break; + + case OP_KET: + return FALSE; + + default: + return TRUE; + } + } +} + +static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional) +{ +DEFINE_COMPILER; +int framesize; +int extrasize; +BOOL needs_control_head; +int private_data_ptr; +backtrack_common altbacktrack; +PCRE2_SPTR ccbegin; +PCRE2_UCHAR opcode; +PCRE2_UCHAR bra = OP_BRA; +jump_list *tmp = NULL; +jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; +jump_list **found; +/* Saving previous accept variables. */ +BOOL save_local_exit = common->local_exit; +BOOL save_positive_assert = common->positive_assert; +then_trap_backtrack *save_then_trap = common->then_trap; +struct sljit_label *save_quit_label = common->quit_label; +struct sljit_label *save_accept_label = common->accept_label; +jump_list *save_quit = common->quit; +jump_list *save_positive_assert_quit = common->positive_assert_quit; +jump_list *save_accept = common->accept; +struct sljit_jump *jump; +struct sljit_jump *brajump = NULL; + +/* Assert captures then. */ +common->then_trap = NULL; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + SLJIT_ASSERT(!conditional); + bra = *cc; + cc++; + } +private_data_ptr = PRIVATE_DATA(cc); +SLJIT_ASSERT(private_data_ptr != 0); +framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); +backtrack->framesize = framesize; +backtrack->private_data_ptr = private_data_ptr; +opcode = *cc; +SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); +found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; +ccbegin = cc; +cc += GET(cc, 1); + +if (bra == OP_BRAMINZERO) + { + /* This is a braminzero backtrack path. */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (framesize < 0) + { + extrasize = 1; + if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) + extrasize = 0; + + if (needs_control_head) + extrasize++; + + if (framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); + + if (extrasize > 0) + allocate_stack(common, extrasize); + + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + + if (extrasize > 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + + if (needs_control_head) + { + SLJIT_ASSERT(extrasize == 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + } + } +else + { + extrasize = needs_control_head ? 3 : 2; + allocate_stack(common, framesize + extrasize); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + + if (needs_control_head) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + + init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); + } + +memset(&altbacktrack, 0, sizeof(backtrack_common)); +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + /* Negative assert is stronger than positive assert. */ + common->local_exit = TRUE; + common->quit_label = NULL; + common->quit = NULL; + common->positive_assert = FALSE; + } +else + common->positive_assert = TRUE; +common->positive_assert_quit = NULL; + +while (1) + { + common->accept_label = NULL; + common->accept = NULL; + altbacktrack.top = NULL; + altbacktrack.topbacktracks = NULL; + + if (*ccbegin == OP_ALT && extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + altbacktrack.cc = ccbegin; + compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } + common->positive_assert = save_positive_assert; + common->then_trap = save_then_trap; + common->accept_label = save_accept_label; + common->positive_assert_quit = save_positive_assert_quit; + common->accept = save_accept; + return NULL; + } + common->accept_label = LABEL(); + if (common->accept != NULL) + set_jumps(common->accept, common->accept_label); + + /* Reset stack. */ + if (framesize < 0) + { + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + else if (extrasize > 0) + free_stack(common, extrasize); + + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); + } + else + { + if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) + { + /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); + } + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + } + + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + /* We know that STR_PTR was stored on the top of the stack. */ + if (conditional) + { + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); + } + else if (bra == OP_BRAZERO) + { + if (framesize < 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + } + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else if (framesize >= 0) + { + /* For OP_BRA and OP_BRAMINZERO. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + } + } + add_jump(compiler, found, JUMP(SLJIT_JUMP)); + + compile_backtrackingpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } + common->positive_assert = save_positive_assert; + common->then_trap = save_then_trap; + common->accept_label = save_accept_label; + common->positive_assert_quit = save_positive_assert_quit; + common->accept = save_accept; + return NULL; + } + set_jumps(altbacktrack.topbacktracks, LABEL()); + + if (*cc != OP_ALT) + break; + + ccbegin = cc; + cc += GET(cc, 1); + } + +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + SLJIT_ASSERT(common->positive_assert_quit == NULL); + /* Makes the check less complicated below. */ + common->positive_assert_quit = common->quit; + } + +/* None of them matched. */ +if (common->positive_assert_quit != NULL) + { + jump = JUMP(SLJIT_JUMP); + set_jumps(common->positive_assert_quit, LABEL()); + SLJIT_ASSERT(framesize != no_stack); + if (framesize < 0) + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); + } + JUMPHERE(jump); + } + +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); + +if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) + { + /* Assert is failed. */ + if ((conditional && extrasize > 0) || bra == OP_BRAZERO) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + if (framesize < 0) + { + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + { + if (extrasize == 2) + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else if (extrasize > 0) + free_stack(common, extrasize); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + { + free_stack(common, framesize + extrasize - 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + extrasize); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + } + jump = JUMP(SLJIT_JUMP); + if (bra != OP_BRAZERO) + add_jump(compiler, target, jump); + + /* Assert is successful. */ + set_jumps(tmp, LABEL()); + if (framesize < 0) + { + /* We know that STR_PTR was stored on the top of the stack. */ + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); + + /* Keep the STR_PTR on the top of the stack. */ + if (bra == OP_BRAZERO) + { + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + if (extrasize == 2) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else if (bra == OP_BRAMINZERO) + { + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + else + { + if (bra == OP_BRA) + { + /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw)); + } + else + { + /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); + if (extrasize == 2) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra == OP_BRAMINZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); + } + } + } + + if (bra == OP_BRAZERO) + { + backtrack->matchingpath = LABEL(); + SET_LABEL(jump, backtrack->matchingpath); + } + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPHERE(brajump); + if (framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + } + set_jumps(backtrack->common.topbacktracks, LABEL()); + } + } +else + { + /* AssertNot is successful. */ + if (framesize < 0) + { + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + if (bra != OP_BRA) + { + if (extrasize == 2) + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else if (extrasize > 0) + free_stack(common, extrasize); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); + /* The topmost item should be 0. */ + if (bra != OP_BRA) + { + free_stack(common, framesize + extrasize - 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + extrasize); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + } + + if (bra == OP_BRAZERO) + backtrack->matchingpath = LABEL(); + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPHERE(brajump); + } + + if (bra != OP_BRA) + { + SLJIT_ASSERT(found == &backtrack->common.topbacktracks); + set_jumps(backtrack->common.topbacktracks, LABEL()); + backtrack->common.topbacktracks = NULL; + } + } + +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } +common->positive_assert = save_positive_assert; +common->then_trap = save_then_trap; +common->accept_label = save_accept_label; +common->positive_assert_quit = save_positive_assert_quit; +common->accept = save_accept; +return cc + 1 + LINK_SIZE; +} + +static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head) +{ +DEFINE_COMPILER; +int stacksize; + +if (framesize < 0) + { + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + else + { + stacksize = needs_control_head ? 1 : 0; + if (ket != OP_KET || has_alternatives) + stacksize++; + + if (stacksize > 0) + free_stack(common, stacksize); + } + + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0); + + /* TMP2 which is set here used by OP_KETRMAX below. */ + if (ket == OP_KETRMAX) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (ket == OP_KETRMIN) + { + /* Move the STR_PTR to the private_data_ptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); + } + } +else + { + stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1; + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw)); + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0); + + if (ket == OP_KETRMAX) + { + /* TMP2 which is set here used by OP_KETRMAX below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + } +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); +} + +static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr) +{ +DEFINE_COMPILER; + +if (common->capture_last_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); + stacksize++; + } +if (common->optimized_cbracket[offset >> 1] == 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + stacksize += 2; + } +return stacksize; +} + +/* + Handling bracketed expressions is probably the most complex part. + + Stack layout naming characters: + S - Push the current STR_PTR + 0 - Push a 0 (NULL) + A - Push the current STR_PTR. Needed for restoring the STR_PTR + before the next alternative. Not pushed if there are no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. + L - Push the previous local (pointed by localptr) to the stack + () - opional values stored on the stack + ()* - optonal, can be stored multiple times + + The following list shows the regular expression templates, their PCRE byte codes + and stack layout supported by pcre-sljit. + + (?:) OP_BRA | OP_KET A M + () OP_CBRA | OP_KET C M + (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* + OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* + (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* + OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* + ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* + ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* + (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) + (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) + ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) + ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) + (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* + OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* + (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* + OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* + ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* + OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* + ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* + OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* + + + Stack layout naming characters: + A - Push the alternative index (starting from 0) on the stack. + Not pushed if there is no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + + The next list shows the possible content of a bracket: + (|) OP_*BRA | OP_ALT ... M A + (?()|) OP_*COND | OP_ALT M A + (?>|) OP_ONCE | OP_ALT ... [stack trace] M A + (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A + Or nothing, if trace is unnecessary +*/ + +static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +PCRE2_UCHAR opcode; +int private_data_ptr = 0; +int offset = 0; +int i, stacksize; +int repeat_ptr = 0, repeat_length = 0; +int repeat_type = 0, repeat_count = 0; +PCRE2_SPTR ccbegin; +PCRE2_SPTR matchingpath; +PCRE2_SPTR slot; +PCRE2_UCHAR bra = OP_BRA; +PCRE2_UCHAR ket; +assert_backtrack *assert; +BOOL has_alternatives; +BOOL needs_control_head = FALSE; +struct sljit_jump *jump; +struct sljit_jump *skip; +struct sljit_label *rmax_label = NULL; +struct sljit_jump *braminzero = NULL; + +PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + opcode = *cc; + } + +opcode = *cc; +ccbegin = cc; +matchingpath = bracketend(cc) - 1 - LINK_SIZE; +ket = *matchingpath; +if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0) + { + repeat_ptr = PRIVATE_DATA(matchingpath); + repeat_length = PRIVATE_DATA(matchingpath + 1); + repeat_type = PRIVATE_DATA(matchingpath + 2); + repeat_count = PRIVATE_DATA(matchingpath + 3); + SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0); + if (repeat_type == OP_UPTO) + ket = OP_KETRMAX; + if (repeat_type == OP_MINUPTO) + ket = OP_KETRMIN; + } + +matchingpath = ccbegin + 1 + LINK_SIZE; +SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); +SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); +cc += GET(cc, 1); + +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) + { + SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3, + compile_time_checks_must_be_grouped_together); + has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE; + } + +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Capturing brackets has a pre-allocated space. */ + offset = GET2(ccbegin, 1 + LINK_SIZE); + if (common->optimized_cbracket[offset] == 0) + { + private_data_ptr = OVECTOR_PRIV(offset); + offset <<= 1; + } + else + { + offset <<= 1; + private_data_ptr = OVECTOR(offset); + } + BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; + matchingpath += IMM2_SIZE; + } +else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Other brackets simply allocate the next entry. */ + private_data_ptr = PRIVATE_DATA(ccbegin); + SLJIT_ASSERT(private_data_ptr != 0); + BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; + if (opcode == OP_ONCE) + BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); + } + +/* Instructions before the first alternative. */ +stacksize = 0; +if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + stacksize++; +if (bra == OP_BRAZERO) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (bra == OP_BRAZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + +if (bra == OP_BRAMINZERO) + { + /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (ket != OP_KETRMIN) + { + free_stack(common, 1); + braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + else + { + if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* Nothing stored during the first run. */ + skip = JUMP(SLJIT_JUMP); + JUMPHERE(jump); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) + { + /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ + braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + } + else + { + /* Except when the whole stack frame must be saved. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); + } + JUMPHERE(skip); + } + else + { + jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPHERE(jump); + } + } + } + +if (repeat_type != 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count); + if (repeat_type == OP_EXACT) + rmax_label = LABEL(); + } + +if (ket == OP_KETRMIN) + BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); + +if (ket == OP_KETRMAX) + { + rmax_label = LABEL(); + if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; + } + +/* Handling capturing brackets and alternatives. */ +if (opcode == OP_ONCE) + { + stacksize = 0; + if (needs_control_head) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + stacksize++; + } + + if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) + { + /* Neither capturing brackets nor recursions are found in the block. */ + if (ket == OP_KETRMIN) + { + stacksize += 2; + if (!needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + } + else + { + if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); + if (ket == OP_KETRMAX || has_alternatives) + stacksize++; + } + + if (stacksize > 0) + allocate_stack(common, stacksize); + + stacksize = 0; + if (needs_control_head) + { + stacksize++; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + + if (ket == OP_KETRMIN) + { + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); + } + else if (ket == OP_KETRMAX || has_alternatives) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + } + else + { + if (ket != OP_KET || has_alternatives) + stacksize++; + + stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1; + allocate_stack(common, stacksize); + + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + + stacksize = needs_control_head ? 1 : 0; + if (ket != OP_KET || has_alternatives) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); + stacksize++; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); + } + else + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); + } + init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); + } + } +else if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Saving the previous values. */ + if (common->optimized_cbracket[offset >> 1] != 0) + { + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); + allocate_stack(common, 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Saving the previous value. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } +else if (has_alternatives) + { + /* Pushing the starting string pointer. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + +/* Generating code for the first alternative. */ +if (opcode == OP_COND || opcode == OP_SCOND) + { + if (*matchingpath == OP_CREF) + { + SLJIT_ASSERT(has_alternatives); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), + CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + matchingpath += 1 + IMM2_SIZE; + } + else if (*matchingpath == OP_DNCREF) + { + SLJIT_ASSERT(has_alternatives); + + i = GET2(matchingpath, 1 + IMM2_SIZE); + slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); + slot += common->name_entry_size; + i--; + while (i-- > 0) + { + OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); + OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0); + slot += common->name_entry_size; + } + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); + matchingpath += 1 + 2 * IMM2_SIZE; + } + else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) + { + /* Never has other case. */ + BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; + SLJIT_ASSERT(!has_alternatives); + + if (*matchingpath == OP_TRUE) + { + stacksize = 1; + matchingpath++; + } + else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL) + stacksize = 0; + else if (*matchingpath == OP_RREF) + { + stacksize = GET2(matchingpath, 1); + if (common->currententry == NULL) + stacksize = 0; + else if (stacksize == RREF_ANY) + stacksize = 1; + else if (common->currententry->start == 0) + stacksize = stacksize == 0; + else + stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + + if (stacksize != 0) + matchingpath += 1 + IMM2_SIZE; + } + else + { + if (common->currententry == NULL || common->currententry->start == 0) + stacksize = 0; + else + { + stacksize = GET2(matchingpath, 1 + IMM2_SIZE); + slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; + i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + while (stacksize > 0) + { + if ((int)GET2(slot, 0) == i) + break; + slot += common->name_entry_size; + stacksize--; + } + } + + if (stacksize != 0) + matchingpath += 1 + 2 * IMM2_SIZE; + } + + /* The stacksize == 0 is a common "else" case. */ + if (stacksize == 0) + { + if (*cc == OP_ALT) + { + matchingpath = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } + else + matchingpath = cc; + } + } + else + { + SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT); + /* Similar code as PUSH_BACKTRACK macro. */ + assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + memset(assert, 0, sizeof(assert_backtrack)); + assert->common.cc = matchingpath; + BACKTRACK_AS(bracket_backtrack)->u.assert = assert; + matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE); + } + } + +compile_matchingpath(common, matchingpath, cc, backtrack); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + +if (opcode == OP_ONCE) + match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); + +stacksize = 0; +if (repeat_type == OP_MINUPTO) + { + /* We need to preserve the counter. TMP2 will be used below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); + stacksize++; + } +if (ket != OP_KET || bra != OP_BRA) + stacksize++; +if (offset != 0) + { + if (common->capture_last_ptr != 0) + stacksize++; + if (common->optimized_cbracket[offset >> 1] == 0) + stacksize += 2; + } +if (has_alternatives && opcode != OP_ONCE) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if (repeat_type == OP_MINUPTO) + { + /* TMP2 was set above. */ + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); + stacksize++; + } + +if (ket != OP_KET || bra != OP_BRA) + { + if (ket != OP_KET) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (offset != 0) + stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); + +if (has_alternatives) + { + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + if (ket != OP_KETRMAX) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + } + +/* Must be after the matchingpath label. */ +if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) + { + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); + } + +if (ket == OP_KETRMAX) + { + if (repeat_type != 0) + { + if (has_alternatives) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, rmax_label); + /* Drop STR_PTR for greedy plus quantifier. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + if (has_alternatives) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE) + { + CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); + /* Drop STR_PTR for greedy plus quantifier. */ + if (bra != OP_BRAZERO) + free_stack(common, 1); + } + else + /* TMP2 must contain the starting STR_PTR. */ + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); + } + else + JUMPTO(SLJIT_JUMP, rmax_label); + BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); + } + +if (repeat_type == OP_EXACT) + { + count_match(common); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, rmax_label); + } +else if (repeat_type == OP_UPTO) + { + /* We need to preserve the counter. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + +if (bra == OP_BRAZERO) + BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); + +if (bra == OP_BRAMINZERO) + { + /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ + JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); + if (braminzero != NULL) + { + JUMPHERE(braminzero); + /* We need to release the end pointer to perform the + backtrack for the zero-length iteration. When + framesize is < 0, OP_ONCE will do the release itself. */ + if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + else if (ket == OP_KETRMIN && opcode != OP_ONCE) + free_stack(common, 1); + } + /* Continue to the normal backtrack. */ + } + +if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) + count_match(common); + +/* Skip the other alternatives. */ +while (*cc == OP_ALT) + cc += GET(cc, 1); +cc += 1 + LINK_SIZE; + +if (opcode == OP_ONCE) + { + /* We temporarily encode the needs_control_head in the lowest bit. + Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns + the same value for small signed numbers (including negative numbers). */ + BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); + } +return cc + repeat_length; +} + +static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +PCRE2_UCHAR opcode; +int private_data_ptr; +int cbraprivptr = 0; +BOOL needs_control_head; +int framesize; +int stacksize; +int offset = 0; +BOOL zero = FALSE; +PCRE2_SPTR ccbegin = NULL; +int stack; /* Also contains the offset of control head. */ +struct sljit_label *loop = NULL; +struct jump_list *emptymatch = NULL; + +PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); +if (*cc == OP_BRAPOSZERO) + { + zero = TRUE; + cc++; + } + +opcode = *cc; +private_data_ptr = PRIVATE_DATA(cc); +SLJIT_ASSERT(private_data_ptr != 0); +BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr; +switch(opcode) + { + case OP_BRAPOS: + case OP_SBRAPOS: + ccbegin = cc + 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + offset = GET2(cc, 1 + LINK_SIZE); + /* This case cannot be optimized in the same was as + normal capturing brackets. */ + SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); + cbraprivptr = OVECTOR_PRIV(offset); + offset <<= 1; + ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); +BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; +if (framesize < 0) + { + if (offset != 0) + { + stacksize = 2; + if (common->capture_last_ptr != 0) + stacksize++; + } + else + stacksize = 1; + + if (needs_control_head) + stacksize++; + if (!zero) + stacksize++; + + BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; + allocate_stack(common, stacksize); + if (framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); + + stack = 0; + if (offset != 0) + { + stack = 2; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + if (common->capture_last_ptr != 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + stack = 3; + } + } + else + { + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + stack = 1; + } + + if (needs_control_head) + stack++; + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1); + if (needs_control_head) + { + stack--; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); + } + } +else + { + stacksize = framesize + 1; + if (!zero) + stacksize++; + if (needs_control_head) + stacksize++; + if (offset == 0) + stacksize++; + BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; + + allocate_stack(common, stacksize); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); + + stack = 0; + if (!zero) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); + stack = 1; + } + if (needs_control_head) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); + stack++; + } + if (offset == 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); + stack++; + } + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); + init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); + stack -= 1 + (offset == 0); + } + +if (offset != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); + +loop = LABEL(); +while (*cc != OP_KETRPOS) + { + backtrack->top = NULL; + backtrack->topbacktracks = NULL; + cc += GET(cc, 1); + + compile_matchingpath(common, ccbegin, cc, backtrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + + if (framesize < 0) + { + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + } + else + { + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + + /* Even if the match is empty, we need to reset the control head. */ + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + } + else + { + if (offset != 0) + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); + } + + /* Even if the match is empty, we need to reset the control head. */ + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + { + if (framesize < 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + + JUMPTO(SLJIT_JUMP, loop); + flush_stubs(common); + + compile_backtrackingpath(common, backtrack->top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + set_jumps(backtrack->topbacktracks, LABEL()); + + if (framesize < 0) + { + if (offset != 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + else + { + if (offset != 0) + { + /* Last alternative. */ + if (*cc == OP_KETRPOS) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); + } + } + + if (*cc == OP_KETRPOS) + break; + ccbegin = cc + 1 + LINK_SIZE; + } + +/* We don't have to restore the control head in case of a failed match. */ + +backtrack->topbacktracks = NULL; +if (!zero) + { + if (framesize < 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); + else /* TMP2 is set to [private_data_ptr] above. */ + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); + } + +/* None of them matched. */ +set_jumps(emptymatch, LABEL()); +count_match(common); +return cc + 1 + LINK_SIZE; +} + +static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_ui *max, sljit_ui *exact, PCRE2_SPTR *end) +{ +int class_len; + +*opcode = *cc; +*exact = 0; + +if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) + { + cc++; + *type = OP_CHAR; + } +else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) + { + cc++; + *type = OP_CHARI; + *opcode -= OP_STARI - OP_STAR; + } +else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) + { + cc++; + *type = OP_NOT; + *opcode -= OP_NOTSTAR - OP_STAR; + } +else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) + { + cc++; + *type = OP_NOTI; + *opcode -= OP_NOTSTARI - OP_STAR; + } +else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) + { + cc++; + *opcode -= OP_TYPESTAR - OP_STAR; + *type = OP_END; + } +else + { + SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); + *type = *opcode; + cc++; + class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0); + *opcode = cc[class_len - 1]; + + if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) + { + *opcode -= OP_CRSTAR - OP_STAR; + *end = cc + class_len; + + if (*opcode == OP_PLUS || *opcode == OP_MINPLUS) + { + *exact = 1; + *opcode -= OP_PLUS - OP_STAR; + } + } + else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) + { + *opcode -= OP_CRPOSSTAR - OP_POSSTAR; + *end = cc + class_len; + + if (*opcode == OP_POSPLUS) + { + *exact = 1; + *opcode = OP_POSSTAR; + } + } + else + { + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); + *max = GET2(cc, (class_len + IMM2_SIZE)); + *exact = GET2(cc, class_len); + + if (*max == 0) + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSSTAR; + else + *opcode -= OP_CRRANGE - OP_STAR; + } + else + { + *max -= *exact; + if (*max == 0) + *opcode = OP_EXACT; + else if (*max == 1) + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSQUERY; + else + *opcode -= OP_CRRANGE - OP_QUERY; + } + else + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSUPTO; + else + *opcode -= OP_CRRANGE - OP_UPTO; + } + } + *end = cc + class_len + 2 * IMM2_SIZE; + } + return cc; + } + +switch(*opcode) + { + case OP_EXACT: + *exact = GET2(cc, 0); + cc += IMM2_SIZE; + break; + + case OP_PLUS: + case OP_MINPLUS: + *exact = 1; + *opcode -= OP_PLUS - OP_STAR; + break; + + case OP_POSPLUS: + *exact = 1; + *opcode = OP_POSSTAR; + break; + + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + *max = GET2(cc, 0); + cc += IMM2_SIZE; + break; + } + +if (*type == OP_END) + { + *type = *cc; + *end = next_opcode(common, cc); + cc++; + return cc; + } + +*end = cc + 1; +#ifdef SUPPORT_UNICODE +if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); +#endif +return cc; +} + +static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +PCRE2_UCHAR opcode; +PCRE2_UCHAR type; +sljit_ui max = 0, exact; +BOOL fast_fail; +sljit_si fast_str_ptr; +BOOL charpos_enabled; +PCRE2_UCHAR charpos_char; +unsigned int charpos_othercasebit; +PCRE2_SPTR end; +jump_list *no_match = NULL; +jump_list *no_char1_match = NULL; +struct sljit_jump *jump = NULL; +struct sljit_label *label; +int private_data_ptr = PRIVATE_DATA(cc); +int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); +int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; +int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); +int tmp_base, tmp_offset; + +PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); + +fast_str_ptr = PRIVATE_DATA(cc + 1); +fast_fail = TRUE; + +SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr); + +if (cc == common->fast_forward_bc_ptr) + fast_fail = FALSE; +else if (common->fast_fail_start_ptr == 0) + fast_str_ptr = 0; + +SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0 + || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr)); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); + +if (type != OP_EXTUNI) + { + tmp_base = TMP3; + tmp_offset = 0; + } +else + { + tmp_base = SLJIT_MEM1(SLJIT_SP); + tmp_offset = POSSESSIVE0; + } + +if (fast_fail && fast_str_ptr != 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr)); + +/* Handle fixed part first. */ +if (exact > 1) + { + SLJIT_ASSERT(fast_str_ptr == 0); + if (common->mode == PCRE2_JIT_COMPLETE +#ifdef SUPPORT_UNICODE + && !common->utf +#endif + ) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + { + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + } +else if (exact == 1) + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + +switch(opcode) + { + case OP_STAR: + case OP_UPTO: + SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR); + + if (type == OP_ANYNL || type == OP_EXTUNI) + { + SLJIT_ASSERT(private_data_ptr == 0); + SLJIT_ASSERT(fast_str_ptr == 0); + + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max); + + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + if (opcode == OP_UPTO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + jump = JUMP(SLJIT_ZERO); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); + } + + /* We cannot use TMP3 because of this allocate_stack. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + if (jump != NULL) + JUMPHERE(jump); + } + else + { + charpos_enabled = FALSE; + charpos_char = 0; + charpos_othercasebit = 0; + + if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) + { + charpos_enabled = TRUE; +#ifdef SUPPORT_UNICODE + charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]); +#endif + if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1)) + { + charpos_othercasebit = char_get_othercase_bit(common, end + 1); + if (charpos_othercasebit == 0) + charpos_enabled = FALSE; + } + + if (charpos_enabled) + { + charpos_char = end[1]; + /* Consumpe the OP_CHAR opcode. */ + end += 2; +#if PCRE2_CODE_UNIT_WIDTH == 8 + SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); +#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); + if ((charpos_othercasebit & 0x100) != 0) + { + charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; + } +#endif + if (charpos_othercasebit != 0) + charpos_char |= charpos_othercasebit; + + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; + } + } + + if (charpos_enabled) + { + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); + + /* Search the first instance of charpos_char. */ + jump = JUMP(SLJIT_JUMP); + label = LABEL(); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); + } + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + JUMPHERE(jump); + + detect_partial_match(common, &backtrack->topbacktracks); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } + + /* Search the last instance of charpos_char. */ + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + detect_partial_match(common, &no_match); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + if (opcode == OP_STAR) + { + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } + else + { + jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPHERE(jump); + } + + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + else if (common->utf) + { + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + } +#endif + else + { + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + label = LABEL(); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + } + } + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_MINSTAR: + if (private_data_ptr == 0) + allocate_stack(common, 1); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + break; + + case OP_MINUPTO: + SLJIT_ASSERT(fast_str_ptr == 0); + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_QUERY: + case OP_MINQUERY: + SLJIT_ASSERT(fast_str_ptr == 0); + if (private_data_ptr == 0) + allocate_stack(common, 1); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode == OP_QUERY) + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_EXACT: + break; + + case OP_POSSTAR: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + { + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + break; + } +#endif + label = LABEL(); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + JUMPTO(SLJIT_JUMP, label); + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + break; + + case OP_POSUPTO: + SLJIT_ASSERT(fast_str_ptr == 0); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); + break; + } +#endif + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + label = LABEL(); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + break; + + case OP_POSQUERY: + SLJIT_ASSERT(fast_str_ptr == 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +count_match(common); +return end; +} + +static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; + +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); + +if (*cc == OP_FAIL) + { + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + return cc + 1; + } + +if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) + { + /* No need to check notempty conditions. */ + if (common->accept_label == NULL) + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->accept_label); + return cc + 1; + } + +if (common->accept_label == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); +else + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); +add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); +if (common->accept_label == NULL) + add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO)); +else + JUMPTO(SLJIT_ZERO, common->accept_label); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +if (common->accept_label == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); +else + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); +add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); +return cc + 1; +} + +static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1); +BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0; + +/* Data will be discarded anyway... */ +if (common->currententry != NULL) + return cc + 1 + IMM2_SIZE; + +if (!optimized_cbracket) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset)); +offset <<= 1; +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); +if (!optimized_cbracket) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); +return cc + 1 + IMM2_SIZE; +} + +static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +PCRE2_UCHAR opcode = *cc; +PCRE2_SPTR ccend = cc + 1; + +if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) + ccend += 2 + cc[1]; + +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); + +if (opcode == OP_SKIP) + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + return ccend; + } + +if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); + } + +return ccend; +} + +static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP }; + +static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +BOOL needs_control_head; +int size; + +PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); +common->then_trap = BACKTRACK_AS(then_trap_backtrack); +BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; +BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start); +BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); + +size = BACKTRACK_AS(then_trap_backtrack)->framesize; +size = 3 + (size < 0 ? 0 : size); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); +allocate_stack(common, size); +if (size > 3) + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw)); +else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0); + +size = BACKTRACK_AS(then_trap_backtrack)->framesize; +if (size >= 0) + init_frame(common, cc, ccend, size - 1, 0, FALSE); +} + +static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +BOOL has_then_trap = FALSE; +then_trap_backtrack *save_then_trap = NULL; + +SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); + +if (common->has_then && common->then_offsets[cc - common->start] != 0) + { + SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); + has_then_trap = TRUE; + save_then_trap = common->then_trap; + /* Tail item on backtrack. */ + compile_then_trap_matchingpath(common, cc, ccend, parent); + } + +while (cc < ccend) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_REVERSE: + cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_NOTPROP: + case OP_PROP: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_NOT: + case OP_NOTI: + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + break; + + case OP_SET_SOM: + PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + cc++; + break; + + case OP_CHAR: + case OP_CHARI: + if (common->mode == PCRE2_JIT_COMPLETE) + cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + else + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + cc = compile_iterator_matchingpath(common, cc, parent); + break; + + case OP_CLASS: + case OP_NCLASS: + if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) + cc = compile_iterator_matchingpath(common, cc, parent); + else + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + break; + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + case OP_XCLASS: + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) + cc = compile_iterator_matchingpath(common, cc, parent); + else + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + break; +#endif + + case OP_REF: + case OP_REFI: + if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) + cc = compile_ref_iterator_matchingpath(common, cc, parent); + else + { + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + cc += 1 + IMM2_SIZE; + } + break; + + case OP_DNREF: + case OP_DNREFI: + if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) + cc = compile_ref_iterator_matchingpath(common, cc, parent); + else + { + compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + cc += 1 + 2 * IMM2_SIZE; + } + break; + + case OP_RECURSE: + cc = compile_recurse_matchingpath(common, cc, parent); + break; + + case OP_CALLOUT: + case OP_CALLOUT_STR: + cc = compile_callout_matchingpath(common, cc, parent); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); + cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + break; + + case OP_BRAMINZERO: + PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); + cc = bracketend(cc + 1); + if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); + } + BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); + count_match(common); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + cc = compile_bracket_matchingpath(common, cc, parent); + break; + + case OP_BRAZERO: + if (cc[1] > OP_ASSERTBACK_NOT) + cc = compile_bracket_matchingpath(common, cc, parent); + else + { + PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); + cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + } + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + cc = compile_bracketpos_matchingpath(common, cc, parent); + break; + + case OP_MARK: + PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); + SLJIT_ASSERT(common->mark_ptr != 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + allocate_stack(common, common->has_skip_arg ? 5 : 1); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); + if (common->has_skip_arg) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + } + cc += 1 + 2 + cc[1]; + break; + + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + case OP_THEN: + case OP_THEN_ARG: + case OP_COMMIT: + cc = compile_control_verb_matchingpath(common, cc, parent); + break; + + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + cc = compile_fail_accept_matchingpath(common, cc, parent); + break; + + case OP_CLOSE: + cc = compile_close_matchingpath(common, cc); + break; + + case OP_SKIPZERO: + cc = bracketend(cc + 1); + break; + + default: + SLJIT_ASSERT_STOP(); + return; + } + if (cc == NULL) + return; + } + +if (has_then_trap) + { + /* Head item on backtrack. */ + PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); + BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; + BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; + common->then_trap = save_then_trap; + } +SLJIT_ASSERT(cc == ccend); +} + +#undef PUSH_BACKTRACK +#undef PUSH_BACKTRACK_NOVALUE +#undef BACKTRACK_AS + +#define COMPILE_BACKTRACKINGPATH(current) \ + do \ + { \ + compile_backtrackingpath(common, (current)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + } \ + while (0) + +#define CURRENT_AS(type) ((type *)current) + +static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +PCRE2_SPTR cc = current->cc; +PCRE2_UCHAR opcode; +PCRE2_UCHAR type; +sljit_ui max = 0, exact; +struct sljit_label *label = NULL; +struct sljit_jump *jump = NULL; +jump_list *jumplist = NULL; +PCRE2_SPTR end; +int private_data_ptr = PRIVATE_DATA(cc); +int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); +int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; +int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); + +switch(opcode) + { + case OP_STAR: + case OP_UPTO: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + SLJIT_ASSERT(private_data_ptr == 0); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); + } + else + { + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled) + { + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, TMP2, 0, base, offset1); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + label = LABEL(); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); + skip_char_back(common); + CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + skip_char_back(common); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + } + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 2); + } + break; + + case OP_MINSTAR: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + if (private_data_ptr == 0) + free_stack(common, 1); + break; + + case OP_MINUPTO: + OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); + + OP1(SLJIT_MOV, base, offset1, TMP1, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + + set_jumps(jumplist, LABEL()); + if (private_data_ptr == 0) + free_stack(common, 2); + break; + + case OP_QUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); + jump = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 1); + break; + + case OP_MINQUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 1); + break; + + case OP_EXACT: + case OP_POSSTAR: + case OP_POSQUERY: + case OP_POSUPTO: + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + + set_jumps(current->topbacktracks, LABEL()); +} + +static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +PCRE2_SPTR cc = current->cc; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); +PCRE2_UCHAR type; + +type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; + +if ((type & 0x1) == 0) + { + /* Maximize case. */ + set_jumps(current->topbacktracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); + return; + } + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); +set_jumps(current->topbacktracks, LABEL()); +free_stack(common, ref ? 2 : 3); +} + +static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; + +if (CURRENT_AS(recurse_backtrack)->inlined_pattern) + compile_backtrackingpath(common, current->top); +set_jumps(current->topbacktracks, LABEL()); +if (CURRENT_AS(recurse_backtrack)->inlined_pattern) + return; + +if (common->has_set_som && common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); + } +else if (common->has_set_som || common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); + } +} + +static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +PCRE2_SPTR cc = current->cc; +PCRE2_UCHAR bra = OP_BRA; +struct sljit_jump *brajump = NULL; + +SLJIT_ASSERT(*cc != OP_BRAMINZERO); +if (*cc == OP_BRAZERO) + { + bra = *cc; + cc++; + } + +if (bra == OP_BRAZERO) + { + SLJIT_ASSERT(current->topbacktracks == NULL); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + +if (CURRENT_AS(assert_backtrack)->framesize < 0) + { + set_jumps(current->topbacktracks, LABEL()); + + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); + free_stack(common, 1); + } + return; + } + +if (bra == OP_BRAZERO) + { + if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); + free_stack(common, 1); + return; + } + free_stack(common, 1); + brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw)); + + set_jumps(current->topbacktracks, LABEL()); + } +else + set_jumps(current->topbacktracks, LABEL()); + +if (bra == OP_BRAZERO) + { + /* We know there is enough place on the stack. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath); + JUMPHERE(brajump); + } +} + +static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +int opcode, stacksize, alt_count, alt_max; +int offset = 0; +int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; +int repeat_ptr = 0, repeat_type = 0, repeat_count = 0; +PCRE2_SPTR cc = current->cc; +PCRE2_SPTR ccbegin; +PCRE2_SPTR ccprev; +PCRE2_UCHAR bra = OP_BRA; +PCRE2_UCHAR ket; +assert_backtrack *assert; +sljit_uw *next_update_addr = NULL; +BOOL has_alternatives; +BOOL needs_control_head = FALSE; +struct sljit_jump *brazero = NULL; +struct sljit_jump *alt1 = NULL; +struct sljit_jump *alt2 = NULL; +struct sljit_jump *once = NULL; +struct sljit_jump *cond = NULL; +struct sljit_label *rmin_label = NULL; +struct sljit_label *exact_label = NULL; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + } + +opcode = *cc; +ccbegin = bracketend(cc) - 1 - LINK_SIZE; +ket = *ccbegin; +if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0) + { + repeat_ptr = PRIVATE_DATA(ccbegin); + repeat_type = PRIVATE_DATA(ccbegin + 2); + repeat_count = PRIVATE_DATA(ccbegin + 3); + SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0); + if (repeat_type == OP_UPTO) + ket = OP_KETRMAX; + if (repeat_type == OP_MINUPTO) + ket = OP_KETRMIN; + } +ccbegin = cc; +cc += GET(cc, 1); +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; +if (opcode == OP_CBRA || opcode == OP_SCBRA) + offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +alt_max = has_alternatives ? no_alternatives(ccbegin) : 0; + +/* Decoding the needs_control_head in framesize. */ +if (opcode == OP_ONCE) + { + needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0; + CURRENT_AS(bracket_backtrack)->u.framesize >>= 1; + } + +if (ket != OP_KET && repeat_type != 0) + { + /* TMP1 is used in OP_KETRMIN below. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + if (repeat_type == OP_UPTO) + OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1); + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); + } + +if (ket == OP_KETRMAX) + { + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } + } +else if (ket == OP_KETRMIN) + { + if (bra != OP_BRAMINZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (repeat_type != 0) + { + /* TMP1 was set a few lines above. */ + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + /* Drop STR_PTR for non-greedy plus quantifier. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else if (opcode >= OP_SBRA || opcode == OP_ONCE) + { + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + } + /* Drop STR_PTR for non-greedy plus quantifier. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + } + rmin_label = LABEL(); + if (repeat_type != 0) + OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } +else if (repeat_type == OP_EXACT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); + exact_label = LABEL(); + } + +if (offset != 0) + { + if (common->capture_last_ptr != 0) + { + SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); + } + else if (common->optimized_cbracket[offset >> 1] == 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); + } + } + +if (SLJIT_UNLIKELY(opcode == OP_ONCE)) + { + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + once = JUMP(SLJIT_JUMP); + } +else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + if (has_alternatives) + { + /* Always exactly one alternative. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + + alt_max = 2; + alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); + } + } +else if (has_alternatives) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + + if (alt_max > 4) + { + /* Table jump if alt_max is greater than 4. */ + next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw)); + if (SLJIT_UNLIKELY(next_update_addr == NULL)) + return; + sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr); + add_label_addr(common, next_update_addr++); + } + else + { + if (alt_max == 4) + alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); + alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); + } + } + +COMPILE_BACKTRACKINGPATH(current->top); +if (current->topbacktracks) + set_jumps(current->topbacktracks, LABEL()); + +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + /* Conditional block always has at most one alternative. */ + if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) + { + SLJIT_ASSERT(has_alternatives); + assert = CURRENT_AS(bracket_backtrack)->u.assert; + if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + } + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); + } + else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) + { + SLJIT_ASSERT(has_alternatives); + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); + } + else + SLJIT_ASSERT(!has_alternatives); + } + +if (has_alternatives) + { + alt_count = sizeof(sljit_uw); + do + { + current->top = NULL; + current->topbacktracks = NULL; + current->nextbacktracks = NULL; + /* Conditional blocks always have an additional alternative, even if it is empty. */ + if (*cc == OP_ALT) + { + ccprev = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + if (opcode != OP_COND && opcode != OP_SCOND) + { + if (opcode != OP_ONCE) + { + if (private_data_ptr != 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); + } + compile_matchingpath(common, ccprev, cc, current); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + } + + /* Instructions after the current alternative is successfully matched. */ + /* There is a similar code in compile_bracket_matchingpath. */ + if (opcode == OP_ONCE) + match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); + + stacksize = 0; + if (repeat_type == OP_MINUPTO) + { + /* We need to preserve the counter. TMP2 will be used below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); + stacksize++; + } + if (ket != OP_KET || bra != OP_BRA) + stacksize++; + if (offset != 0) + { + if (common->capture_last_ptr != 0) + stacksize++; + if (common->optimized_cbracket[offset >> 1] == 0) + stacksize += 2; + } + if (opcode != OP_ONCE) + stacksize++; + + if (stacksize > 0) + allocate_stack(common, stacksize); + + stacksize = 0; + if (repeat_type == OP_MINUPTO) + { + /* TMP2 was set above. */ + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); + stacksize++; + } + + if (ket != OP_KET || bra != OP_BRA) + { + if (ket != OP_KET) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + + if (offset != 0) + stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); + + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); + + if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0) + { + /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */ + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); + } + + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath); + + if (opcode != OP_ONCE) + { + if (alt_max > 4) + add_label_addr(common, next_update_addr++); + else + { + if (alt_count != 2 * sizeof(sljit_uw)) + { + JUMPHERE(alt1); + if (alt_max == 3 && alt_count == sizeof(sljit_uw)) + alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); + } + else + { + JUMPHERE(alt2); + if (alt_max == 4) + alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); + } + } + alt_count += sizeof(sljit_uw); + } + + COMPILE_BACKTRACKINGPATH(current->top); + if (current->topbacktracks) + set_jumps(current->topbacktracks, LABEL()); + SLJIT_ASSERT(!current->nextbacktracks); + } + while (*cc == OP_ALT); + + if (cond != NULL) + { + SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); + assert = CURRENT_AS(bracket_backtrack)->u.assert; + if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + } + JUMPHERE(cond); + } + + /* Free the STR_PTR. */ + if (private_data_ptr == 0) + free_stack(common, 1); + } + +if (offset != 0) + { + /* Using both tmp register is better for instruction scheduling. */ + if (common->optimized_cbracket[offset >> 1] != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + } + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + } +else if (opcode == OP_ONCE) + { + cc = ccbegin + GET(ccbegin, 1); + stacksize = needs_control_head ? 1 : 0; + + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + { + /* Reset head and drop saved frame. */ + stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1); + } + else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) + { + /* The STR_PTR must be released. */ + stacksize++; + } + + if (stacksize > 0) + free_stack(common, stacksize); + + JUMPHERE(once); + /* Restore previous private_data_ptr */ + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw)); + else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* See the comment below. */ + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + } + } + +if (repeat_type == OP_EXACT) + { + OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); + CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label); + } +else if (ket == OP_KETRMAX) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra != OP_BRAZERO) + free_stack(common, 1); + + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); + JUMPHERE(brazero); + free_stack(common, 1); + } + } +else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + /* OP_ONCE removes everything in case of a backtrack, so we don't + need to explicitly release the STR_PTR. The extra release would + affect badly the free_stack(2) above. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label); + if (opcode == OP_ONCE) + free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); + else if (bra == OP_BRAMINZERO) + free_stack(common, 1); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); + JUMPHERE(brazero); + } +} + +static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +int offset; +struct sljit_jump *jump; + +if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) + { + if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) + { + offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); + } + set_jumps(current->topbacktracks, LABEL()); + free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); + return; + } + +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr); +add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + +if (current->topbacktracks) + { + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topbacktracks, LABEL()); + /* Drop the stack frame. */ + free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); + JUMPHERE(jump); + } +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); +} + +static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +assert_backtrack backtrack; + +current->top = NULL; +current->topbacktracks = NULL; +current->nextbacktracks = NULL; +if (current->cc[1] > OP_ASSERTBACK_NOT) + { + /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ + compile_bracket_matchingpath(common, current->cc, current); + compile_bracket_backtrackingpath(common, current->top); + } +else + { + memset(&backtrack, 0, sizeof(backtrack)); + backtrack.common.cc = current->cc; + backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath; + /* Manual call of compile_assert_matchingpath. */ + compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); + } +SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); +} + +static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +PCRE2_UCHAR opcode = *current->cc; +struct sljit_label *loop; +struct sljit_jump *jump; + +if (opcode == OP_THEN || opcode == OP_THEN_ARG) + { + if (common->then_trap != NULL) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start); + jump = JUMP(SLJIT_JUMP); + + loop = LABEL(); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw)); + JUMPHERE(jump); + CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop); + CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop); + add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); + return; + } + else if (common->positive_assert) + { + add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP)); + return; + } + } + +if (common->local_exit) + { + if (common->quit_label == NULL) + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->quit_label); + return; + } + +if (opcode == OP_SKIP_ARG) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); + sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); + return; + } + +if (opcode == OP_SKIP) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0); +add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); +} + +static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +int size; + +if (CURRENT_AS(then_trap_backtrack)->then_trap) + { + common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; + return; + } + +size = CURRENT_AS(then_trap_backtrack)->framesize; +size = 3 + (size < 0 ? 0 : size); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3)); +free_stack(common, size); +jump = JUMP(SLJIT_JUMP); + +set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); +/* STACK_TOP is set by THEN. */ +if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +free_stack(common, 3); + +JUMPHERE(jump); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); +} + +static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +then_trap_backtrack *save_then_trap = common->then_trap; + +while (current) + { + if (current->nextbacktracks != NULL) + set_jumps(current->nextbacktracks, LABEL()); + switch(*current->cc) + { + case OP_SET_SOM: + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: +#endif + compile_iterator_backtrackingpath(common, current); + break; + + case OP_REF: + case OP_REFI: + case OP_DNREF: + case OP_DNREFI: + compile_ref_iterator_backtrackingpath(common, current); + break; + + case OP_RECURSE: + compile_recurse_backtrackingpath(common, current); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + compile_assert_backtrackingpath(common, current); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + compile_bracket_backtrackingpath(common, current); + break; + + case OP_BRAZERO: + if (current->cc[1] > OP_ASSERTBACK_NOT) + compile_bracket_backtrackingpath(common, current); + else + compile_assert_backtrackingpath(common, current); + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + compile_bracketpos_backtrackingpath(common, current); + break; + + case OP_BRAMINZERO: + compile_braminzero_backtrackingpath(common, current); + break; + + case OP_MARK: + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0)); + if (common->has_skip_arg) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, common->has_skip_arg ? 5 : 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); + if (common->has_skip_arg) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); + break; + + case OP_THEN: + case OP_THEN_ARG: + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + compile_control_verb_backtrackingpath(common, current); + break; + + case OP_COMMIT: + if (!common->local_exit) + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + if (common->quit_label == NULL) + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->quit_label); + break; + + case OP_CALLOUT: + case OP_CALLOUT_STR: + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + set_jumps(current->topbacktracks, LABEL()); + break; + + case OP_THEN_TRAP: + /* A virtual opcode for then traps. */ + compile_then_trap_backtrackingpath(common, current); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + current = current->prev; + } +common->then_trap = save_then_trap; +} + +static SLJIT_INLINE void compile_recurse(compiler_common *common) +{ +DEFINE_COMPILER; +PCRE2_SPTR cc = common->start + common->currententry->start; +PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); +PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE); +BOOL needs_control_head; +int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); +int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); +int alternativesize; +BOOL needs_frame; +backtrack_common altbacktrack; +struct sljit_jump *jump; + +/* Recurse captures then. */ +common->then_trap = NULL; + +SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); +needs_frame = framesize >= 0; +if (!needs_frame) + framesize = 0; +alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; + +SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0); +common->currententry->entry = LABEL(); +set_jumps(common->currententry->calls, common->currententry->entry); + +sljit_emit_fast_enter(compiler, TMP2, 0); +count_match(common); +allocate_stack(common, private_data_size + framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); +copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0); +if (needs_frame) + init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE); + +if (alternativesize > 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +memset(&altbacktrack, 0, sizeof(backtrack_common)); +common->quit_label = NULL; +common->accept_label = NULL; +common->quit = NULL; +common->accept = NULL; +altbacktrack.cc = ccbegin; +cc += GET(cc, 1); +while (1) + { + altbacktrack.top = NULL; + altbacktrack.topbacktracks = NULL; + + if (altbacktrack.cc != ccbegin) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + + compile_backtrackingpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + set_jumps(altbacktrack.topbacktracks, LABEL()); + + if (*cc != OP_ALT) + break; + + altbacktrack.cc = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } + +/* None of them matched. */ +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_JUMP); + +if (common->quit != NULL) + { + set_jumps(common->quit, LABEL()); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); + if (needs_frame) + { + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + } + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); + common->quit = NULL; + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + } + +set_jumps(common->accept, LABEL()); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); +if (needs_frame) + { + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + } +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + +JUMPHERE(jump); +if (common->quit != NULL) + set_jumps(common->quit, LABEL()); +copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); +free_stack(common, private_data_size + framesize + alternativesize); +if (needs_control_head) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); + } +else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0); + } +sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); +} + +#undef COMPILE_BACKTRACKINGPATH +#undef CURRENT_AS + +static int jit_compile(pcre2_code *code, uint32_t mode) +{ +pcre2_real_code *re = (pcre2_real_code *)code; +struct sljit_compiler *compiler; +backtrack_common rootbacktrack; +compiler_common common_data; +compiler_common *common = &common_data; +const sljit_ub *tables = re->tables; +void *allocator_data = &re->memctl; +int private_data_size; +PCRE2_SPTR ccend; +executable_functions *functions; +void *executable_func; +sljit_uw executable_size; +sljit_uw total_length; +label_addr_list *label_addr; +struct sljit_label *mainloop_label = NULL; +struct sljit_label *continue_match_label; +struct sljit_label *empty_match_found_label = NULL; +struct sljit_label *empty_match_backtrack_label = NULL; +struct sljit_label *reset_match_label; +struct sljit_label *quit_label; +struct sljit_jump *jump; +struct sljit_jump *minlength_check_failed = NULL; +struct sljit_jump *reqbyte_notfound = NULL; +struct sljit_jump *empty_match = NULL; + +SLJIT_ASSERT(tables); + +memset(&rootbacktrack, 0, sizeof(backtrack_common)); +memset(common, 0, sizeof(compiler_common)); +common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); +rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size; + +common->start = rootbacktrack.cc; +common->read_only_data_head = NULL; +common->fcc = tables + fcc_offset; +common->lcc = (sljit_sw)(tables + lcc_offset); +common->mode = mode; +common->might_be_empty = re->minlength == 0; +common->nltype = NLTYPE_FIXED; +switch(re->newline_convention) + { + case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break; + case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break; + case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; + case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + default: return PCRE2_ERROR_INTERNAL; + } +common->nlmax = READ_CHAR_MAX; +common->nlmin = 0; +if (re->bsr_convention == PCRE2_BSR_UNICODE) + common->bsr_nltype = NLTYPE_ANY; +else if (re->bsr_convention == PCRE2_BSR_ANYCRLF) + common->bsr_nltype = NLTYPE_ANYCRLF; +else + { +#ifdef BSR_ANYCRLF + common->bsr_nltype = NLTYPE_ANYCRLF; +#else + common->bsr_nltype = NLTYPE_ANY; +#endif + } +common->bsr_nlmax = READ_CHAR_MAX; +common->bsr_nlmin = 0; +common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0; +common->ctypes = (sljit_sw)(tables + ctypes_offset); +common->name_count = re->name_count; +common->name_entry_size = re->name_entry_size; +common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0; +common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0; +#ifdef SUPPORT_UNICODE +/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ +common->utf = (re->overall_options & PCRE2_UTF) != 0; +common->use_ucp = (re->overall_options & PCRE2_UCP) != 0; +if (common->utf) + { + if (common->nltype == NLTYPE_ANY) + common->nlmax = 0x2029; + else if (common->nltype == NLTYPE_ANYCRLF) + common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; + else + { + /* We only care about the first newline character. */ + common->nlmax = common->newline & 0xff; + } + + if (common->nltype == NLTYPE_FIXED) + common->nlmin = common->newline & 0xff; + else + common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; + + if (common->bsr_nltype == NLTYPE_ANY) + common->bsr_nlmax = 0x2029; + else + common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; + common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; + } +#endif /* SUPPORT_UNICODE */ +ccend = bracketend(common->start); + +/* Calculate the local space size on the stack. */ +common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); +common->optimized_cbracket = (sljit_ub *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); +if (!common->optimized_cbracket) + return PCRE2_ERROR_NOMEMORY; +#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 +memset(common->optimized_cbracket, 0, re->top_bracket + 1); +#else +memset(common->optimized_cbracket, 1, re->top_bracket + 1); +#endif + +SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); +#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2 +common->capture_last_ptr = common->ovector_start; +common->ovector_start += sizeof(sljit_sw); +#endif +if (!check_opcode_types(common, common->start, ccend)) + { + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + +/* Checking flags and updating ovector_start. */ +if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + { + common->req_char_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } +if (mode != PCRE2_JIT_COMPLETE) + { + common->start_used_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + if (mode == PCRE2_JIT_PARTIAL_SOFT) + { + common->hit_start = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + } +if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0) + { + common->match_end_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } +#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD +common->control_head_ptr = 1; +#endif +if (common->control_head_ptr != 0) + { + common->control_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } +if (common->has_set_som) + { + /* Saving the real start pointer is necessary. */ + common->start_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + +/* Aligning ovector to even number of sljit words. */ +if ((common->ovector_start & sizeof(sljit_sw)) != 0) + common->ovector_start += sizeof(sljit_sw); + +if (common->start_ptr == 0) + common->start_ptr = OVECTOR(0); + +/* Capturing brackets cannot be optimized if callouts are allowed. */ +if (common->capture_last_ptr != 0) + memset(common->optimized_cbracket, 0, re->top_bracket + 1); + +SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); +common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); + +total_length = ccend - common->start; +common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)), allocator_data); +if (!common->private_data_ptrs) + { + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } +memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); + +private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); +set_private_data_ptrs(common, &private_data_size, ccend); +if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + { + if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back) + detect_fast_fail(common, common->start, &private_data_size, 4); + } + +SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr); + +if (private_data_size > SLJIT_MAX_LOCAL_SIZE) + { + SLJIT_FREE(common->private_data_ptrs, allocator_data); + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + +if (common->has_then) + { + common->then_offsets = (sljit_ub *)(common->private_data_ptrs + total_length); + memset(common->then_offsets, 0, total_length); + set_then_offsets(common, common->start, NULL); + } + +compiler = sljit_create_compiler(allocator_data); +if (!compiler) + { + SLJIT_FREE(common->optimized_cbracket, allocator_data); + SLJIT_FREE(common->private_data_ptrs, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } +common->compiler = compiler; + +/* Main pcre_jit_exec entry. */ +sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size); + +/* Register init. */ +reset_ovector(common, (re->top_bracket + 1) * 2); +if (common->req_char_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0); + +OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0); + +if (common->fast_fail_start_ptr < common->fast_fail_end_ptr) + reset_fast_fail(common); + +if (mode == PCRE2_JIT_PARTIAL_SOFT) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); +if (common->control_head_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); + +/* Main part of the matching */ +if ((re->overall_options & PCRE2_ANCHORED) == 0) + { + mainloop_label = mainloop_entry(common, (re->flags & PCRE2_HASCRORLF) != 0, re->overall_options); + continue_match_label = LABEL(); + /* Forward search if possible. */ + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + { + if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common)) + ; + else if ((re->flags & PCRE2_FIRSTSET) != 0) + fast_forward_first_char(common, (PCRE2_UCHAR)(re->first_codeunit), (re->flags & PCRE2_FIRSTCASELESS) != 0); + else if ((re->flags & PCRE2_STARTLINE) != 0) + fast_forward_newline(common); + else if ((re->flags & PCRE2_FIRSTMAPSET) != 0) + fast_forward_start_bits(common, re->start_bitmap); + } + } +else + continue_match_label = LABEL(); + +if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + { + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength)); + minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0); + } +if (common->req_char_ptr != 0) + reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0); + +/* Store the current STR_PTR in OVECTOR(0). */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); +/* Copy the limit of allowed recursions. */ +OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH); +if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0); +if (common->fast_forward_bc_ptr != NULL) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0); + +if (common->start_ptr != OVECTOR(0)) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0); + +/* Copy the beginning of the string. */ +if (mode == PCRE2_JIT_PARTIAL_SOFT) + { + jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +else if (mode == PCRE2_JIT_PARTIAL_HARD) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + +compile_matchingpath(common, common->start, ccend, &rootbacktrack); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); + SLJIT_FREE(common->private_data_ptrs, allocator_data); + PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + +if (common->might_be_empty) + { + empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); + empty_match_found_label = LABEL(); + } + +common->accept_label = LABEL(); +if (common->accept != NULL) + set_jumps(common->accept, common->accept_label); + +/* This means we have a match. Update the ovector. */ +copy_ovector(common, re->top_bracket + 1); +common->quit_label = common->forced_quit_label = LABEL(); +if (common->quit != NULL) + set_jumps(common->quit, common->quit_label); +if (common->forced_quit != NULL) + set_jumps(common->forced_quit, common->forced_quit_label); +if (minlength_check_failed != NULL) + SET_LABEL(minlength_check_failed, common->forced_quit_label); +sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); + +if (mode != PCRE2_JIT_COMPLETE) + { + common->partialmatchlabel = LABEL(); + set_jumps(common->partialmatch, common->partialmatchlabel); + return_with_partial_match(common, common->quit_label); + } + +if (common->might_be_empty) + empty_match_backtrack_label = LABEL(); +compile_backtrackingpath(common, rootbacktrack.top); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); + SLJIT_FREE(common->private_data_ptrs, allocator_data); + PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + +SLJIT_ASSERT(rootbacktrack.prev == NULL); +reset_match_label = LABEL(); + +if (mode == PCRE2_JIT_PARTIAL_SOFT) + { + /* Update hit_start only in the first time. */ + jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0); + JUMPHERE(jump); + } + +/* Check we have remaining characters. */ +if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + } + +if (common->fast_forward_bc_ptr != NULL) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1)); +else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + +if ((re->overall_options & PCRE2_ANCHORED) == 0) + { + if (common->ff_newline_shortcut != NULL) + { + /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */ + if ((re->overall_options & PCRE2_FIRSTLINE) == 0) + { + if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); + CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + } + else + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut); + } + } + else + { + CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label); + } + } + +/* No more remaining characters. */ +if (reqbyte_notfound != NULL) + JUMPHERE(reqbyte_notfound); + +if (mode == PCRE2_JIT_PARTIAL_SOFT) + CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel); + +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); +JUMPTO(SLJIT_JUMP, common->quit_label); + +flush_stubs(common); + +if (common->might_be_empty) + { + JUMPHERE(empty_match); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); + JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); + JUMPTO(SLJIT_ZERO, empty_match_found_label); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label); + JUMPTO(SLJIT_JUMP, empty_match_backtrack_label); + } + +common->fast_forward_bc_ptr = NULL; +common->fast_fail_start_ptr = 0; +common->fast_fail_end_ptr = 0; +common->currententry = common->entries; +common->local_exit = TRUE; +quit_label = common->quit_label; +while (common->currententry != NULL) + { + /* Might add new entries. */ + compile_recurse(common); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); + SLJIT_FREE(common->private_data_ptrs, allocator_data); + PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + flush_stubs(common); + common->currententry = common->currententry->next; + } +common->local_exit = FALSE; +common->quit_label = quit_label; + +/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ +/* This is a (really) rare case. */ +set_jumps(common->stackalloc, LABEL()); +/* RETURN_ADDR is not a saved register. */ +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); +OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); + +sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); +jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); + +/* Allocation failed. */ +JUMPHERE(jump); +/* We break the return address cache here, but this is a really rare case. */ +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT); +JUMPTO(SLJIT_JUMP, common->quit_label); + +/* Call limit reached. */ +set_jumps(common->calllimit, LABEL()); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT); +JUMPTO(SLJIT_JUMP, common->quit_label); + +if (common->revertframes != NULL) + { + set_jumps(common->revertframes, LABEL()); + do_revertframes(common); + } +if (common->wordboundary != NULL) + { + set_jumps(common->wordboundary, LABEL()); + check_wordboundary(common); + } +if (common->anynewline != NULL) + { + set_jumps(common->anynewline, LABEL()); + check_anynewline(common); + } +if (common->hspace != NULL) + { + set_jumps(common->hspace, LABEL()); + check_hspace(common); + } +if (common->vspace != NULL) + { + set_jumps(common->vspace, LABEL()); + check_vspace(common); + } +if (common->casefulcmp != NULL) + { + set_jumps(common->casefulcmp, LABEL()); + do_casefulcmp(common); + } +if (common->caselesscmp != NULL) + { + set_jumps(common->caselesscmp, LABEL()); + do_caselesscmp(common); + } +if (common->reset_match != NULL) + { + set_jumps(common->reset_match, LABEL()); + do_reset_match(common, (re->top_bracket + 1) * 2); + CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + JUMPTO(SLJIT_JUMP, reset_match_label); + } +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utfreadchar != NULL) + { + set_jumps(common->utfreadchar, LABEL()); + do_utfreadchar(common); + } +if (common->utfreadchar16 != NULL) + { + set_jumps(common->utfreadchar16, LABEL()); + do_utfreadchar16(common); + } +if (common->utfreadtype8 != NULL) + { + set_jumps(common->utfreadtype8, LABEL()); + do_utfreadtype8(common); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ +if (common->getucd != NULL) + { + set_jumps(common->getucd, LABEL()); + do_getucd(common); + } +#endif /* SUPPORT_UNICODE */ + +SLJIT_FREE(common->optimized_cbracket, allocator_data); +SLJIT_FREE(common->private_data_ptrs, allocator_data); + +executable_func = sljit_generate_code(compiler); +executable_size = sljit_get_generated_code_size(compiler); +label_addr = common->label_addrs; +while (label_addr != NULL) + { + *label_addr->update_addr = sljit_get_label_addr(label_addr->label); + label_addr = label_addr->next; + } +sljit_free_compiler(compiler); +if (executable_func == NULL) + { + PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + +/* Reuse the function descriptor if possible. */ +if (re->executable_jit != NULL) + functions = (executable_functions *)re->executable_jit; +else + { + functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data); + if (functions == NULL) + { + /* This case is highly unlikely since we just recently + freed a lot of memory. Not impossible though. */ + sljit_free_code(executable_func); + PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); + return PCRE2_ERROR_NOMEMORY; + } + memset(functions, 0, sizeof(executable_functions)); + functions->top_bracket = re->top_bracket + 1; + functions->limit_match = re->limit_match; + re->executable_jit = functions; + } + +/* Turn mode into an index. */ +if (mode == PCRE2_JIT_COMPLETE) + mode = 0; +else + mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2; + +SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES); +functions->executable_funcs[mode] = executable_func; +functions->read_only_data_heads[mode] = common->read_only_data_head; +functions->executable_sizes[mode] = executable_size; +return 0; +} + +#endif + +/************************************************* +* JIT compile a Regular Expression * +*************************************************/ + +/* This function used JIT to convert a previously-compiled pattern into machine +code. + +Arguments: + code a compiled pattern + options JIT option bits + +Returns: 0: success or (*NOJIT) was used + <0: an error code +*/ + +#define PUBLIC_JIT_COMPILE_OPTIONS \ + (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD) + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_jit_compile(pcre2_code *code, uint32_t options) +{ +#ifndef SUPPORT_JIT + +(void)code; +(void)options; +return PCRE2_ERROR_JIT_BADOPTION; + +#else /* SUPPORT_JIT */ + +pcre2_real_code *re = (pcre2_real_code *)code; +executable_functions *functions; +int result; + +if (code == NULL) + return PCRE2_ERROR_NULL; + +if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0) + return PCRE2_ERROR_JIT_BADOPTION; + +if ((re->flags & PCRE2_NOJIT) != 0) return 0; + +functions = (executable_functions *)re->executable_jit; + +if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL + || functions->executable_funcs[0] == NULL)) { + result = jit_compile(code, PCRE2_JIT_COMPLETE); + if (result != 0) + return result; + } + +if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL + || functions->executable_funcs[1] == NULL)) { + result = jit_compile(code, PCRE2_JIT_PARTIAL_SOFT); + if (result != 0) + return result; + } + +if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL + || functions->executable_funcs[2] == NULL)) { + result = jit_compile(code, PCRE2_JIT_PARTIAL_HARD); + if (result != 0) + return result; + } + +return 0; + +#endif /* SUPPORT_JIT */ +} + +/* JIT compiler uses an all-in-one approach. This improves security, + since the code generator functions are not exported. */ + +#define INCLUDED_FROM_PCRE2_JIT_COMPILE + +#include "pcre2_jit_match.c" +#include "pcre2_jit_misc.c" + +/* End of pcre2_jit_compile.c */ diff --git a/pcre2/src/pcre2_jit_match.c b/pcre2/src/pcre2_jit_match.c new file mode 100644 index 000000000..d804cfea4 --- /dev/null +++ b/pcre2/src/pcre2_jit_match.c @@ -0,0 +1,189 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE +#error This file must be included from pcre2_jit_compile.c. +#endif + +#ifdef SUPPORT_JIT + +static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) +{ +sljit_ub local_space[MACHINE_STACK_SIZE]; +struct sljit_stack local_stack; + +local_stack.top = (sljit_sw)&local_space; +local_stack.base = local_stack.top; +local_stack.limit = local_stack.base + MACHINE_STACK_SIZE; +local_stack.max_limit = local_stack.limit; +arguments->stack = &local_stack; +return executable_func(arguments); +} + +#endif + + +/************************************************* +* Do a JIT pattern match * +*************************************************/ + +/* This function runs a JIT pattern match. + +Arguments: + code points to the compiled expression + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + match_data points to a match_data block + mcontext points to a match context + jit_stack points to a JIT stack + +Returns: > 0 => success; value is the number of ovector pairs filled + = 0 => success, but ovector is not big enough + -1 => failed to match (PCRE_ERROR_NOMATCH) + < -1 => some kind of unexpected problem +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, + PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, + pcre2_match_context *mcontext) +{ +#ifndef SUPPORT_JIT + +(void)code; +(void)subject; +(void)length; +(void)start_offset; +(void)options; +(void)match_data; +(void)mcontext; +return PCRE2_ERROR_JIT_BADOPTION; + +#else /* SUPPORT_JIT */ + +pcre2_real_code *re = (pcre2_real_code *)code; +executable_functions *functions = (executable_functions *)re->executable_jit; +pcre2_jit_stack *jit_stack; +uint32_t oveccount = match_data->oveccount; +uint32_t max_oveccount; +union { + void *executable_func; + jit_function call_executable_func; +} convert_executable_func; +jit_arguments arguments; +int rc; +int index = 0; + +if ((options & PCRE2_PARTIAL_HARD) != 0) + index = 2; +else if ((options & PCRE2_PARTIAL_SOFT) != 0) + index = 1; + +if (functions->executable_funcs[index] == NULL) + return PCRE2_ERROR_JIT_BADOPTION; + +/* Sanity checks should be handled by pcre_exec. */ +arguments.str = subject + start_offset; +arguments.begin = subject; +arguments.end = subject + length; +arguments.match_data = match_data; +arguments.startchar_ptr = subject; +arguments.mark_ptr = NULL; +arguments.options = options; + +if (mcontext != NULL) + { + arguments.callout = mcontext->callout; + arguments.callout_data = mcontext->callout_data; + arguments.offset_limit = mcontext->offset_limit; + arguments.limit_match = (mcontext->match_limit < re->limit_match)? + mcontext->match_limit : re->limit_match; + if (mcontext->jit_callback != NULL) + jit_stack = mcontext->jit_callback(mcontext->jit_callback_data); + else + jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data; + } +else + { + arguments.callout = NULL; + arguments.callout_data = NULL; + arguments.offset_limit = PCRE2_UNSET; + arguments.limit_match = (MATCH_LIMIT < re->limit_match)? + MATCH_LIMIT : re->limit_match; + jit_stack = NULL; + } + +/* JIT only need two offsets for each ovector entry. Hence + the last 1/3 of the ovector will never be touched. */ + +max_oveccount = functions->top_bracket; +if (oveccount > max_oveccount) + oveccount = max_oveccount; +arguments.oveccount = oveccount << 1; + + +convert_executable_func.executable_func = functions->executable_funcs[index]; +if (jit_stack != NULL) + { + arguments.stack = (struct sljit_stack *)(jit_stack->stack); + rc = convert_executable_func.call_executable_func(&arguments); + } +else + rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func); + +if (rc > (int)oveccount) + rc = 0; +match_data->code = re; +match_data->subject = subject; +match_data->rc = rc; +match_data->startchar = arguments.startchar_ptr - subject; +match_data->leftchar = 0; +match_data->rightchar = 0; +match_data->mark = arguments.mark_ptr; +match_data->matchedby = PCRE2_MATCHEDBY_JIT; + +return match_data->rc; + +#endif /* SUPPORT_JIT */ +} + +/* End of pcre2_jit_match.c */ diff --git a/pcre2/src/pcre2_jit_misc.c b/pcre2/src/pcre2_jit_misc.c new file mode 100644 index 000000000..efdb05580 --- /dev/null +++ b/pcre2/src/pcre2_jit_misc.c @@ -0,0 +1,227 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE +#error This file must be included from pcre2_jit_compile.c. +#endif + + + +/************************************************* +* Free JIT read-only data * +*************************************************/ + +void +PRIV(jit_free_rodata)(void *current, void *allocator_data) +{ +#ifndef SUPPORT_JIT +(void)current; +(void)allocator_data; +#else /* SUPPORT_JIT */ +void *next; + +SLJIT_UNUSED_ARG(allocator_data); + +while (current != NULL) + { + next = *(void**)current; + SLJIT_FREE(current, allocator_data); + current = next; + } + +#endif /* SUPPORT_JIT */ +} + +/************************************************* +* Free JIT compiled code * +*************************************************/ + +void +PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) +{ +#ifndef SUPPORT_JIT +(void)executable_jit; +(void)memctl; +#else /* SUPPORT_JIT */ + +executable_functions *functions = (executable_functions *)executable_jit; +void *allocator_data = memctl; +int i; + +for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) + { + if (functions->executable_funcs[i] != NULL) + sljit_free_code(functions->executable_funcs[i]); + PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); + } + +SLJIT_FREE(functions, allocator_data); + +#endif /* SUPPORT_JIT */ +} + + +/************************************************* +* Free unused JIT memory * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_jit_free_unused_memory(pcre2_general_context *gcontext) +{ +#ifndef SUPPORT_JIT +(void)gcontext; /* Suppress warning */ +#else /* SUPPORT_JIT */ +SLJIT_UNUSED_ARG(gcontext); +sljit_free_unused_memory_exec(); +#endif /* SUPPORT_JIT */ +} + + + +/************************************************* +* Allocate a JIT stack * +*************************************************/ + +PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION +pcre2_jit_stack_create(size_t startsize, size_t maxsize, + pcre2_general_context *gcontext) +{ +#ifndef SUPPORT_JIT + +(void)gcontext; +(void)startsize; +(void)maxsize; +return NULL; + +#else /* SUPPORT_JIT */ + +pcre2_jit_stack *jit_stack; + +if (startsize < 1 || maxsize < 1) + return NULL; +if (startsize > maxsize) + startsize = maxsize; +startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); +maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); + +jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); +if (jit_stack == NULL) return NULL; +jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); +return jit_stack; + +#endif +} + + +/************************************************* +* Assign a JIT stack to a pattern * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback, + void *callback_data) +{ +#ifndef SUPPORT_JIT +(void)mcontext; +(void)callback; +(void)callback_data; +#else /* SUPPORT_JIT */ + +if (mcontext == NULL) return; +mcontext->jit_callback = callback; +mcontext->jit_callback_data = callback_data; + +#endif /* SUPPORT_JIT */ +} + + +/************************************************* +* Free a JIT stack * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_jit_stack_free(pcre2_jit_stack *jit_stack) +{ +#ifndef SUPPORT_JIT +(void)jit_stack; +#else /* SUPPORT_JIT */ +if (jit_stack != NULL) + { + sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl); + jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); + } +#endif /* SUPPORT_JIT */ +} + + +/************************************************* +* Get target CPU type * +*************************************************/ + +const char* +PRIV(jit_get_target)(void) +{ +#ifndef SUPPORT_JIT +return "JIT is not supported"; +#else /* SUPPORT_JIT */ +return sljit_get_platform_name(); +#endif /* SUPPORT_JIT */ +} + + +/************************************************* +* Get size of JIT code * +*************************************************/ + +size_t +PRIV(jit_get_size)(void *executable_jit) +{ +#ifndef SUPPORT_JIT +(void)executable_jit; +return 0; +#else /* SUPPORT_JIT */ +sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes; +SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed); +return executable_sizes[0] + executable_sizes[1] + executable_sizes[2]; +#endif +} + +/* End of pcre2_jit_misc.c */ diff --git a/pcre2/src/pcre2_jit_test.c b/pcre2/src/pcre2_jit_test.c new file mode 100644 index 000000000..78837cf56 --- /dev/null +++ b/pcre2/src/pcre2_jit_test.c @@ -0,0 +1,1735 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#define PCRE2_CODE_UNIT_WIDTH 0 +#include "pcre2.h" + +/* + Letter characters: + \xe6\x92\xad = 0x64ad = 25773 (kanji) + Non-letter characters: + \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark) + \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888 + \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character) + \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character) + Newlines: + \xc2\x85 = 0x85 = 133 (NExt Line = NEL) + \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator) + Othercase pairs: + \xc3\xa9 = 0xe9 = 233 (e') + \xc3\x89 = 0xc9 = 201 (E') + \xc3\xa1 = 0xe1 = 225 (a') + \xc3\x81 = 0xc1 = 193 (A') + \x53 = 0x53 = S + \x73 = 0x73 = s + \xc5\xbf = 0x17f = 383 (long S) + \xc8\xba = 0x23a = 570 + \xe2\xb1\xa5 = 0x2c65 = 11365 + \xe1\xbd\xb8 = 0x1f78 = 8056 + \xe1\xbf\xb8 = 0x1ff8 = 8184 + \xf0\x90\x90\x80 = 0x10400 = 66560 + \xf0\x90\x90\xa8 = 0x10428 = 66600 + \xc7\x84 = 0x1c4 = 452 + \xc7\x85 = 0x1c5 = 453 + \xc7\x86 = 0x1c6 = 454 + Caseless sets: + ucp_Armenian - \x{531}-\x{556} -> \x{561}-\x{586} + ucp_Coptic - \x{2c80}-\x{2ce3} -> caseless: XOR 0x1 + ucp_Latin - \x{ff21}-\x{ff3a} -> \x{ff41]-\x{ff5a} + + Mark property: + \xcc\x8d = 0x30d = 781 + Special: + \xc2\x80 = 0x80 = 128 (lowest 2 byte character) + \xdf\xbf = 0x7ff = 2047 (highest 2 byte character) + \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character) + \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character) + \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character) + \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character) +*/ + +static int regression_tests(void); + +int main(void) +{ + int jit = 0; +#if defined SUPPORT_PCRE2_8 + pcre2_config_8(PCRE2_CONFIG_JIT, &jit); +#elif defined SUPPORT_PCRE2_16 + pcre2_config_16(PCRE2_CONFIG_JIT, &jit); +#elif defined SUPPORT_PCRE2_32 + pcre2_config_32(PCRE2_CONFIG_JIT, &jit); +#endif + if (!jit) { + printf("JIT must be enabled to run pcre_jit_test\n"); + return 1; + } + return regression_tests(); +} + +/* --------------------------------------------------------------------------------------- */ + +#if !(defined SUPPORT_PCRE2_8) && !(defined SUPPORT_PCRE2_16) && !(defined SUPPORT_PCRE2_32) +#error SUPPORT_PCRE2_8 or SUPPORT_PCRE2_16 or SUPPORT_PCRE2_32 must be defined +#endif + +#define MU (PCRE2_MULTILINE | PCRE2_UTF) +#define MUP (PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP) +#define CMU (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF) +#define CMUP (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP) +#define M (PCRE2_MULTILINE) +#define MP (PCRE2_MULTILINE | PCRE2_UCP) +#define U (PCRE2_UTF) +#define CM (PCRE2_CASELESS | PCRE2_MULTILINE) + +#define BSR(x) ((x) << 16) +#define A PCRE2_NEWLINE_ANYCRLF + +#define GET_NEWLINE(x) ((x) & 0xffff) +#define GET_BSR(x) ((x) >> 16) + +#define OFFSET_MASK 0x00ffff +#define F_NO8 0x010000 +#define F_NO16 0x020000 +#define F_NO32 0x020000 +#define F_NOMATCH 0x040000 +#define F_DIFF 0x080000 +#define F_FORCECONV 0x100000 +#define F_PROPERTY 0x200000 +#define F_STUDY 0x400000 + +struct regression_test_case { + int compile_options; + int newline; + int match_options; + int start_offset; + const char *pattern; + const char *input; +}; + +static struct regression_test_case regression_test_cases[] = { + /* Constant strings. */ + { MU, A, 0, 0, "AbC", "AbAbC" }, + { MU, A, 0, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" }, + { CMU, A, 0, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" }, + { M, A, 0, 0, "[^a]", "aAbB" }, + { CM, A, 0, 0, "[^m]", "mMnN" }, + { M, A, 0, 0, "a[^b][^#]", "abacd" }, + { CM, A, 0, 0, "A[^B][^E]", "abacd" }, + { CMU, A, 0, 0, "[^x][^#]", "XxBll" }, + { MU, A, 0, 0, "[^a]", "aaa\xc3\xa1#Ab" }, + { CMU, A, 0, 0, "[^A]", "aA\xe6\x92\xad" }, + { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\n+bc" }, + { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\r+bc" }, + { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\r+bc" }, + { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\n+bc" }, + { MU, A, 0, 0, "[axd]", "sAXd" }, + { CMU, A, 0, 0, "[axd]", "sAXd" }, + { CMU, A, 0, 0 | F_NOMATCH, "[^axd]", "DxA" }, + { MU, A, 0, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" }, + { MU, A, 0, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, + { CMU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, + { MU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, + { MU, A, 0, 0, "[^a]", "\xc2\x80[]" }, + { CMU, A, 0, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, + { CM, A, 0, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, + { PCRE2_CASELESS, 0, 0, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, + { PCRE2_CASELESS, 0, 0, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, + { PCRE2_CASELESS, 0, 0, 0, "a1", "Aa1" }, + { M, A, 0, 0, "\\Ca", "cda" }, + { CM, A, 0, 0, "\\Ca", "CDA" }, + { M, A, 0, 0 | F_NOMATCH, "\\Cx", "cda" }, + { CM, A, 0, 0 | F_NOMATCH, "\\Cx", "CDA" }, + { CMUP, A, 0, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUP, A, 0, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUP, A, 0, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUP, A, 0, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + { M, A, 0, 0, "[3-57-9]", "5" }, + + /* Assertions. */ + { MU, A, 0, 0, "\\b[^A]", "A_B#" }, + { M, A, 0, 0 | F_NOMATCH, "\\b\\W", "\n*" }, + { MU, A, 0, 0, "\\B[^,]\\b[^s]\\b", "#X" }, + { MP, A, 0, 0, "\\B", "_\xa1" }, + { MP, A, 0, 0 | F_PROPERTY, "\\b_\\b[,A]\\B", "_," }, + { MUP, A, 0, 0, "\\b", "\xe6\x92\xad!" }, + { MUP, A, 0, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" }, + { MUP, A, 0, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" }, + { MUP, A, 0, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, + { MU, A, 0, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" }, + { CMUP, A, 0, 0, "\\By", "\xf0\x90\x90\xa8y" }, + { M, A, 0, 0 | F_NOMATCH, "\\R^", "\n" }, + { M, A, 0, 1 | F_NOMATCH, "^", "\n" }, + { 0, 0, 0, 0, "^ab", "ab" }, + { 0, 0, 0, 0 | F_NOMATCH, "^ab", "aab" }, + { M, PCRE2_NEWLINE_CRLF, 0, 0, "^a", "\r\raa\n\naa\r\naa" }, + { MU, A, 0, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" }, + { M, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--b--\x85--" }, + { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xe2\x80\xa8--" }, + { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xc2\x85--" }, + { 0, 0, 0, 0, "ab$", "ab" }, + { 0, 0, 0, 0 | F_NOMATCH, "ab$", "abab\n\n" }, + { PCRE2_DOLLAR_ENDONLY, 0, 0, 0 | F_NOMATCH, "ab$", "abab\r\n" }, + { M, PCRE2_NEWLINE_CRLF, 0, 0, "a$", "\r\raa\n\naa\r\naa" }, + { M, PCRE2_NEWLINE_ANY, 0, 0, "a$", "aaa" }, + { MU, PCRE2_NEWLINE_ANYCRLF, 0, 0, "#$", "#\xc2\x85###\r#" }, + { MU, PCRE2_NEWLINE_ANY, 0, 0, "#$", "#\xe2\x80\xa9" }, + { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0 | F_NOMATCH, "^a", "aa\naa" }, + { M, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0, "^a", "aa\naa" }, + { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\naa" }, + { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\r\n" }, + { U | PCRE2_DOLLAR_ENDONLY, PCRE2_NEWLINE_ANY, 0, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" }, + { M, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0, "a$", "aa\naa" }, + { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa" }, + { U, PCRE2_NEWLINE_CR, 0, 0, "a\\Z", "aaa\r" }, + { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa\n" }, + { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r" }, + { U, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\n" }, + { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r\n" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" }, + { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xc2\x85" }, + { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" }, + { M, A, 0, 0, "\\Aa", "aaa" }, + { M, A, 0, 1 | F_NOMATCH, "\\Aa", "aaa" }, + { M, A, 0, 1, "\\Ga", "aaa" }, + { M, A, 0, 1 | F_NOMATCH, "\\Ga", "aba" }, + { M, A, 0, 0, "a\\z", "aaa" }, + { M, A, 0, 0 | F_NOMATCH, "a\\z", "aab" }, + + /* Brackets and alternatives. */ + { MU, A, 0, 0, "(ab|bb|cd)", "bacde" }, + { MU, A, 0, 0, "(?:ab|a)(bc|c)", "ababc" }, + { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" }, + { CMU, A, 0, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" }, + { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" }, + { MU, A, 0, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" }, + { MU, A, 0, 0, "\xc7\x82|\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, + { MU, A, 0, 0, "=\xc7\x82|#\xc6\x82", "\xf1\x83\x82\x82=\xc7\x82\xc7\x83" }, + { MU, A, 0, 0, "\xc7\x82\xc7\x83|\xc6\x82\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, + { MU, A, 0, 0, "\xc6\x82\xc6\x82|\xc7\x83\xc7\x83|\xc8\x84\xc8\x84", "\xf1\x83\x82\x82\xc8\x84\xc8\x84" }, + + /* Greedy and non-greedy ? operators. */ + { MU, A, 0, 0, "(?:a)?a", "laab" }, + { CMU, A, 0, 0, "(A)?A", "llaab" }, + { MU, A, 0, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */ + { MU, A, 0, 0, "(a)?a", "manm" }, + { CMU, A, 0, 0, "(a|b)?\?d((?:e)?)", "ABABdx" }, + { MU, A, 0, 0, "(a|b)?\?d((?:e)?)", "abcde" }, + { MU, A, 0, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" }, + + /* Greedy and non-greedy + operators */ + { MU, A, 0, 0, "(aa)+aa", "aaaaaaa" }, + { MU, A, 0, 0, "(aa)+?aa", "aaaaaaa" }, + { MU, A, 0, 0, "(?:aba|ab|a)+l", "ababamababal" }, + { MU, A, 0, 0, "(?:aba|ab|a)+?l", "ababamababal" }, + { MU, A, 0, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, + { MU, A, 0, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, + { MU, A, 0, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" }, + + /* Greedy and non-greedy * operators */ + { CMU, A, 0, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" }, + { MU, A, 0, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" }, + { MU, A, 0, 0, "(aa|ab)*ab", "aaabaaab" }, + { CMU, A, 0, 0, "(aa|Ab)*?aB", "aaabaaab" }, + { MU, A, 0, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" }, + { MU, A, 0, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" }, + { M, A, 0, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" }, + { M, A, 0, 0, "((?:a|)*){0}a", "a" }, + + /* Combining ? + * operators */ + { MU, A, 0, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" }, + { MU, A, 0, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" }, + { MU, A, 0, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" }, + { MU, A, 0, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" }, + { MU, A, 0, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" }, + + /* Single character iterators. */ + { MU, A, 0, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" }, + { MU, A, 0, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" }, + { MU, A, 0, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" }, + { MU, A, 0, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" }, + { MU, A, 0, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" }, + { MU, A, 0, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" }, + { MU, A, 0, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" }, + { MU, A, 0, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" }, + { MU, A, 0, 0, "(ba{2})+c", "baabaaabacbaabaac" }, + { MU, A, 0, 0, "(a*+bc++)+", "aaabbcaaabcccab" }, + { MU, A, 0, 0, "(a?+[^b])+", "babaacacb" }, + { MU, A, 0, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" }, + { CMU, A, 0, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" }, + { CMU, A, 0, 0, "[c-f]+k", "DemmFke" }, + { MU, A, 0, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" }, + { MU, A, 0, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" }, + { CMU, A, 0, 0, "[ace]{3,7}", "AcbDAcEEcEd" }, + { CMU, A, 0, 0, "[ace]{3,7}?", "AcbDAcEEcEd" }, + { CMU, A, 0, 0, "[ace]{3,}", "AcbDAcEEcEd" }, + { CMU, A, 0, 0, "[ace]{3,}?", "AcbDAcEEcEd" }, + { MU, A, 0, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" }, + { CMU, A, 0, 0, "[ace]{5}?", "AcCebDAcEEcEd" }, + { MU, A, 0, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" }, + { MU, A, 0, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" }, + { MU, A, 0, 0, "\\b\\w+\\B", "x,a_cd" }, + { MUP, A, 0, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, + { CMU, A, 0, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" }, + { CMUP, A, 0, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CMU, A, 0, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" }, + { CMU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, + { MU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, + { MU, A, 0, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" }, + { MU, A, 0, 0, "\\d+123", "987654321,01234" }, + { MU, A, 0, 0, "abcd*|\\w+xy", "aaaaa,abxyz" }, + { MU, A, 0, 0, "(?:abc|((?:amc|\\b\\w*xy)))", "aaaaa,abxyz" }, + { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.abcd#."}, + { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.mbcd#."}, + { MU, A, 0, 0, ".[ab]*.", "xx" }, + { MU, A, 0, 0, ".[ab]*a", "xxa" }, + { MU, A, 0, 0, ".[ab]?.", "xx" }, + + /* Bracket repeats with limit. */ + { MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" }, + { MU, A, 0, 0, "(?:ab|abab){1,5}M", "abababababababababababM" }, + { MU, A, 0, 0, "(?>ab|abab){1,5}M", "abababababababababababM" }, + { MU, A, 0, 0, "(?:ab|abab){1,5}?M", "abababababababababababM" }, + { MU, A, 0, 0, "(?>ab|abab){1,5}?M", "abababababababababababM" }, + { MU, A, 0, 0, "(?:(ab){1,4}?){1,3}?M", "abababababababababababababM" }, + { MU, A, 0, 0, "(?:(ab){1,4}){1,3}abababababababababababM", "ababababababababababababM" }, + { MU, A, 0, 0 | F_NOMATCH, "(?:(ab){1,4}){1,3}abababababababababababM", "abababababababababababM" }, + { MU, A, 0, 0, "(ab){4,6}?M", "abababababababM" }, + + /* Basic character sets. */ + { MU, A, 0, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " }, + { MU, A, 0, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" }, + { MU, A, 0, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" }, + { MU, A, 0, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" }, + { MU, A, 0, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" }, + { MU, A, 0, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" }, + { MU, A, 0, 0, "x[bcef]+", "xaxdxecbfg" }, + { MU, A, 0, 0, "x[bcdghij]+", "xaxexfxdgbjk" }, + { MU, A, 0, 0, "x[^befg]+", "xbxexacdhg" }, + { MU, A, 0, 0, "x[^bcdl]+", "xlxbxaekmd" }, + { MU, A, 0, 0, "x[^bcdghi]+", "xbxdxgxaefji" }, + { MU, A, 0, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" }, + { CMU, A, 0, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" }, + { CMU, A, 0, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" }, + { MU, A, 0, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" }, + { MU, A, 0, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" }, + { MU, A, 0, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" }, + { MU, A, 0, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" }, + { MU, A, 0, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" }, + { MU, A, 0, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" }, + { MU, A, 0, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" }, + { MU, A, 0, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" }, + + /* Unicode properties. */ + { MUP, A, 0, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" }, + { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" }, + { MUP, A, 0, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, + { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, + { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, + { MUP, A, 0, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, + { MUP, A, 0, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" }, + { CMUP, A, 0, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" }, + { MUP, A, 0, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" }, + { MUP, A, 0, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" }, + { MU, A, 0, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" }, + { CMUP, A, 0, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" }, + { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" }, + { MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" }, + { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB baaa" }, + + /* Possible empty brackets. */ + { MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" }, + { MU, A, 0, 0, "(|ab||bc|a)+d", "abcxabcabd" }, + { MU, A, 0, 0, "(?:|ab||bc|a)*d", "abcxabcabd" }, + { MU, A, 0, 0, "(|ab||bc|a)*d", "abcxabcabd" }, + { MU, A, 0, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" }, + { MU, A, 0, 0, "(|ab||bc|a)+?d", "abcxabcabd" }, + { MU, A, 0, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" }, + { MU, A, 0, 0, "(|ab||bc|a)*?d", "abcxabcabd" }, + { MU, A, 0, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" }, + { MU, A, 0, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" }, + + /* Start offset. */ + { MU, A, 0, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" }, + { MU, A, 0, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, + { MU, A, 0, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, + { MU, A, 0, 1, "(\\w\\W\\w)+", "ab#d" }, + + /* Newline. */ + { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, + { M, PCRE2_NEWLINE_CR, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, + { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{1,3}[^#]", "\r\n##...." }, + { MU, A, PCRE2_NO_UTF_CHECK, 1, "^.a", "\n\x80\nxa" }, + { MU, A, 0, 1, "^", "\r\n" }, + { M, PCRE2_NEWLINE_CRLF, 0, 1 | F_NOMATCH, "^", "\r\n" }, + { M, PCRE2_NEWLINE_CRLF, 0, 1, "^", "\r\na" }, + + /* Any character except newline or any newline. */ + { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" }, + { U, PCRE2_NEWLINE_CRLF, 0, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" }, + { 0, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, + { U, PCRE2_NEWLINE_ANY, 0, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" }, + { U, PCRE2_NEWLINE_ANYCRLF, 0, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" }, + { 0, PCRE2_NEWLINE_ANY, 0, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" }, + { U, PCRE2_NEWLINE_ANY, 0, 0, "(.+)#", "#\rMn\xc2\x85#\n###" }, + { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\r" }, + { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\x85#\r\n#" }, + { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\xe2\x80\xa8#c" }, + { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\r\nc" }, + { U, PCRE2_NEWLINE_CRLF | BSR(PCRE2_BSR_UNICODE), 0, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" }, + { MU, A, 0, 0 | F_NOMATCH, "\\R+", "ab" }, + { MU, A, 0, 0, "\\R+", "ab\r\n\r" }, + { MU, A, 0, 0, "\\R*", "ab\r\n\r" }, + { MU, A, 0, 0, "\\R*", "\r\n\r" }, + { MU, A, 0, 0, "\\R{2,4}", "\r\nab\r\r" }, + { MU, A, 0, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" }, + { MU, A, 0, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" }, + { MU, A, 0, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" }, + { MU, A, 0, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" }, + { MU, A, 0, 0, "\\R+\\R\\R", "\r\r\r" }, + { MU, A, 0, 0, "\\R*\\R\\R", "\n\r" }, + { MU, A, 0, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" }, + { MU, A, 0, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" }, + + /* Atomic groups (no fallback from "next" direction). */ + { MU, A, 0, 0 | F_NOMATCH, "(?>ab)ab", "bab" }, + { MU, A, 0, 0 | F_NOMATCH, "(?>(ab))ab", "bab" }, + { MU, A, 0, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op", + "bababcdedefgheijijklmlmnop" }, + { MU, A, 0, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" }, + { MU, A, 0, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" }, + { MU, A, 0, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" }, + { MU, A, 0, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" }, + { MU, A, 0, 0, "((?>a|)+?)b", "aaacaaab" }, + { MU, A, 0, 0, "(?>x|)*$", "aaa" }, + { MU, A, 0, 0, "(?>(x)|)*$", "aaa" }, + { MU, A, 0, 0, "(?>x|())*$", "aaa" }, + { MU, A, 0, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" }, + { MU, A, 0, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" }, + { MU, A, 0, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" }, + { MU, A, 0, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" }, + { MU, A, 0, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" }, + { MU, A, 0, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" }, + { MU, A, 0, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" }, + { MU, A, 0, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" }, + { MU, A, 0, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" }, + { MU, A, 0, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" }, + { MU, A, 0, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" }, + { MU, A, 0, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" }, + { MU, A, 0, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" }, + { MU, A, 0, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" }, + { CM, A, 0, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" }, + { MU, A, 0, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, + { MU, A, 0, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" }, + { MU, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" }, + { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" }, + { MU, A, 0, 0, "(c(ab)?+ab)+", "cabcababcab" }, + { MU, A, 0, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, + + /* Possessive quantifiers. */ + { MU, A, 0, 0, "(?:a|b)++m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, + { MU, A, 0, 0, "(a|b)++m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(a|b)*+m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(a|b)*+m", "ababbaaxababbaam" }, + { MU, A, 0, 0, "(a|b(*ACCEPT))++m", "maaxab" }, + { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, + { MU, A, 0, 0, "(a|(b))++m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "((a)|b)*+m", "mababbaaxababbaam" }, + { MU, A, 0, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, + { MU, A, 0, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, + { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxm" }, + { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxbbm" }, + { MU, A, 0, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" }, + { MU, A, 0, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" }, + { MU, A, 0, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" }, + { MU, A, 0, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, + { MU, A, 0, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, + + /* Back references. */ + { MU, A, 0, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" }, + { CMU, A, 0, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" }, + { CM, A, 0, 0, "(a{2,4})\\1", "AaAaaAaA" }, + { MU, A, 0, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" }, + { MU, A, 0, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" }, + { MU, A, 0, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, + { MU, A, 0, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, + { MU, A, 0, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" }, + { MU, A, 0, 0, "(?:(aa)|b)\\1?b", "bb" }, + { CMU, A, 0, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" }, + { MU, A, 0, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" }, + { CMU, A, 0, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" }, + { MU, A, 0, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, + { CM, A, 0, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, + { MU, A, 0, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" }, + { MU, A, 0, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" }, + { M, A, 0, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" }, + { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, + { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." }, + { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" }, + { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" }, + { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, + { CMUP, A, 0, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" }, + { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k{1,3}(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k{1,3}(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k*(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?aa)(?bb)\\k{0,3}aaaaaa", "aabbaaaaaa" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?aa)(?bb)\\k{2,5}bb", "aabbaaaabb" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{0,3}m", "aaaaaaaabbbbaabbbbm" }, + { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k{1,3}?(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k{1,3}?(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "\\k*?(?aa)(?bb)", "aabb" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{0,3}?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k*?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, + { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{0,3}M", "aaaaaaaabbbbaabbbbm" }, + { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{1,3}M", "aaaaaaaabbbbaabbbbm" }, + { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{0,3}?M", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, + + /* Assertions. */ + { MU, A, 0, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" }, + { MU, A, 0, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" }, + { MU, A, 0, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" }, + { MU, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" }, + { MU, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" }, + { M, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" }, + { M, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" }, + { MU, A, 0, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" }, + { MU, A, 0, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" }, + { MU, A, 0, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" }, + { MU, A, 0, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" }, + { MU, A, 0, 0, "((?(?=(a))a)+k)", "bbak" }, + { MU, A, 0, 0, "((?(?=a)a)+k)", "bbak" }, + { MU, A, 0, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" }, + { MU, A, 0, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" }, + { MU, A, 0, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" }, + { MU, A, 0, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" }, + { MU, A, 0, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" }, + { MU, A, 0, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, + { MU, A, 0, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, + { MU, A, 0, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" }, + { MU, A, 0, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" }, + { MU, A, 0, 0, "((?!a)?(?!([^a]))?)+$", "acbab" }, + { MU, A, 0, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" }, + { MU, A, 0, 0, "a(?=(?C)\\B(?C`x`))b", "ab" }, + { MU, A, 0, 0, "a(?!(?C)\\B(?C`x`))bb|ab", "abb" }, + { MU, A, 0, 0, "a(?=\\b|(?C)\\B(?C`x`))b", "ab" }, + { MU, A, 0, 0, "a(?!\\b|(?C)\\B(?C`x`))bb|ab", "abb" }, + { MU, A, 0, 0, "c(?(?=(?C)\\B(?C`x`))ab|a)", "cab" }, + { MU, A, 0, 0, "c(?(?!(?C)\\B(?C`x`))ab|a)", "cab" }, + { MU, A, 0, 0, "c(?(?=\\b|(?C)\\B(?C`x`))ab|a)", "cab" }, + { MU, A, 0, 0, "c(?(?!\\b|(?C)\\B(?C`x`))ab|a)", "cab" }, + { MU, A, 0, 0, "a(?=)b", "ab" }, + { MU, A, 0, 0 | F_NOMATCH, "a(?!)b", "ab" }, + + /* Not empty, ACCEPT, FAIL */ + { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" }, + { MU, A, PCRE2_NOTEMPTY, 0, "a*", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY, 0, "a*?", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*", "bcaad" }, + { MU, A, 0, 0, "a(*ACCEPT)b", "ab" }, + { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" }, + { MU, A, PCRE2_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" }, + { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" }, + { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" }, + { MU, A, PCRE2_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" }, + { MU, A, 0, 0, "((a(*ACCEPT)b))", "ab" }, + { MU, A, 0, 0, "(a(*FAIL)a|a)", "aaa" }, + { MU, A, 0, 0, "(?=ab(*ACCEPT)b)a", "ab" }, + { MU, A, 0, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" }, + { MU, A, 0, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" }, + { MU, A, PCRE2_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" }, + + /* Conditional blocks. */ + { MU, A, 0, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, + { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, + { MU, A, 0, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, + { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, + { MU, A, 0, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" }, + { MU, A, 0, 0, "(?(?=a)ab)", "a" }, + { MU, A, 0, 0, "(?(?a)?(?Pb)?(?(Name)c|d)*l", "bc ddd abccabccl" }, + { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" }, + { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" }, + { MU, A, 0, 0, "((?:a|aa)(?(1)aaa))x", "aax" }, + { MU, A, 0, 0, "(?(?!)a|b)", "ab" }, + { MU, A, 0, 0, "(?(?!)a)", "ab" }, + { MU, A, 0, 0 | F_NOMATCH, "(?(?!)a|b)", "ac" }, + + /* Set start of match. */ + { MU, A, 0, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, + { MU, A, 0, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, + { MU, A, 0, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, + { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" }, + { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" }, + + /* First line. */ + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0, "(?<=a)", "a" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[^a][^b]", "ab" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "a", "\na" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[abc]", "\na" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^a", "\na" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^(?<=\n)", "\na" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0, "\xf0\x90\x90\x80", "\xf0\x90\x90\x80" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\xc2\x85#" }, + { M | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\x85#" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_PROPERTY, "\\p{Any}", "\r\na" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, "a", "\ra" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH, "ba", "bbb\r\nba" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" }, + { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 1, ".", "\r\n" }, + { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_LF, 0, 0 | F_NOMATCH, "ab.", "ab" }, + { MU | PCRE2_FIRSTLINE, A, 0, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" }, + { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_ANY, 0, 0, "....a", "012\n0a" }, + + /* Recurse. */ + { MU, A, 0, 0, "(a)(?1)", "aa" }, + { MU, A, 0, 0, "((a))(?1)", "aa" }, + { MU, A, 0, 0, "(b|a)(?1)", "aa" }, + { MU, A, 0, 0, "(b|(a))(?1)", "aa" }, + { MU, A, 0, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" }, + { MU, A, 0, 0, "((a)(b)(?:a*))(?1)", "abab" }, + { MU, A, 0, 0, "((a+)c(?2))b(?1)", "aacaabaca" }, + { MU, A, 0, 0, "((?2)b|(a)){2}(?1)", "aabab" }, + { MU, A, 0, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" }, + { MU, A, 0, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" }, + { MU, A, 0, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" }, + { MU, A, 0, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" }, + { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" }, + { MU, A, 0, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" }, + { MU, A, 0, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" }, + { MU, A, 0, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" }, + { MU, A, 0, 0, "b|<(?R)*>", "<" }, + { MU, A, 0, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" }, + { MU, A, 0, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" }, + { MU, A, 0, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" }, + { MU, A, 0, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" }, + { MU, A, 0, 0, "(a)((?(R1)a|b))(?2)", "ababba" }, + { MU, A, 0, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" }, + { MU, A, 0, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" }, + { MU, A, 0, 0, "(?Pa(?(R&Name)a|b))(?1)", "aab abb abaa" }, + { MU, A, 0, 0, "((?(R)a|(?1)){3})", "XaaaaaaaaaX" }, + { MU, A, 0, 0, "((?:(?(R)a|(?1))){3})", "XaaaaaaaaaX" }, + { MU, A, 0, 0, "((?(R)a|(?1)){1,3})aaaaaa", "aaaaaaaaXaaaaaaaaa" }, + { MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" }, + + /* 16 bit specific tests. */ + { CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" }, + { CM, A, 0, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CM, A, 0, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" }, + { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" }, + { CM, A, 0, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" }, + { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" }, + { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" }, + { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" }, + { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" }, + { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" }, + { M, A, 0, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, + { M, A, 0, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, + { CM, A, 0, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" }, + { CM, A, 0, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" }, + { CM, A, 0, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" }, + { CM, A, 0, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" }, + { CM | PCRE2_EXTENDED, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" }, + { CM, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" }, + { CM, A, 0, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" }, + { M, PCRE2_NEWLINE_ANY, 0, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" }, + { 0, BSR(PCRE2_BSR_UNICODE), 0, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" }, + { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" }, + { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" }, + { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" }, + { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" }, + + /* Partial matching. */ + { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab", "a" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab|a", "a" }, + { MU, A, PCRE2_PARTIAL_HARD, 0, "ab|a", "a" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "\\b#", "a" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "(?<=a)b", "a" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "a\\B", "a" }, + { MU, A, PCRE2_PARTIAL_HARD, 0, "a\\b", "a" }, + + /* (*MARK) verb. */ + { MU, A, 0, 0, "a(*MARK:aa)a", "ababaa" }, + { MU, A, 0, 0 | F_NOMATCH, "a(*:aa)a", "abab" }, + { MU, A, 0, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" }, + { MU, A, 0, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" }, + { MU, A, 0, 0, "(?>a(*:aa))b|ac", "ac" }, + { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" }, + { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" }, + { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" }, + { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, + { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" }, + { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, + { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" }, + { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(*:mark)m", "a" }, + + /* (*COMMIT) verb. */ + { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" }, + { MU, A, 0, 0, "aa(*COMMIT)b", "xaxaab" }, + { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" }, + { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b)++", "abac" }, + { MU, A, 0, 0 | F_NOMATCH, "((a)(*COMMIT)b)++", "abac" }, + { MU, A, 0, 0 | F_NOMATCH, "(?=a(*COMMIT)b)ab|ad", "ad" }, + + /* (*PRUNE) verb. */ + { MU, A, 0, 0, "aa\\K(*PRUNE)b", "aaab" }, + { MU, A, 0, 0, "aa(*PRUNE:bb)b|a", "aa" }, + { MU, A, 0, 0, "(a)(a)(*PRUNE)b|(a)", "aa" }, + { MU, A, 0, 0, "(a)(a)(a)(a)(a)(a)(a)(a)(*PRUNE)b|(a)", "aaaaaaaa" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|", "a" }, + { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|m", "a" }, + { MU, A, 0, 0 | F_NOMATCH, "(?=a(*PRUNE)b)ab|ad", "ad" }, + { MU, A, 0, 0, "a(*COMMIT)(*PRUNE)d|bc", "abc" }, + { MU, A, 0, 0, "(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0, "(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0, "(a(*COMMIT)b){0}a(?1)(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b){0}a(*COMMIT)(?1)(*PRUNE)c|bc", "abc" }, + { MU, A, 0, 0, "(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MU, A, 0, 0, "((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, + { MU, A, 0, 0, "(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, + { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, + + /* (*SKIP) verb. */ + { MU, A, 0, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" }, + { MU, A, 0, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," }, + { MU, A, 0, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," }, + { MU, A, 0, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" }, + + /* (*THEN) verb. */ + { MU, A, 0, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" }, + { MU, A, 0, 0 | F_NOMATCH, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcm" }, + { MU, A, 0, 0, "((?:a(*THEN)|aab)c|a+)+m", "aabcaabcnmaabcaabcm" }, + { MU, A, 0, 0, "((?:a|aab)(*THEN)c|a+)+m", "aam" }, + { MU, A, 0, 0, "((?:a(*COMMIT)|aab)(*THEN)c|a+)+m", "aam" }, + { MU, A, 0, 0, "(?(?=a(*THEN)b)ab|ad)", "ad" }, + { MU, A, 0, 0, "(?(?!a(*THEN)b)ad|add)", "add" }, + { MU, A, 0, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" }, + { MU, A, 0, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" }, + + /* Deep recursion. */ + { MU, A, 0, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, + { MU, A, 0, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " }, + { MU, A, 0, 0, "((a?)+)+b", "aaaaaaaaaaaa b" }, + + /* Deep recursion: Stack limit reached. */ + { M, A, 0, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" }, + { M, A, 0, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { M, A, 0, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { M, A, 0, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { M, A, 0, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + + { 0, 0, 0, 0, NULL, NULL } +}; + +#ifdef SUPPORT_PCRE2_8 +static pcre2_jit_stack_8* callback8(void *arg) +{ + return (pcre2_jit_stack_8 *)arg; +} +#endif + +#ifdef SUPPORT_PCRE2_16 +static pcre2_jit_stack_16* callback16(void *arg) +{ + return (pcre2_jit_stack_16 *)arg; +} +#endif + +#ifdef SUPPORT_PCRE2_32 +static pcre2_jit_stack_32* callback32(void *arg) +{ + return (pcre2_jit_stack_32 *)arg; +} +#endif + +#ifdef SUPPORT_PCRE2_8 +static pcre2_jit_stack_8 *stack8; + +static pcre2_jit_stack_8 *getstack8(void) +{ + if (!stack8) + stack8 = pcre2_jit_stack_create_8(1, 1024 * 1024, NULL); + return stack8; +} + +static void setstack8(pcre2_match_context_8 *mcontext) +{ + if (!mcontext) { + if (stack8) + pcre2_jit_stack_free_8(stack8); + stack8 = NULL; + return; + } + + pcre2_jit_stack_assign_8(mcontext, callback8, getstack8()); +} +#endif /* SUPPORT_PCRE2_8 */ + +#ifdef SUPPORT_PCRE2_16 +static pcre2_jit_stack_16 *stack16; + +static pcre2_jit_stack_16 *getstack16(void) +{ + if (!stack16) + stack16 = pcre2_jit_stack_create_16(1, 1024 * 1024, NULL); + return stack16; +} + +static void setstack16(pcre2_match_context_16 *mcontext) +{ + if (!mcontext) { + if (stack16) + pcre2_jit_stack_free_16(stack16); + stack16 = NULL; + return; + } + + pcre2_jit_stack_assign_16(mcontext, callback16, getstack16()); +} +#endif /* SUPPORT_PCRE2_16 */ + +#ifdef SUPPORT_PCRE2_32 +static pcre2_jit_stack_32 *stack32; + +static pcre2_jit_stack_32 *getstack32(void) +{ + if (!stack32) + stack32 = pcre2_jit_stack_create_32(1, 1024 * 1024, NULL); + return stack32; +} + +static void setstack32(pcre2_match_context_32 *mcontext) +{ + if (!mcontext) { + if (stack32) + pcre2_jit_stack_free_32(stack32); + stack32 = NULL; + return; + } + + pcre2_jit_stack_assign_32(mcontext, callback32, getstack32()); +} +#endif /* SUPPORT_PCRE2_32 */ + +#ifdef SUPPORT_PCRE2_16 + +static int convert_utf8_to_utf16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int *offsetmap, int max_length) +{ + PCRE2_SPTR8 iptr = input; + PCRE2_UCHAR16 *optr = output; + unsigned int c; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + c = 0; + if (offsetmap) + *offsetmap++ = (int)(iptr - (unsigned char*)input); + + if (*iptr < 0xc0) + c = *iptr++; + else if (!(*iptr & 0x20)) { + c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); + iptr += 2; + } else if (!(*iptr & 0x10)) { + c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); + iptr += 3; + } else if (!(*iptr & 0x08)) { + c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); + iptr += 4; + } + + if (c < 65536) { + *optr++ = c; + max_length--; + } else if (max_length <= 2) { + *optr = '\0'; + return (int)(optr - output); + } else { + c -= 0x10000; + *optr++ = 0xd800 | ((c >> 10) & 0x3ff); + *optr++ = 0xdc00 | (c & 0x3ff); + max_length -= 2; + if (offsetmap) + offsetmap++; + } + } + if (offsetmap) + *offsetmap = (int)(iptr - (unsigned char*)input); + *optr = '\0'; + return (int)(optr - output); +} + +static int copy_char8_to_char16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int max_length) +{ + PCRE2_SPTR8 iptr = input; + PCRE2_UCHAR16 *optr = output; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + *optr++ = *iptr++; + max_length--; + } + *optr = '\0'; + return (int)(optr - output); +} + +#define REGTEST_MAX_LENGTH16 4096 +static PCRE2_UCHAR16 regtest_buf16[REGTEST_MAX_LENGTH16]; +static int regtest_offsetmap16[REGTEST_MAX_LENGTH16]; + +#endif /* SUPPORT_PCRE2_16 */ + +#ifdef SUPPORT_PCRE2_32 + +static int convert_utf8_to_utf32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int *offsetmap, int max_length) +{ + PCRE2_SPTR8 iptr = input; + PCRE2_UCHAR32 *optr = output; + unsigned int c; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + c = 0; + if (offsetmap) + *offsetmap++ = (int)(iptr - (unsigned char*)input); + + if (*iptr < 0xc0) + c = *iptr++; + else if (!(*iptr & 0x20)) { + c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); + iptr += 2; + } else if (!(*iptr & 0x10)) { + c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); + iptr += 3; + } else if (!(*iptr & 0x08)) { + c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); + iptr += 4; + } + + *optr++ = c; + max_length--; + } + if (offsetmap) + *offsetmap = (int)(iptr - (unsigned char*)input); + *optr = 0; + return (int)(optr - output); +} + +static int copy_char8_to_char32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int max_length) +{ + PCRE2_SPTR8 iptr = input; + PCRE2_UCHAR32 *optr = output; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + *optr++ = *iptr++; + max_length--; + } + *optr = '\0'; + return (int)(optr - output); +} + +#define REGTEST_MAX_LENGTH32 4096 +static PCRE2_UCHAR32 regtest_buf32[REGTEST_MAX_LENGTH32]; +static int regtest_offsetmap32[REGTEST_MAX_LENGTH32]; + +#endif /* SUPPORT_PCRE2_32 */ + +static int check_ascii(const char *input) +{ + const unsigned char *ptr = (unsigned char *)input; + while (*ptr) { + if (*ptr > 127) + return 0; + ptr++; + } + return 1; +} + +#define OVECTOR_SIZE 15 + +static int regression_tests(void) +{ + struct regression_test_case *current = regression_test_cases; + int error; + PCRE2_SIZE err_offs; + int is_successful; + int is_ascii; + int total = 0; + int successful = 0; + int successful_row = 0; + int counter = 0; + int jit_compile_mode; + int utf = 0; + int disabled_options = 0; + int i; +#ifdef SUPPORT_PCRE2_8 + pcre2_code_8 *re8; + pcre2_compile_context_8 *ccontext8; + pcre2_match_data_8 *mdata8_1; + pcre2_match_data_8 *mdata8_2; + pcre2_match_context_8 *mcontext8; + PCRE2_SIZE *ovector8_1 = NULL; + PCRE2_SIZE *ovector8_2 = NULL; + int return_value8[2]; +#endif +#ifdef SUPPORT_PCRE2_16 + pcre2_code_16 *re16; + pcre2_compile_context_16 *ccontext16; + pcre2_match_data_16 *mdata16_1; + pcre2_match_data_16 *mdata16_2; + pcre2_match_context_16 *mcontext16; + PCRE2_SIZE *ovector16_1 = NULL; + PCRE2_SIZE *ovector16_2 = NULL; + int return_value16[2]; + int length16; +#endif +#ifdef SUPPORT_PCRE2_32 + pcre2_code_32 *re32; + pcre2_compile_context_32 *ccontext32; + pcre2_match_data_32 *mdata32_1; + pcre2_match_data_32 *mdata32_2; + pcre2_match_context_32 *mcontext32; + PCRE2_SIZE *ovector32_1 = NULL; + PCRE2_SIZE *ovector32_2 = NULL; + int return_value32[2]; + int length32; +#endif + +#if defined SUPPORT_PCRE2_8 + PCRE2_UCHAR8 cpu_info[128]; +#elif defined SUPPORT_PCRE2_16 + PCRE2_UCHAR16 cpu_info[128]; +#elif defined SUPPORT_PCRE2_32 + PCRE2_UCHAR32 cpu_info[128]; +#endif +#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2) + int return_value; +#endif + + /* This test compares the behaviour of interpreter and JIT. Although disabling + utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is + still considered successful from pcre_jit_test point of view. */ + +#if defined SUPPORT_PCRE2_8 + pcre2_config_8(PCRE2_CONFIG_JITTARGET, &cpu_info); +#elif defined SUPPORT_PCRE2_16 + pcre2_config_16(PCRE2_CONFIG_JITTARGET, &cpu_info); +#elif defined SUPPORT_PCRE2_32 + pcre2_config_32(PCRE2_CONFIG_JITTARGET, &cpu_info); +#endif + + printf("Running JIT regression tests\n"); + printf(" target CPU of SLJIT compiler: "); + for (i = 0; cpu_info[i]; i++) + printf("%c", (char)(cpu_info[i])); + printf("\n"); + +#if defined SUPPORT_PCRE2_8 + pcre2_config_8(PCRE2_CONFIG_UNICODE, &utf); +#elif defined SUPPORT_PCRE2_16 + pcre2_config_16(PCRE2_CONFIG_UNICODE, &utf); +#elif defined SUPPORT_PCRE2_32 + pcre2_config_32(PCRE2_CONFIG_UNICODE, &utf); +#endif + + if (!utf) + disabled_options |= PCRE2_UTF; +#ifdef SUPPORT_PCRE2_8 + printf(" in 8 bit mode with UTF-8 %s:\n", utf ? "enabled" : "disabled"); +#endif +#ifdef SUPPORT_PCRE2_16 + printf(" in 16 bit mode with UTF-16 %s:\n", utf ? "enabled" : "disabled"); +#endif +#ifdef SUPPORT_PCRE2_32 + printf(" in 32 bit mode with UTF-32 %s:\n", utf ? "enabled" : "disabled"); +#endif + + while (current->pattern) { + /* printf("\nPattern: %s :\n", current->pattern); */ + total++; + is_ascii = 0; + if (!(current->start_offset & F_PROPERTY)) + is_ascii = check_ascii(current->pattern) && check_ascii(current->input); + + if (current->match_options & PCRE2_PARTIAL_SOFT) + jit_compile_mode = PCRE2_JIT_PARTIAL_SOFT; + else if (current->match_options & PCRE2_PARTIAL_HARD) + jit_compile_mode = PCRE2_JIT_PARTIAL_HARD; + else + jit_compile_mode = PCRE2_JIT_COMPLETE; + error = 0; +#ifdef SUPPORT_PCRE2_8 + re8 = NULL; + ccontext8 = pcre2_compile_context_create_8(NULL); + if (ccontext8) { + if (GET_NEWLINE(current->newline)) + pcre2_set_newline_8(ccontext8, GET_NEWLINE(current->newline)); + if (GET_BSR(current->newline)) + pcre2_set_bsr_8(ccontext8, GET_BSR(current->newline)); + + if (!(current->start_offset & F_NO8)) { + re8 = pcre2_compile_8((PCRE2_SPTR8)current->pattern, PCRE2_ZERO_TERMINATED, + current->compile_options & ~disabled_options, + &error, &err_offs, ccontext8); + + if (!re8 && (utf || is_ascii)) + printf("\n8 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); + } + pcre2_compile_context_free_8(ccontext8); + } + else + printf("\n8 bit: Cannot allocate compile context\n"); +#endif +#ifdef SUPPORT_PCRE2_16 + if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) + convert_utf8_to_utf16((PCRE2_SPTR8)current->pattern, regtest_buf16, NULL, REGTEST_MAX_LENGTH16); + else + copy_char8_to_char16((PCRE2_SPTR8)current->pattern, regtest_buf16, REGTEST_MAX_LENGTH16); + + re16 = NULL; + ccontext16 = pcre2_compile_context_create_16(NULL); + if (ccontext16) { + if (GET_NEWLINE(current->newline)) + pcre2_set_newline_16(ccontext16, GET_NEWLINE(current->newline)); + if (GET_BSR(current->newline)) + pcre2_set_bsr_16(ccontext16, GET_BSR(current->newline)); + + if (!(current->start_offset & F_NO16)) { + re16 = pcre2_compile_16(regtest_buf16, PCRE2_ZERO_TERMINATED, + current->compile_options & ~disabled_options, + &error, &err_offs, ccontext16); + + if (!re16 && (utf || is_ascii)) + printf("\n16 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); + } + pcre2_compile_context_free_16(ccontext16); + } + else + printf("\n16 bit: Cannot allocate compile context\n"); +#endif +#ifdef SUPPORT_PCRE2_32 + if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) + convert_utf8_to_utf32((PCRE2_SPTR8)current->pattern, regtest_buf32, NULL, REGTEST_MAX_LENGTH32); + else + copy_char8_to_char32((PCRE2_SPTR8)current->pattern, regtest_buf32, REGTEST_MAX_LENGTH32); + + re32 = NULL; + ccontext32 = pcre2_compile_context_create_32(NULL); + if (ccontext32) { + if (GET_NEWLINE(current->newline)) + pcre2_set_newline_32(ccontext32, GET_NEWLINE(current->newline)); + if (GET_BSR(current->newline)) + pcre2_set_bsr_32(ccontext32, GET_BSR(current->newline)); + + if (!(current->start_offset & F_NO32)) { + re32 = pcre2_compile_32(regtest_buf32, PCRE2_ZERO_TERMINATED, + current->compile_options & ~disabled_options, + &error, &err_offs, ccontext32); + + if (!re32 && (utf || is_ascii)) + printf("\n32 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); + } + pcre2_compile_context_free_32(ccontext32); + } + else + printf("\n32 bit: Cannot allocate compile context\n"); +#endif + + counter++; + if ((counter & 0x3) != 0) { +#ifdef SUPPORT_PCRE2_8 + setstack8(NULL); +#endif +#ifdef SUPPORT_PCRE2_16 + setstack16(NULL); +#endif +#ifdef SUPPORT_PCRE2_32 + setstack32(NULL); +#endif + } + +#ifdef SUPPORT_PCRE2_8 + return_value8[0] = -1000; + return_value8[1] = -1000; + mdata8_1 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL); + mdata8_2 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL); + mcontext8 = pcre2_match_context_create_8(NULL); + if (!mdata8_1 || !mdata8_2 || !mcontext8) { + printf("\n8 bit: Cannot allocate match data\n"); + pcre2_match_data_free_8(mdata8_1); + pcre2_match_data_free_8(mdata8_2); + pcre2_match_context_free_8(mcontext8); + pcre2_code_free_8(re8); + re8 = NULL; + } else { + ovector8_1 = pcre2_get_ovector_pointer_8(mdata8_1); + ovector8_2 = pcre2_get_ovector_pointer_8(mdata8_2); + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector8_1[i] = -2; + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector8_2[i] = -2; + } + if (re8) { + return_value8[1] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), + current->start_offset & OFFSET_MASK, current->match_options, mdata8_2, NULL); + + if (pcre2_jit_compile_8(re8, jit_compile_mode)) { + printf("\n8 bit: JIT compiler does not support \"%s\"\n", current->pattern); + } else if ((counter & 0x1) != 0) { + setstack8(mcontext8); + return_value8[0] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), + current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8); + } else { + pcre2_jit_stack_assign_8(mcontext8, NULL, getstack8()); + return_value8[0] = pcre2_jit_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), + current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8); + } + } +#endif + +#ifdef SUPPORT_PCRE2_16 + return_value16[0] = -1000; + return_value16[1] = -1000; + mdata16_1 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL); + mdata16_2 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL); + mcontext16 = pcre2_match_context_create_16(NULL); + if (!mdata16_1 || !mdata16_2 || !mcontext16) { + printf("\n16 bit: Cannot allocate match data\n"); + pcre2_match_data_free_16(mdata16_1); + pcre2_match_data_free_16(mdata16_2); + pcre2_match_context_free_16(mcontext16); + pcre2_code_free_16(re16); + re16 = NULL; + } else { + ovector16_1 = pcre2_get_ovector_pointer_16(mdata16_1); + ovector16_2 = pcre2_get_ovector_pointer_16(mdata16_2); + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector16_1[i] = -2; + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector16_2[i] = -2; + } + if (re16) { + if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) + length16 = convert_utf8_to_utf16((PCRE2_SPTR8)current->input, regtest_buf16, regtest_offsetmap16, REGTEST_MAX_LENGTH16); + else + length16 = copy_char8_to_char16((PCRE2_SPTR8)current->input, regtest_buf16, REGTEST_MAX_LENGTH16); + + return_value16[1] = pcre2_match_16(re16, regtest_buf16, length16, + current->start_offset & OFFSET_MASK, current->match_options, mdata16_2, NULL); + + if (pcre2_jit_compile_16(re16, jit_compile_mode)) { + printf("\n16 bit: JIT compiler does not support \"%s\"\n", current->pattern); + } else if ((counter & 0x1) != 0) { + setstack16(mcontext16); + return_value16[0] = pcre2_match_16(re16, regtest_buf16, length16, + current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16); + } else { + pcre2_jit_stack_assign_16(mcontext16, NULL, getstack16()); + return_value16[0] = pcre2_jit_match_16(re16, regtest_buf16, length16, + current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16); + } + } +#endif + +#ifdef SUPPORT_PCRE2_32 + return_value32[0] = -1000; + return_value32[1] = -1000; + mdata32_1 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL); + mdata32_2 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL); + mcontext32 = pcre2_match_context_create_32(NULL); + if (!mdata32_1 || !mdata32_2 || !mcontext32) { + printf("\n32 bit: Cannot allocate match data\n"); + pcre2_match_data_free_32(mdata32_1); + pcre2_match_data_free_32(mdata32_2); + pcre2_match_context_free_32(mcontext32); + pcre2_code_free_32(re32); + re32 = NULL; + } else { + ovector32_1 = pcre2_get_ovector_pointer_32(mdata32_1); + ovector32_2 = pcre2_get_ovector_pointer_32(mdata32_2); + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector32_1[i] = -2; + for (i = 0; i < OVECTOR_SIZE * 3; ++i) + ovector32_2[i] = -2; + } + if (re32) { + if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) + length32 = convert_utf8_to_utf32((PCRE2_SPTR8)current->input, regtest_buf32, regtest_offsetmap32, REGTEST_MAX_LENGTH32); + else + length32 = copy_char8_to_char32((PCRE2_SPTR8)current->input, regtest_buf32, REGTEST_MAX_LENGTH32); + + return_value32[1] = pcre2_match_32(re32, regtest_buf32, length32, + current->start_offset & OFFSET_MASK, current->match_options, mdata32_2, NULL); + + if (pcre2_jit_compile_32(re32, jit_compile_mode)) { + printf("\n32 bit: JIT compiler does not support \"%s\"\n", current->pattern); + } else if ((counter & 0x1) != 0) { + setstack32(mcontext32); + return_value32[0] = pcre2_match_32(re32, regtest_buf32, length32, + current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32); + } else { + pcre2_jit_stack_assign_32(mcontext32, NULL, getstack32()); + return_value32[0] = pcre2_jit_match_32(re32, regtest_buf32, length32, + current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32); + } + } +#endif + + /* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s", + return_value8[0], return_value16[0], return_value32[0], + (int)ovector8_1[0], (int)ovector8_1[1], + (int)ovector16_1[0], (int)ovector16_1[1], + (int)ovector32_1[0], (int)ovector32_1[1], + (current->compile_options & PCRE2_CASELESS) ? "C" : ""); */ + + /* If F_DIFF is set, just run the test, but do not compare the results. + Segfaults can still be captured. */ + + is_successful = 1; + if (!(current->start_offset & F_DIFF)) { +#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2) + if (!(current->start_offset & F_FORCECONV)) { + + /* All results must be the same. */ +#ifdef SUPPORT_PCRE2_8 + if ((return_value = return_value8[0]) != return_value8[1]) { + printf("\n8 bit: Return value differs(J8:%d,I8:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value8[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#ifdef SUPPORT_PCRE2_16 + if ((return_value = return_value16[0]) != return_value16[1]) { + printf("\n16 bit: Return value differs(J16:%d,I16:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value16[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#ifdef SUPPORT_PCRE2_32 + if ((return_value = return_value32[0]) != return_value32[1]) { + printf("\n32 bit: Return value differs(J32:%d,I32:%d): [%d] '%s' @ '%s'\n", + return_value32[0], return_value32[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16 + if (return_value8[0] != return_value16[0]) { + printf("\n8 and 16 bit: Return value differs(J8:%d,J16:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value16[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32 + if (return_value8[0] != return_value32[0]) { + printf("\n8 and 32 bit: Return value differs(J8:%d,J32:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value32[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32 + if (return_value16[0] != return_value32[0]) { + printf("\n16 and 32 bit: Return value differs(J16:%d,J32:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value32[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif + if (return_value >= 0 || return_value == PCRE_ERROR_PARTIAL) { + if (return_value == PCRE_ERROR_PARTIAL) { + return_value = 2; + } else { + return_value *= 2; + } +#ifdef SUPPORT_PCRE2_8 + return_value8[0] = return_value; +#endif +#ifdef SUPPORT_PCRE2_16 + return_value16[0] = return_value; +#endif +#ifdef SUPPORT_PCRE2_32 + return_value32[0] = return_value; +#endif + /* Transform back the results. */ + if (current->flags & PCRE_UTF8) { +#ifdef SUPPORT_PCRE2_16 + for (i = 0; i < return_value; ++i) { + if (ovector16_1[i] >= 0) + ovector16_1[i] = regtest_offsetmap16[ovector16_1[i]]; + if (ovector16_2[i] >= 0) + ovector16_2[i] = regtest_offsetmap16[ovector16_2[i]]; + } +#endif +#ifdef SUPPORT_PCRE2_32 + for (i = 0; i < return_value; ++i) { + if (ovector32_1[i] >= 0) + ovector32_1[i] = regtest_offsetmap32[ovector32_1[i]]; + if (ovector32_2[i] >= 0) + ovector32_2[i] = regtest_offsetmap32[ovector32_2[i]]; + } +#endif + } + + for (i = 0; i < return_value; ++i) { +#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16 + if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) { + printf("\n8 and 16 bit: Ovector[%d] value differs(J8:%d,I8:%d,J16:%d,I16:%d): [%d] '%s' @ '%s' \n", + i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i], + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32 + if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector32_1[i] || ovector8_1[i] != ovector32_2[i]) { + printf("\n8 and 32 bit: Ovector[%d] value differs(J8:%d,I8:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector8_1[i], ovector8_2[i], ovector32_1[i], ovector32_2[i], + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_16 + if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector16_1[i] || ovector16_1[i] != ovector16_2[i]) { + printf("\n16 and 16 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector16_1[i], ovector16_2[i], ovector16_1[i], ovector16_2[i], + total, current->pattern, current->input); + is_successful = 0; + } +#endif + } + } + } else +#endif /* more than one of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16 and SUPPORT_PCRE2_32 */ + { +#ifdef SUPPORT_PCRE2_8 + if (return_value8[0] != return_value8[1]) { + printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value8[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value8[0] >= 0 || return_value8[0] == PCRE2_ERROR_PARTIAL) { + if (return_value8[0] == PCRE2_ERROR_PARTIAL) + return_value8[0] = 2; + else + return_value8[0] *= 2; + + for (i = 0; i < return_value8[0]; ++i) + if (ovector8_1[i] != ovector8_2[i]) { + printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, (int)ovector8_1[i], (int)ovector8_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + +#ifdef SUPPORT_PCRE2_16 + if (return_value16[0] != return_value16[1]) { + printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value16[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value16[0] >= 0 || return_value16[0] == PCRE2_ERROR_PARTIAL) { + if (return_value16[0] == PCRE2_ERROR_PARTIAL) + return_value16[0] = 2; + else + return_value16[0] *= 2; + + for (i = 0; i < return_value16[0]; ++i) + if (ovector16_1[i] != ovector16_2[i]) { + printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, (int)ovector16_1[i], (int)ovector16_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + +#ifdef SUPPORT_PCRE2_32 + if (return_value32[0] != return_value32[1]) { + printf("\n32 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value32[0], return_value32[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value32[0] >= 0 || return_value32[0] == PCRE2_ERROR_PARTIAL) { + if (return_value32[0] == PCRE2_ERROR_PARTIAL) + return_value32[0] = 2; + else + return_value32[0] *= 2; + + for (i = 0; i < return_value32[0]; ++i) + if (ovector32_1[i] != ovector32_2[i]) { + printf("\n32 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, (int)ovector32_1[i], (int)ovector32_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + } + } + + if (is_successful) { +#ifdef SUPPORT_PCRE2_8 + if (!(current->start_offset & F_NO8) && (utf || is_ascii)) { + if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) { + printf("8 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value8[0] >= 0 && (current->start_offset & F_NOMATCH)) { + printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + } +#endif +#ifdef SUPPORT_PCRE2_16 + if (!(current->start_offset & F_NO16) && (utf || is_ascii)) { + if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) { + printf("16 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value16[0] >= 0 && (current->start_offset & F_NOMATCH)) { + printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + } +#endif +#ifdef SUPPORT_PCRE2_32 + if (!(current->start_offset & F_NO32) && (utf || is_ascii)) { + if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) { + printf("32 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value32[0] >= 0 && (current->start_offset & F_NOMATCH)) { + printf("32 bit: Test should not match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + } + + if (is_successful) { +#ifdef SUPPORT_PCRE2_8 + if (re8 && !(current->start_offset & F_NO8) && pcre2_get_mark_8(mdata8_1) != pcre2_get_mark_8(mdata8_2)) { + printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#ifdef SUPPORT_PCRE2_16 + if (re16 && !(current->start_offset & F_NO16) && pcre2_get_mark_16(mdata16_1) != pcre2_get_mark_16(mdata16_2)) { + printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#ifdef SUPPORT_PCRE2_32 + if (re32 && !(current->start_offset & F_NO32) && pcre2_get_mark_32(mdata32_1) != pcre2_get_mark_32(mdata32_2)) { + printf("32 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } +#endif + } + +#ifdef SUPPORT_PCRE2_8 + pcre2_code_free_8(re8); + pcre2_match_data_free_8(mdata8_1); + pcre2_match_data_free_8(mdata8_2); + pcre2_match_context_free_8(mcontext8); +#endif +#ifdef SUPPORT_PCRE2_16 + pcre2_code_free_16(re16); + pcre2_match_data_free_16(mdata16_1); + pcre2_match_data_free_16(mdata16_2); + pcre2_match_context_free_16(mcontext16); +#endif +#ifdef SUPPORT_PCRE2_32 + pcre2_code_free_32(re32); + pcre2_match_data_free_32(mdata32_1); + pcre2_match_data_free_32(mdata32_2); + pcre2_match_context_free_32(mcontext32); +#endif + + if (is_successful) { + successful++; + successful_row++; + printf("."); + if (successful_row >= 60) { + successful_row = 0; + printf("\n"); + } + } else + successful_row = 0; + + fflush(stdout); + current++; + } +#ifdef SUPPORT_PCRE2_8 + setstack8(NULL); +#endif +#ifdef SUPPORT_PCRE2_16 + setstack16(NULL); +#endif +#ifdef SUPPORT_PCRE2_32 + setstack32(NULL); +#endif + + if (total == successful) { + printf("\nAll JIT regression tests are successfully passed.\n"); + return 0; + } else { + printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful); + return 1; + } +} + +/* End of pcre2_jit_test.c */ diff --git a/pcre2/src/pcre2_maketables.c b/pcre2/src/pcre2_maketables.c new file mode 100644 index 000000000..2c7ae84d8 --- /dev/null +++ b/pcre2/src/pcre2_maketables.c @@ -0,0 +1,157 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains the external function pcre2_maketables(), which builds +character tables for PCRE2 in the current locale. The file is compiled on its +own as part of the PCRE2 library. However, it is also included in the +compilation of dftables.c, in which case the macro DFTABLES is defined. */ + +#ifndef DFTABLES +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +# include "pcre2_internal.h" +#endif + + + +/************************************************* +* Create PCRE2 character tables * +*************************************************/ + +/* This function builds a set of character tables for use by PCRE2 and returns +a pointer to them. They are build using the ctype functions, and consequently +their contents will depend upon the current locale setting. When compiled as +part of the library, the store is obtained via a general context malloc, if +supplied, but when DFTABLES is defined (when compiling the dftables auxiliary +program) malloc() is used, and the function has a different name so as not to +clash with the prototype in pcre2.h. + +Arguments: none when DFTABLES is defined + else a PCRE2 general context or NULL +Returns: pointer to the contiguous block of data +*/ + +#ifdef DFTABLES /* Included in freestanding dftables.c program */ +static const uint8_t *maketables(void) +{ +uint8_t *yield = (uint8_t *)malloc(tables_length); + +#else /* Not DFTABLES, compiling the library */ +PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION +pcre2_maketables(pcre2_general_context *gcontext) +{ +uint8_t *yield = (uint8_t *)((gcontext != NULL)? + gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) : + malloc(tables_length)); +#endif /* DFTABLES */ + +int i; +uint8_t *p; + +if (yield == NULL) return NULL; +p = yield; + +/* First comes the lower casing table */ + +for (i = 0; i < 256; i++) *p++ = tolower(i); + +/* Next the case-flipping table */ + +for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); + +/* Then the character class tables. Don't try to be clever and save effort on +exclusive ones - in some locales things may be different. + +Note that the table for "space" includes everything "isspace" gives, including +VT in the default locale. This makes it work for the POSIX class [:space:]. +From release 8.34 is is also correct for Perl space, because Perl added VT at +release 5.18. + +Note also that it is possible for a character to be alnum or alpha without +being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the +fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must +test for alnum specially. */ + +memset(p, 0, cbit_length); +for (i = 0; i < 256; i++) + { + if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); + if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); + if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); + if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); + if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); + if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); + if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); + if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); + if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); + if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); + if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); + } +p += cbit_length; + +/* Finally, the character type table. In this, we used to exclude VT from the +white space chars, because Perl didn't recognize it as such for \s and for +comments within regexes. However, Perl changed at release 5.18, so PCRE changed +at release 8.34. */ + +for (i = 0; i < 256; i++) + { + int x = 0; + if (isspace(i)) x += ctype_space; + if (isalpha(i)) x += ctype_letter; + if (isdigit(i)) x += ctype_digit; + if (isxdigit(i)) x += ctype_xdigit; + if (isalnum(i) || i == '_') x += ctype_word; + + /* Note: strchr includes the terminating zero in the characters it considers. + In this instance, that is ok because we want binary zero to be flagged as a + meta-character, which in this sense is any character that terminates a run + of data characters. */ + + if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta; + *p++ = x; + } + +return yield; +} + +/* End of pcre2_maketables.c */ diff --git a/pcre2/src/pcre2_match.c b/pcre2/src/pcre2_match.c new file mode 100644 index 000000000..f5275c7c4 --- /dev/null +++ b/pcre2/src/pcre2_match.c @@ -0,0 +1,7243 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK mb /* Block containing newline information */ +#define PSSTART start_subject /* Field containing processed string start */ +#define PSEND end_subject /* Field containing processed string end */ + +#include "pcre2_internal.h" + +/* Masks for identifying the public options that are permitted at match time. +*/ + +#define PUBLIC_MATCH_OPTIONS \ + (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ + PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ + PCRE2_PARTIAL_SOFT) + +#define PUBLIC_JIT_MATCH_OPTIONS \ + (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ + PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD) + +/* The mb->capture_last field uses the lower 16 bits for the last captured +substring (which can never be greater than 65535) and a bit in the top half +to mean "capture vector overflowed". This odd way of doing things was +implemented when it was realized that preserving and restoring the overflow bit +whenever the last capture number was saved/restored made for a neater +interface, and doing it this way saved on (a) another variable, which would +have increased the stack frame size (a big NO-NO in PCRE) and (b) another +separate set of save/restore instructions. The following defines are used in +implementing this. */ + +#define CAPLMASK 0x0000ffff /* The bits used for last_capture */ +#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */ +#define OVFLBIT 0x00010000 /* The bit that is set for overflow */ + +/* Bits for setting in mb->match_function_type to indicate two special types +of call to match(). We do it this way to save on using another stack variable, +as stack usage is to be discouraged. */ + +#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */ +#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */ + +/* Non-error returns from the match() function. Error returns are externally +defined PCRE2_ERROR_xxx codes, which are all negative. */ + +#define MATCH_MATCH 1 +#define MATCH_NOMATCH 0 + +/* Special internal returns from the match() function. Make them sufficiently +negative to avoid the external error codes. */ + +#define MATCH_ACCEPT (-999) +#define MATCH_KETRPOS (-998) +#define MATCH_ONCE (-997) +/* The next 5 must be kept together and in sequence so that a test that checks +for any one of them can use a range. */ +#define MATCH_COMMIT (-996) +#define MATCH_PRUNE (-995) +#define MATCH_SKIP (-994) +#define MATCH_SKIP_ARG (-993) +#define MATCH_THEN (-992) +#define MATCH_BACKTRACK_MAX MATCH_THEN +#define MATCH_BACKTRACK_MIN MATCH_COMMIT + +/* Min and max values for the common repeats; for the maxima, 0 => infinity */ + +static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, }; +static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, }; + +/* Maximum number of ovector elements that can be saved on the system stack +when processing OP_RECURSE in non-HEAP_MATCH_RECURSE mode. If the ovector is +bigger, malloc() is used. This value should be a multiple of 3, because the +ovector length is always a multiple of 3. */ + +#define OP_RECURSE_STACK_SAVE_MAX 45 + + + +/************************************************* +* Match a back-reference * +*************************************************/ + +/* This function is called only when it is known that the offset lies within +the offsets that have so far been used in the match. Note that in caseless +UTF-8 mode, the number of subject bytes matched may be different to the number +of reference bytes. (In theory this could also happen in UTF-16 mode, but it +seems unlikely.) + +Arguments: + offset index into the offset vector + offset_top top of the used offset vector + eptr pointer into the subject + mb points to match block + caseless TRUE if caseless + lengthptr pointer for returning the length matched + +Returns: = 0 sucessful match; number of code units matched is set + < 0 no match + > 0 partial match +*/ + +static int +match_ref(PCRE2_SIZE offset, PCRE2_SIZE offset_top, register PCRE2_SPTR eptr, + match_block *mb, BOOL caseless, PCRE2_SIZE *lengthptr) +{ +#if defined SUPPORT_UNICODE +BOOL utf = (mb->poptions & PCRE2_UTF) != 0; +#endif + +register PCRE2_SPTR p; +PCRE2_SIZE length; +PCRE2_SPTR eptr_start = eptr; + +/* Deal with an unset group. The default is no match, but there is an option to +match an empty string. */ + +if (offset >= offset_top || mb->ovector[offset] == PCRE2_UNSET) + { + if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0) + { + *lengthptr = 0; + return 0; /* Match */ + } + else return -1; /* No match */ + } + +/* Separate the caseless and UTF cases for speed. */ + +p = mb->start_subject + mb->ovector[offset]; +length = mb->ovector[offset+1] - mb->ovector[offset]; + +if (caseless) + { +#if defined SUPPORT_UNICODE + if (utf) + { + /* Match characters up to the end of the reference. NOTE: the number of + code units matched may differ, because in UTF-8 there are some characters + whose upper and lower case versions code have different numbers of bytes. + For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 + (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a + sequence of two of the latter. It is important, therefore, to check the + length along the reference, not along the subject (earlier code did this + wrong). */ + + PCRE2_SPTR endptr = p + length; + while (p < endptr) + { + uint32_t c, d; + const ucd_record *ur; + if (eptr >= mb->end_subject) return 1; /* Partial match */ + GETCHARINC(c, eptr); + GETCHARINC(d, p); + ur = GET_UCD(d); + if (c != d && c != (uint32_t)((int)d + ur->other_case)) + { + const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset; + for (;;) + { + if (c < *pp) return -1; /* No match */ + if (c == *pp++) break; + } + } + } + } + else +#endif + + /* Not in UTF mode */ + + { + for (; length > 0; length--) + { + uint32_t cc, cp; + if (eptr >= mb->end_subject) return 1; /* Partial match */ + cc = UCHAR21TEST(eptr); + cp = UCHAR21TEST(p); + if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc)) + return -1; /* No match */ + p++; + eptr++; + } + } + } + +/* In the caseful case, we can just compare the code units, whether or not we +are in UTF mode. */ + +else + { + for (; length > 0; length--) + { + if (eptr >= mb->end_subject) return 1; /* Partial match */ + if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; /*No match */ + } + } + +*lengthptr = eptr - eptr_start; +return 0; /* Match */ +} + + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +The match() function is highly recursive, though not every recursive call +increases the recursion depth. Nevertheless, some regular expressions can cause +it to recurse to a great depth. I was writing for Unix, so I just let it call +itself recursively. This uses the stack for saving everything that has to be +saved for a recursive call. On Unix, the stack can be large, and this works +fine. + +It turns out that on some non-Unix-like systems there are problems with +programs that use a lot of stack. (This despite the fact that every last chip +has oodles of memory these days, and techniques for extending the stack have +been known for decades.) So.... + +There is a fudge, triggered by defining HEAP_MATCH_RECURSE, which avoids +recursive calls by keeping local variables that need to be preserved in blocks +of memory on the heap instead instead of on the stack. Macros are used to +achieve this so that the actual code doesn't look very different to what it +always used to. + +The original heap-recursive code used longjmp(). However, it seems that this +can be very slow on some operating systems. Following a suggestion from Stan +Switzer, the use of longjmp() has been abolished, at the cost of having to +provide a unique number for each call to RMATCH. There is no way of generating +a sequence of numbers at compile time in C. I have given them names, to make +them stand out more clearly. + +Crude tests on x86 Linux show a small speedup of around 5-8%. However, on +FreeBSD, avoiding longjmp() more than halves the time taken to run the standard +tests. Furthermore, not using longjmp() means that local dynamic variables +don't have indeterminate values; this has meant that the frame size can be +reduced because the result can be "passed back" by straight setting of the +variable instead of being passed in the frame. +**************************************************************************** +***************************************************************************/ + +/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN +below must be updated in sync. */ + +enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, + RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, + RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, + RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, + RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, + RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, + RM61, RM62, RM63, RM64, RM65, RM66, RM67, RM68 }; + +/* These versions of the macros use the stack, as normal. Note that the "rw" +argument of RMATCH isn't actually used in this definition. */ + +#ifndef HEAP_MATCH_RECURSE +#define REGISTER register +#define RMATCH(ra,rb,rc,rd,re,rw) \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) +#define RRETURN(ra) return ra +#else + +/* These versions of the macros manage a private stack on the heap. Note that +the "rd" argument of RMATCH isn't actually used in this definition. It's the mb +argument of match(), which never changes. */ + +#define REGISTER + +#define RMATCH(ra,rb,rc,rd,re,rw)\ + {\ + heapframe *newframe = frame->Xnextframe;\ + if (newframe == NULL)\ + {\ + newframe = (heapframe *)(mb->stack_memctl.malloc)\ + (sizeof(heapframe), mb->stack_memctl.memory_data);\ + if (newframe == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);\ + newframe->Xnextframe = NULL;\ + frame->Xnextframe = newframe;\ + }\ + frame->Xwhere = rw;\ + newframe->Xeptr = ra;\ + newframe->Xecode = rb;\ + newframe->Xmstart = mstart;\ + newframe->Xoffset_top = rc;\ + newframe->Xeptrb = re;\ + newframe->Xrdepth = frame->Xrdepth + 1;\ + newframe->Xprevframe = frame;\ + frame = newframe;\ + goto HEAP_RECURSE;\ + L_##rw:;\ + } + +#define RRETURN(ra)\ + {\ + heapframe *oldframe = frame;\ + frame = oldframe->Xprevframe;\ + if (frame != NULL)\ + {\ + rrc = ra;\ + goto HEAP_RETURN;\ + }\ + return ra;\ + } + + +/* Structure for remembering the local variables in a private frame. Arrange it +so as to minimize the number of holes. */ + +typedef struct heapframe { + struct heapframe *Xprevframe; + struct heapframe *Xnextframe; + +#ifdef SUPPORT_UNICODE + PCRE2_SPTR Xcharptr; +#endif + PCRE2_SPTR Xeptr; + PCRE2_SPTR Xecode; + PCRE2_SPTR Xmstart; + PCRE2_SPTR Xcallpat; + PCRE2_SPTR Xdata; + PCRE2_SPTR Xnext_ecode; + PCRE2_SPTR Xpp; + PCRE2_SPTR Xprev; + PCRE2_SPTR Xsaved_eptr; + + eptrblock *Xeptrb; + + PCRE2_SIZE Xlength; + PCRE2_SIZE Xoffset; + PCRE2_SIZE Xoffset_top; + PCRE2_SIZE Xsave_offset1, Xsave_offset2, Xsave_offset3; + + uint32_t Xfc; + uint32_t Xnumber; + uint32_t Xrdepth; + uint32_t Xop; + uint32_t Xsave_capture_last; + +#ifdef SUPPORT_UNICODE + uint32_t Xprop_value; + int Xprop_type; + int Xprop_fail_result; + int Xoclength; +#endif + + int Xcodelink; + int Xctype; + int Xfi; + int Xmax; + int Xmin; + int Xwhere; /* Where to jump back to */ + + BOOL Xcondition; + BOOL Xcur_is_word; + BOOL Xprev_is_word; + + eptrblock Xnewptrb; + recursion_info Xnew_recursive; + +#ifdef SUPPORT_UNICODE + PCRE2_UCHAR Xocchars[6]; +#endif +} heapframe; + +#endif + + +/*************************************************************************** +***************************************************************************/ + + +/* When HEAP_MATCH_RECURSE is not defined, the match() function implements +backtrack points by calling itself recursively in all but one case. The one +special case is when processing OP_RECURSE, which specifies recursion in the +pattern. The entire ovector must be saved and restored while processing +OP_RECURSE. If the ovector is small enough, instead of calling match() +directly, op_recurse_ovecsave() is called. This function uses the system stack +to save the ovector while calling match() to process the pattern recursion. */ + +#ifndef HEAP_MATCH_RECURSE + +/* We need a prototype for match() because it is mutually recursive with +op_recurse_ovecsave(). */ + +static int +match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart, + PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth); + + +/************************************************* +* Process OP_RECURSE, stacking ovector * +*************************************************/ + +/* When this function is called, mb->recursive has already been updated to +point to a new recursion data block, and all its fields other than ovec_save +have been set. + +This function exists so that the local vector variable ovecsave is no longer +defined in the match() function, as it was in PCRE1. It is used only when there +is recursion in the pattern, so it wastes a lot of stack to have it defined for +every call of match(). We now use this function as an indirect way of calling +match() only in the case when ovecsave is needed. (David Wheeler used to say +"All problems in computer science can be solved by another level of +indirection.") + +HOWEVER: when this file is compiled by gcc in an optimizing mode, because this +function is called only once, and only from within match(), gcc will "inline" +it - that is, move it inside match() - and this completely negates its reason +for existence. Therefore, we mark it as non-inline when gcc is in use. + +Arguments: + eptr pointer to current character in subject + callpat the recursion point in the pattern + mstart pointer to the current match start position (can be modified + by encountering \K) + offset_top current top pointer (highest ovector offset used + 1) + mb pointer to "static" info block for the match + eptrb pointer to chain of blocks containing eptr at start of + brackets - for testing for empty matches + rdepth the recursion depth + +Returns: a match() return code +*/ + +static int +#ifdef __GNUC__ +__attribute__ ((noinline)) +#endif +op_recurse_ovecsave(REGISTER PCRE2_SPTR eptr, PCRE2_SPTR callpat, + PCRE2_SPTR mstart, PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, + uint32_t rdepth) +{ +register int rrc; +BOOL cbegroup = *callpat >= OP_SBRA; +recursion_info *new_recursive = mb->recursive; +PCRE2_SIZE ovecsave[OP_RECURSE_STACK_SAVE_MAX]; + +/* Save the ovector */ + +new_recursive->ovec_save = ovecsave; +memcpy(ovecsave, mb->ovector, mb->offset_end * sizeof(PCRE2_SIZE)); + +/* Do the recursion. After processing each alternative, restore the ovector +data and the last captured value. */ + +do + { + if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP; + rrc = match(eptr, callpat + PRIV(OP_lengths)[*callpat], mstart, offset_top, + mb, eptrb, rdepth + 1); + memcpy(mb->ovector, new_recursive->ovec_save, + mb->offset_end * sizeof(PCRE2_SIZE)); + mb->capture_last = new_recursive->saved_capture_last; + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) return rrc; + + /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a + recursion; they cause a NOMATCH for the entire recursion. These codes + are defined in a range that can be tested for. */ + + if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX) + return MATCH_NOMATCH; + + /* Any return code other than NOMATCH is an error. Otherwise, advance to the + next alternative or to the end of the recursing subpattern. If there were + nested recursions, mb->recursive might be changed, so reset it before + looping. */ + + if (rrc != MATCH_NOMATCH) return rrc; + mb->recursive = new_recursive; + callpat += GET(callpat, 1); + } +while (*callpat == OP_ALT); /* Loop for the alternatives */ + +/* None of the alternatives matched. */ + +return MATCH_NOMATCH; +} +#endif /* HEAP_MATCH_RECURSE */ + + + +/************************************************* +* Match from current position * +*************************************************/ + +/* This function is called recursively in many circumstances. Whenever it +returns a negative (error) response, the outer incarnation must also return the +same response. */ + +/* These macros pack up tests that are used for partial matching, and which +appear several times in the code. We set the "hit end" flag if the pointer is +at the end of the subject and also past the earliest inspected character (i.e. +something has been matched, even if not part of the actual matched string). For +hard partial matching, we then return immediately. The second one is used when +we already know we are past the end of the subject. */ + +#define CHECK_PARTIAL()\ + if (mb->partial != 0 && eptr >= mb->end_subject && \ + eptr > mb->start_used_ptr) \ + { \ + mb->hitend = TRUE; \ + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \ + } + +#define SCHECK_PARTIAL()\ + if (mb->partial != 0 && eptr > mb->start_used_ptr) \ + { \ + mb->hitend = TRUE; \ + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \ + } + + +/* Performance note: It might be tempting to extract commonly used fields from +the mb structure (e.g. utf, end_subject) into individual variables to improve +performance. Tests using gcc on a SPARC disproved this; in the first case, it +made performance worse. + +Arguments: + eptr pointer to current character in subject + ecode pointer to current position in compiled code + mstart pointer to the current match start position (can be modified + by encountering \K) + offset_top current top pointer (highest ovector offset used + 1) + mb pointer to "static" info block for the match + eptrb pointer to chain of blocks containing eptr at start of + brackets - for testing for empty matches + rdepth the recursion depth + +Returns: MATCH_MATCH if matched ) these values are >= 0 + MATCH_NOMATCH if failed to match ) + a negative MATCH_xxx value for PRUNE, SKIP, etc + a negative PCRE2_ERROR_xxx value if aborted by an error condition + (e.g. stopped by repeated call or recursion limit) +*/ + +static int +match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart, + PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth) +{ +/* These variables do not need to be preserved over recursion in this function, +so they can be ordinary variables in all cases. Mark some of them with +"register" because they are used a lot in loops. */ + +register int rrc; /* Returns from recursive calls */ +register int i; /* Used for loops not involving calls to RMATCH() */ +register uint32_t c; /* Character values not kept over RMATCH() calls */ +register BOOL utf; /* Local copy of UTF flag for speed */ + +BOOL minimize, possessive; /* Quantifier options */ +BOOL caseless; +int condcode; + +/* When recursion is not being used, all "local" variables that have to be +preserved over calls to RMATCH() are part of a "frame". We set up the top-level +frame on the stack here; subsequent instantiations are obtained from the heap +whenever RMATCH() does a "recursion". See the macro definitions above. Putting +the top-level on the stack rather than malloc-ing them all gives a performance +boost in many cases where there is not much "recursion". */ + +#ifdef HEAP_MATCH_RECURSE +heapframe *frame = (heapframe *)mb->match_frames_base; + +/* Copy in the original argument variables */ + +frame->Xeptr = eptr; +frame->Xecode = ecode; +frame->Xmstart = mstart; +frame->Xoffset_top = offset_top; +frame->Xeptrb = eptrb; +frame->Xrdepth = rdepth; + +/* This is where control jumps back to to effect "recursion" */ + +HEAP_RECURSE: + +/* Macros make the argument variables come from the current frame */ + +#define eptr frame->Xeptr +#define ecode frame->Xecode +#define mstart frame->Xmstart +#define offset_top frame->Xoffset_top +#define eptrb frame->Xeptrb +#define rdepth frame->Xrdepth + +/* Ditto for the local variables */ + +#ifdef SUPPORT_UNICODE +#define charptr frame->Xcharptr +#define prop_value frame->Xprop_value +#define prop_type frame->Xprop_type +#define prop_fail_result frame->Xprop_fail_result +#define oclength frame->Xoclength +#define occhars frame->Xocchars +#endif + + +#define callpat frame->Xcallpat +#define codelink frame->Xcodelink +#define data frame->Xdata +#define next_ecode frame->Xnext_ecode +#define pp frame->Xpp +#define prev frame->Xprev +#define saved_eptr frame->Xsaved_eptr + +#define new_recursive frame->Xnew_recursive + +#define ctype frame->Xctype +#define fc frame->Xfc +#define fi frame->Xfi +#define length frame->Xlength +#define max frame->Xmax +#define min frame->Xmin +#define number frame->Xnumber +#define offset frame->Xoffset +#define op frame->Xop +#define save_capture_last frame->Xsave_capture_last +#define save_offset1 frame->Xsave_offset1 +#define save_offset2 frame->Xsave_offset2 +#define save_offset3 frame->Xsave_offset3 + +#define condition frame->Xcondition +#define cur_is_word frame->Xcur_is_word +#define prev_is_word frame->Xprev_is_word + +#define newptrb frame->Xnewptrb + +/* When normal stack-based recursion is being used for match(), local variables +are allocated on the stack and get preserved during recursion in the usual way. +In this environment, fi and i, and fc and c, can be the same variables. */ + +#else /* HEAP_MATCH_RECURSE not defined */ +#define fi i +#define fc c + +/* Many of the following variables are used only in small blocks of the code. +My normal style of coding would have declared them within each of those blocks. +However, in order to accommodate the version of this code that uses an external +"stack" implemented on the heap, it is easier to declare them all here, so the +declarations can be cut out in a block. The only declarations within blocks +below are for variables that do not have to be preserved over a recursive call +to RMATCH(). */ + +#ifdef SUPPORT_UNICODE +PCRE2_SPTR charptr; +#endif +PCRE2_SPTR callpat; +PCRE2_SPTR data; +PCRE2_SPTR next_ecode; +PCRE2_SPTR pp; +PCRE2_SPTR prev; +PCRE2_SPTR saved_eptr; + +PCRE2_SIZE length; +PCRE2_SIZE offset; +PCRE2_SIZE save_offset1, save_offset2, save_offset3; + +uint32_t number; +uint32_t op; +uint32_t save_capture_last; + +#ifdef SUPPORT_UNICODE +uint32_t prop_value; +int prop_type; +int prop_fail_result; +int oclength; +PCRE2_UCHAR occhars[6]; +#endif + +int codelink; +int ctype; +int max; +int min; + +BOOL condition; +BOOL cur_is_word; +BOOL prev_is_word; + +eptrblock newptrb; +recursion_info new_recursive; +#endif /* HEAP_MATCH_RECURSE not defined */ + +/* To save space on the stack and in the heap frame, I have doubled up on some +of the local variables that are used only in localised parts of the code, but +still need to be preserved over recursive calls of match(). These macros define +the alternative names that are used. */ + +#define allow_zero cur_is_word +#define cbegroup condition +#define code_offset codelink +#define condassert condition +#define foc number +#define matched_once prev_is_word +#define save_mark data + +/* These statements are here to stop the compiler complaining about unitialized +variables. */ + +#ifdef SUPPORT_UNICODE +prop_value = 0; +prop_fail_result = 0; +#endif + + +/* This label is used for tail recursion, which is used in a few cases even +when HEAP_MATCH_RECURSE is not defined, in order to reduce the amount of stack +that is used. Thanks to Ian Taylor for noticing this possibility and sending +the original patch. */ + +TAIL_RECURSE: + +/* OK, now we can get on with the real code of the function. Recursive calls +are specified by the macro RMATCH and RRETURN is used to return. When +HEAP_MATCH_RECURSE is *not* defined, these just turn into a recursive call to +match() and a "return", respectively. However, RMATCH isn't like a function +call because it's quite a complicated macro. It has to be used in one +particular way. This shouldn't, however, impact performance when true recursion +is being used. */ + +#ifdef SUPPORT_UNICODE +utf = (mb->poptions & PCRE2_UTF) != 0; +#else +utf = FALSE; +#endif + +/* First check that we haven't called match() too many times, or that we +haven't exceeded the recursive call limit. */ + +if (mb->match_call_count++ >= mb->match_limit) RRETURN(PCRE2_ERROR_MATCHLIMIT); +if (rdepth >= mb->match_limit_recursion) RRETURN(PCRE2_ERROR_RECURSIONLIMIT); + +/* At the start of a group with an unlimited repeat that may match an empty +string, the variable mb->match_function_type contains the MATCH_CBEGROUP bit. +It is done this way to save having to use another function argument, which +would take up space on the stack. See also MATCH_CONDASSERT below. + +When MATCH_CBEGROUP is set, add the current subject pointer to the chain of +such remembered pointers, to be checked when we hit the closing ket, in order +to break infinite loops that match no characters. When match() is called in +other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must +NOT be used with tail recursion, because the memory block that is used is on +the stack, so a new one may be required for each match(). */ + +if ((mb->match_function_type & MATCH_CBEGROUP) != 0) + { + newptrb.epb_saved_eptr = eptr; + newptrb.epb_prev = eptrb; + eptrb = &newptrb; + mb->match_function_type &= ~MATCH_CBEGROUP; + } + +/* Now, at last, we can start processing the opcodes. */ + +for (;;) + { + minimize = possessive = FALSE; + op = *ecode; + + switch(op) + { + case OP_MARK: + mb->nomatch_mark = ecode + 2; + mb->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, + eptrb, RM55); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + mb->mark == NULL) mb->mark = ecode + 2; + + /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an + argument, and we must check whether that argument matches this MARK's + argument. It is passed back in mb->start_match_ptr (an overloading of that + variable). If it does match, we reset that variable to the current subject + position and return MATCH_SKIP. Otherwise, pass back the return code + unaltered. */ + + else if (rrc == MATCH_SKIP_ARG && + PRIV(strcmp)(ecode + 2, mb->start_match_ptr) == 0) + { + mb->start_match_ptr = eptr; + RRETURN(MATCH_SKIP); + } + RRETURN(rrc); + + case OP_FAIL: + RRETURN(MATCH_NOMATCH); + + case OP_COMMIT: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM52); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RRETURN(MATCH_COMMIT); + + case OP_PRUNE: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM51); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RRETURN(MATCH_PRUNE); + + case OP_PRUNE_ARG: + mb->nomatch_mark = ecode + 2; + mb->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, + eptrb, RM56); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + mb->mark == NULL) mb->mark = ecode + 2; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RRETURN(MATCH_PRUNE); + + case OP_SKIP: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM53); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->start_match_ptr = eptr; /* Pass back current position */ + RRETURN(MATCH_SKIP); + + /* Note that, for Perl compatibility, SKIP with an argument does NOT set + nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was + not a matching mark, we have to re-run the match, ignoring the SKIP_ARG + that failed and any that precede it (either they also failed, or were not + triggered). To do this, we maintain a count of executed SKIP_ARGs. If a + SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg + set to the count of the one that failed. */ + + case OP_SKIP_ARG: + mb->skip_arg_count++; + if (mb->skip_arg_count <= mb->ignore_skip_arg) + { + ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; + break; + } + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, + eptrb, RM57); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + + /* Pass back the current skip name by overloading mb->start_match_ptr and + returning the special MATCH_SKIP_ARG return code. This will either be + caught by a matching MARK, or get to the top, where it causes a rematch + with mb->ignore_skip_arg set to the value of mb->skip_arg_count. */ + + mb->start_match_ptr = ecode + 2; + RRETURN(MATCH_SKIP_ARG); + + /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that + the branch in which it occurs can be determined. Overload the start of + match pointer to do this. */ + + case OP_THEN: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM54); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->start_match_ptr = ecode; + RRETURN(MATCH_THEN); + + case OP_THEN_ARG: + mb->nomatch_mark = ecode + 2; + mb->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, + mb, eptrb, RM58); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + mb->mark == NULL) mb->mark = ecode + 2; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->start_match_ptr = ecode; + RRETURN(MATCH_THEN); + + /* Handle an atomic group that does not contain any capturing parentheses. + This can be handled like an assertion. Prior to 8.13, all atomic groups + were handled this way. In 8.13, the code was changed as below for ONCE, so + that backups pass through the group and thereby reset captured values. + However, this uses a lot more stack, so in 8.20, atomic groups that do not + contain any captures generate OP_ONCE_NC, which can be handled in the old, + less stack intensive way. + + Check the alternative branches in turn - the matching won't pass the KET + for this kind of subpattern. If any one branch matches, we carry on as at + the end of a normal bracket, leaving the subject pointer, but resetting + the start-of-match value in case it was changed by \K. */ + + case OP_ONCE_NC: + prev = ecode; + saved_eptr = eptr; + save_mark = mb->mark; + do + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM64); + if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ + { + mstart = mb->start_match_ptr; + break; + } + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode,1); + mb->mark = save_mark; + } + while (*ecode == OP_ALT); + + /* If hit the end of the group (which could be repeated), fail */ + + if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); + + /* Continue as from after the group, updating the offsets high water + mark, since extracts may have been taken. */ + + do ecode += GET(ecode, 1); while (*ecode == OP_ALT); + + offset_top = mb->end_offset_top; + eptr = mb->end_match_ptr; + + /* For a non-repeating ket, just continue at this level. This also + happens for a repeating ket if no characters were matched in the group. + This is the forcible breaking of infinite loops as implemented in Perl + 5.005. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + ecode += 1+LINK_SIZE; + break; + } + + /* The repeating kets try the rest of the pattern or restart from the + preceding bracket, in the appropriate order. The second "call" of match() + uses tail recursion, to avoid using another stack frame. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM65); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode = prev; + goto TAIL_RECURSE; + } + else /* OP_KETRMAX */ + { + RMATCH(eptr, prev, offset_top, mb, eptrb, RM66); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += 1 + LINK_SIZE; + goto TAIL_RECURSE; + } + /* Control never gets here */ + + /* Handle a capturing bracket, other than those that are possessive with an + unlimited repeat. If there is space in the offset vector, save the current + subject position in the working slot at the top of the vector. We mustn't + change the current values of the data slot, because they may be set from a + previous iteration of this group, and be referred to by a reference inside + the group. A failure to match might occur after the group has succeeded, + if something later on doesn't match. For this reason, we need to restore + the working value and also the values of the final offsets, in case they + were set by a previous iteration of the same bracket. + + If there isn't enough space in the offset vector, treat this as if it were + a non-capturing bracket. Don't worry about setting the flag for the error + case here; that is handled in the code for KET. */ + + case OP_CBRA: + case OP_SCBRA: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + + if (offset < mb->offset_max) + { + save_offset1 = mb->ovector[offset]; + save_offset2 = mb->ovector[offset+1]; + save_offset3 = mb->ovector[mb->offset_end - number]; + save_capture_last = mb->capture_last; + save_mark = mb->mark; + + mb->ovector[mb->offset_end - number] = eptr - mb->start_subject; + + for (;;) + { + if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM1); + if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ + + /* If we backed up to a THEN, check whether it is within the current + branch by comparing the address of the THEN that is passed back with + the end of the branch. If it is within the current branch, and the + branch is one of two or more alternatives (it either starts or ends + with OP_ALT), we have reached the limit of THEN's action, so convert + the return code to NOMATCH, which will cause normal backtracking to + happen from now on. Otherwise, THEN is passed back to an outer + alternative. This implements Perl's treatment of parenthesized groups, + where a group not containing | does not affect the current alternative, + that is, (X) is NOT the same as (X|(*F)). */ + + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + /* Anything other than NOMATCH is passed back. */ + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->capture_last = save_capture_last; + ecode += GET(ecode, 1); + mb->mark = save_mark; + if (*ecode != OP_ALT) break; + } + + mb->ovector[offset] = save_offset1; + mb->ovector[offset+1] = save_offset2; + mb->ovector[mb->offset_end - number] = save_offset3; + + /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ + + RRETURN(rrc); + } + + /* FALL THROUGH ... Insufficient room for saving captured contents. Treat + as a non-capturing bracket. */ + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + /* Non-capturing or atomic group, except for possessive with unlimited + repeat and ONCE group with no captures. Loop for all the alternatives. + + When we get to the final alternative within the brackets, we used to return + the result of a recursive call to match() whatever happened so it was + possible to reduce stack usage by turning this into a tail recursion, + except in the case of a possibly empty group. However, now that there is + the possiblity of (*THEN) occurring in the final alternative, this + optimization is no longer always possible. + + We can optimize if we know there are no (*THEN)s in the pattern; at present + this is the best that can be done. + + MATCH_ONCE is returned when the end of an atomic group is successfully + reached, but subsequent matching fails. It passes back up the tree (causing + captured values to be reset) until the original atomic group level is + reached. This is tested by comparing mb->once_target with the start of the + group. At this point, the return is converted into MATCH_NOMATCH so that + previous backup points can be taken. */ + + case OP_ONCE: + case OP_BRA: + case OP_SBRA: + + for (;;) + { + if (op >= OP_SBRA || op == OP_ONCE) + mb->match_function_type |= MATCH_CBEGROUP; + + /* If this is not a possibly empty group, and there are no (*THEN)s in + the pattern, and this is the final alternative, optimize as described + above. */ + + else if (!mb->hasthen && ecode[GET(ecode, 1)] != OP_ALT) + { + ecode += PRIV(OP_lengths)[*ecode]; + goto TAIL_RECURSE; + } + + /* In all other cases, we have to make another call to match(). */ + + save_mark = mb->mark; + save_capture_last = mb->capture_last; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, eptrb, + RM2); + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) + { + if (rrc == MATCH_ONCE) + { + PCRE2_SPTR scode = ecode; + if (*scode != OP_ONCE) /* If not at start, find it */ + { + while (*scode == OP_ALT) scode += GET(scode, 1); + scode -= GET(scode, 1); + } + if (mb->once_target == scode) rrc = MATCH_NOMATCH; + } + RRETURN(rrc); + } + ecode += GET(ecode, 1); + mb->mark = save_mark; + if (*ecode != OP_ALT) break; + mb->capture_last = save_capture_last; + } + + RRETURN(MATCH_NOMATCH); + + /* Handle possessive capturing brackets with an unlimited repeat. We come + here from BRAZERO with allow_zero set TRUE. The ovector values are + handled similarly to the normal case above. However, the matching is + different. The end of these brackets will always be OP_KETRPOS, which + returns MATCH_KETRPOS without going further in the pattern. By this means + we can handle the group by iteration rather than recursion, thereby + reducing the amount of stack needed. If the ovector is too small for + capturing, treat as non-capturing. */ + + case OP_CBRAPOS: + case OP_SCBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_CAPTURE: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + if (offset >= mb->offset_max) goto POSSESSIVE_NON_CAPTURE; + + matched_once = FALSE; + code_offset = (int)(ecode - mb->start_code); + + save_offset1 = mb->ovector[offset]; + save_offset2 = mb->ovector[offset+1]; + save_offset3 = mb->ovector[mb->offset_end - number]; + save_capture_last = mb->capture_last; + + /* Each time round the loop, save the current subject position for use + when the group matches. For MATCH_MATCH, the group has matched, so we + restart it with a new subject starting position, remembering that we had + at least one match. For MATCH_NOMATCH, carry on with the alternatives, as + usual. If we haven't matched any alternatives in any iteration, check to + see if a previous iteration matched. If so, the group has matched; + continue from afterwards. Otherwise it has failed; restore the previous + capture values before returning NOMATCH. */ + + for (;;) + { + mb->ovector[mb->offset_end - number] = eptr - mb->start_subject; + if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM63); + if (rrc == MATCH_KETRPOS) + { + offset_top = mb->end_offset_top; + ecode = mb->start_code + code_offset; + save_capture_last = mb->capture_last; + matched_once = TRUE; + mstart = mb->start_match_ptr; /* In case \K changed it */ + if (eptr == mb->end_match_ptr) /* Matched an empty string */ + { + do ecode += GET(ecode, 1); while (*ecode == OP_ALT); + break; + } + eptr = mb->end_match_ptr; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->capture_last = save_capture_last; + ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; + } + + if (!matched_once) + { + mb->ovector[offset] = save_offset1; + mb->ovector[offset+1] = save_offset2; + mb->ovector[mb->offset_end - number] = save_offset3; + } + + if (allow_zero || matched_once) + { + ecode += 1 + LINK_SIZE; + break; + } + RRETURN(MATCH_NOMATCH); + + /* Non-capturing possessive bracket with unlimited repeat. We come here + from BRAZERO with allow_zero = TRUE. The code is similar to the above, + without the capturing complication. It is written out separately for speed + and cleanliness. */ + + case OP_BRAPOS: + case OP_SBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_NON_CAPTURE: + matched_once = FALSE; + code_offset = (int)(ecode - mb->start_code); + save_capture_last = mb->capture_last; + + for (;;) + { + if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, + eptrb, RM48); + if (rrc == MATCH_KETRPOS) + { + offset_top = mb->end_offset_top; + ecode = mb->start_code + code_offset; + matched_once = TRUE; + mstart = mb->start_match_ptr; /* In case \K reset it */ + if (eptr == mb->end_match_ptr) /* Matched an empty string */ + { + do ecode += GET(ecode, 1); while (*ecode == OP_ALT); + break; + } + eptr = mb->end_match_ptr; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; + mb->capture_last = save_capture_last; + } + + if (matched_once || allow_zero) + { + ecode += 1 + LINK_SIZE; + break; + } + RRETURN(MATCH_NOMATCH); + + /* Control never reaches here. */ + + /* Conditional group: compilation checked that there are no more than two + branches. If the condition is false, skipping the first branch takes us + past the end of the item if there is only one branch, but that's exactly + what we want. */ + + case OP_COND: + case OP_SCOND: + + /* The variable codelink will be added to ecode when the condition is + false, to get to the second branch. Setting it to the offset to the ALT + or KET, then incrementing ecode achieves this effect. We now have ecode + pointing to the condition or callout. */ + + codelink = GET(ecode, 1); /* Offset to the second branch */ + ecode += 1 + LINK_SIZE; /* From this opcode */ + + /* Because of the way auto-callout works during compile, a callout item is + inserted between OP_COND and an assertion condition. */ + + if (*ecode == OP_CALLOUT || *ecode == OP_CALLOUT_STR) + { + unsigned int callout_length = (*ecode == OP_CALLOUT) + ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE); + + if (mb->callout != NULL) + { + pcre2_callout_block cb; + cb.version = 1; + cb.capture_top = offset_top/2; + cb.capture_last = mb->capture_last & CAPLMASK; + cb.offset_vector = mb->ovector; + cb.mark = mb->nomatch_mark; + cb.subject = mb->start_subject; + cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject); + cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject); + cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject); + cb.pattern_position = GET(ecode, 1); + cb.next_item_length = GET(ecode, 1 + LINK_SIZE); + + if (*ecode == OP_CALLOUT) + { + cb.callout_number = ecode[1 + 2*LINK_SIZE]; + cb.callout_string_offset = 0; + cb.callout_string = NULL; + cb.callout_string_length = 0; + } + else + { + cb.callout_number = 0; + cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE); + cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1; + cb.callout_string_length = + callout_length - (1 + 4*LINK_SIZE) - 2; + } + + if ((rrc = mb->callout(&cb, mb->callout_data)) > 0) + RRETURN(MATCH_NOMATCH); + if (rrc < 0) RRETURN(rrc); + } + + /* Advance ecode past the callout, so it now points to the condition. We + must adjust codelink so that the value of ecode+codelink is unchanged. */ + + ecode += callout_length; + codelink -= callout_length; + } + + /* Test the various possible conditions */ + + condition = FALSE; + switch(condcode = *ecode) + { + case OP_RREF: /* Numbered group recursion test */ + if (mb->recursive != NULL) /* Not recursing => FALSE */ + { + uint32_t recno = GET2(ecode, 1); /* Recursion group number*/ + condition = (recno == RREF_ANY || recno == mb->recursive->group_num); + } + break; + + case OP_DNRREF: /* Duplicate named group recursion test */ + if (mb->recursive != NULL) + { + int count = GET2(ecode, 1 + IMM2_SIZE); + PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; + while (count-- > 0) + { + uint32_t recno = GET2(slot, 0); + condition = recno == mb->recursive->group_num; + if (condition) break; + slot += mb->name_entry_size; + } + } + break; + + case OP_CREF: /* Numbered group used test */ + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + condition = offset < offset_top && + mb->ovector[offset] != PCRE2_UNSET; + break; + + case OP_DNCREF: /* Duplicate named group used test */ + { + int count = GET2(ecode, 1 + IMM2_SIZE); + PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; + while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + condition = offset < offset_top && + mb->ovector[offset] != PCRE2_UNSET; + if (condition) break; + slot += mb->name_entry_size; + } + } + break; + + case OP_FALSE: + case OP_FAIL: /* The assertion (?!) becomes OP_FAIL */ + break; + + case OP_TRUE: + condition = TRUE; + break; + + /* The condition is an assertion. Call match() to evaluate it - setting + the MATCH_CONDASSERT bit in mb->match_function_type causes it to stop at + the end of an assertion. */ + + default: + mb->match_function_type |= MATCH_CONDASSERT; + RMATCH(eptr, ecode, offset_top, mb, NULL, RM3); + if (rrc == MATCH_MATCH) + { + if (mb->end_offset_top > offset_top) + offset_top = mb->end_offset_top; /* Captures may have happened */ + condition = TRUE; + + /* Advance ecode past the assertion to the start of the first branch, + but adjust it so that the general choosing code below works. If the + assertion has a quantifier that allows zero repeats we must skip over + the BRAZERO. This is a lunatic thing to do, but somebody did! */ + + if (*ecode == OP_BRAZERO) ecode++; + ecode += GET(ecode, 1); + while (*ecode == OP_ALT) ecode += GET(ecode, 1); + ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode]; + } + + /* PCRE doesn't allow the effect of (*THEN) to escape beyond an + assertion; it is therefore treated as NOMATCH. Any other return is an + error. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) + { + RRETURN(rrc); /* Need braces because of following else */ + } + break; + } + + /* Choose branch according to the condition */ + + ecode += condition? PRIV(OP_lengths)[condcode] : codelink; + + /* We are now at the branch that is to be obeyed. As there is only one, we + can use tail recursion to avoid using another stack frame, except when + there is unlimited repeat of a possibly empty group. In the latter case, a + recursive call to match() is always required, unless the second alternative + doesn't exist, in which case we can just plough on. Note that, for + compatibility with Perl, the | in a conditional group is NOT treated as + creating two alternatives. If a THEN is encountered in the branch, it + propagates out to the enclosing alternative (unless nested in a deeper set + of alternatives, of course). */ + + if (condition || ecode[-(1+LINK_SIZE)] == OP_ALT) + { + if (op != OP_SCOND) + { + goto TAIL_RECURSE; + } + + mb->match_function_type |= MATCH_CBEGROUP; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM49); + RRETURN(rrc); + } + + /* Condition false & no alternative; continue after the group. */ + + else + { + } + break; + + + /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, + to close any currently open capturing brackets. */ + + case OP_CLOSE: + number = GET2(ecode, 1); /* Must be less than 65536 */ + offset = number << 1; + mb->capture_last = (mb->capture_last & OVFLMASK) | number; + if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else + { + mb->ovector[offset] = + mb->ovector[mb->offset_end - number]; + mb->ovector[offset+1] = eptr - mb->start_subject; + + /* If this group is at or above the current highwater mark, ensure that + any groups between the current high water mark and this group are marked + unset and then update the high water mark. */ + + if (offset >= offset_top) + { + register PCRE2_SIZE *iptr = mb->ovector + offset_top; + register PCRE2_SIZE *iend = mb->ovector + offset; + while (iptr < iend) *iptr++ = PCRE2_UNSET; + offset_top = offset + 2; + } + } + ecode += 1 + IMM2_SIZE; + break; + + + /* End of the pattern, either real or forced. In an assertion ACCEPT, + update the last used pointer. */ + + case OP_ASSERT_ACCEPT: + if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; + + case OP_ACCEPT: + case OP_END: + + /* If we have matched an empty string, fail if not in an assertion and not + in a recursion if either PCRE2_NOTEMPTY is set, or if PCRE2_NOTEMPTY_ATSTART + is set and we have matched at the start of the subject. In both cases, + backtracking will then try other alternatives, if any. */ + + if (eptr == mstart && op != OP_ASSERT_ACCEPT && + mb->recursive == NULL && + ((mb->moptions & PCRE2_NOTEMPTY) != 0 || + ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 && + mstart == mb->start_subject + mb->start_offset))) + RRETURN(MATCH_NOMATCH); + + /* Otherwise, we have a match. */ + + mb->end_match_ptr = eptr; /* Record where we ended */ + mb->end_offset_top = offset_top; /* and how many extracts were taken */ + mb->start_match_ptr = mstart; /* and the start (\K can modify) */ + + /* For some reason, the macros don't work properly if an expression is + given as the argument to RRETURN when the heap is in use. */ + + rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; + RRETURN(rrc); + + /* Assertion brackets. Check the alternative branches in turn - the + matching won't pass the KET for an assertion. If any one branch matches, + the assertion is true. Lookbehind assertions have an OP_REVERSE item at the + start of each branch to move the current point backwards, so the code at + this level is identical to the lookahead case. When the assertion is part + of a condition, we want to return immediately afterwards. The caller of + this incarnation of the match() function will have set MATCH_CONDASSERT in + mb->match_function type, and one of these opcodes will be the first opcode + that is processed. We use a local variable that is preserved over calls to + match() to remember this case. */ + + case OP_ASSERT: + case OP_ASSERTBACK: + save_mark = mb->mark; + if ((mb->match_function_type & MATCH_CONDASSERT) != 0) + { + condassert = TRUE; + mb->match_function_type &= ~MATCH_CONDASSERT; + } + else condassert = FALSE; + + /* Loop for each branch */ + + do + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM4); + + /* A match means that the assertion is true; break out of the loop + that matches its alternatives. */ + + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) + { + mstart = mb->start_match_ptr; /* In case \K reset it */ + break; + } + + /* If not matched, restore the previous mark setting. */ + + mb->mark = save_mark; + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + /* Anything other than NOMATCH causes the entire assertion to fail, + passing back the return code. This includes COMMIT, SKIP, PRUNE and an + uncaptured THEN, which means they take their normal effect. This + consistent approach does not always have exactly the same effect as in + Perl. */ + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode, 1); + } + while (*ecode == OP_ALT); /* Continue for next alternative */ + + /* If we have tried all the alternative branches, the assertion has + failed. If not, we broke out after a match. */ + + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); + + /* If checking an assertion for a condition, return MATCH_MATCH. */ + + if (condassert) RRETURN(MATCH_MATCH); + + /* Continue from after a successful assertion, updating the offsets high + water mark, since extracts may have been taken during the assertion. */ + + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + ecode += 1 + LINK_SIZE; + offset_top = mb->end_offset_top; + continue; + + /* Negative assertion: all branches must fail to match for the assertion to + succeed. */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK_NOT: + save_mark = mb->mark; + if ((mb->match_function_type & MATCH_CONDASSERT) != 0) + { + condassert = TRUE; + mb->match_function_type &= ~MATCH_CONDASSERT; + } + else condassert = FALSE; + + /* Loop for each alternative branch. */ + + do + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM5); + mb->mark = save_mark; /* Always restore the mark setting */ + + switch(rrc) + { + case MATCH_MATCH: /* A successful match means */ + case MATCH_ACCEPT: /* the assertion has failed. */ + RRETURN(MATCH_NOMATCH); + + case MATCH_NOMATCH: /* Carry on with next branch */ + break; + + /* See comment in the code for capturing groups above about handling + THEN. */ + + case MATCH_THEN: + next_ecode = ecode + GET(ecode,1); + if (mb->start_match_ptr < next_ecode && + (*ecode == OP_ALT || *next_ecode == OP_ALT)) + { + rrc = MATCH_NOMATCH; + break; + } + /* Otherwise fall through. */ + + /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole + assertion to fail to match, without considering any more alternatives. + Failing to match means the assertion is true. This is a consistent + approach, but does not always have the same effect as in Perl. */ + + case MATCH_COMMIT: + case MATCH_SKIP: + case MATCH_SKIP_ARG: + case MATCH_PRUNE: + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + goto NEG_ASSERT_TRUE; /* Break out of alternation loop */ + + /* Anything else is an error */ + + default: + RRETURN(rrc); + } + + /* Continue with next branch */ + + ecode += GET(ecode,1); + } + while (*ecode == OP_ALT); + + /* All branches in the assertion failed to match. */ + + NEG_ASSERT_TRUE: + if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ + ecode += 1 + LINK_SIZE; /* Continue with current branch */ + continue; + + /* Move the subject pointer back. This occurs only at the start of + each branch of a lookbehind assertion. If we are too close to the start to + move back, this match function fails. When working with UTF-8 we move + back a number of characters, not bytes. */ + + case OP_REVERSE: + i = GET(ecode, 1); +#ifdef SUPPORT_UNICODE + if (utf) + { + while (i-- > 0) + { + if (eptr <= mb->start_subject) RRETURN(MATCH_NOMATCH); + eptr--; + BACKCHAR(eptr); + } + } + else +#endif + + /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ + + { + if (i > eptr - mb->start_subject) RRETURN(MATCH_NOMATCH); + eptr -= i; + } + + /* Save the earliest consulted character, then skip to next op code */ + + if (eptr < mb->start_used_ptr) mb->start_used_ptr = eptr; + ecode += 1 + LINK_SIZE; + break; + + /* The callout item calls an external function, if one is provided, passing + details of the match so far. This is mainly for debugging, though the + function is able to force a failure. */ + + case OP_CALLOUT: + case OP_CALLOUT_STR: + { + unsigned int callout_length = (*ecode == OP_CALLOUT) + ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE); + + if (mb->callout != NULL) + { + pcre2_callout_block cb; + cb.version = 1; + cb.callout_number = ecode[LINK_SIZE + 1]; + cb.capture_top = offset_top/2; + cb.capture_last = mb->capture_last & CAPLMASK; + cb.offset_vector = mb->ovector; + cb.mark = mb->nomatch_mark; + cb.subject = mb->start_subject; + cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject); + cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject); + cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject); + cb.pattern_position = GET(ecode, 1); + cb.next_item_length = GET(ecode, 1 + LINK_SIZE); + + if (*ecode == OP_CALLOUT) + { + cb.callout_number = ecode[1 + 2*LINK_SIZE]; + cb.callout_string_offset = 0; + cb.callout_string = NULL; + cb.callout_string_length = 0; + } + else + { + cb.callout_number = 0; + cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE); + cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1; + cb.callout_string_length = + callout_length - (1 + 4*LINK_SIZE) - 2; + } + + if ((rrc = mb->callout(&cb, mb->callout_data)) > 0) + RRETURN(MATCH_NOMATCH); + if (rrc < 0) RRETURN(rrc); + } + ecode += callout_length; + } + break; + + /* Recursion either matches the current regex, or some subexpression. The + offset data is the offset to the starting bracket from the start of the + whole pattern. (This is so that it works from duplicated subpatterns.) + + The state of the capturing groups is preserved over recursion, and + re-instated afterwards. We don't know how many are started and not yet + finished (offset_top records the completed total) so we just have to save + all the potential data. There may be up to 65535 such values, which is too + large to put on the stack, but using malloc for small numbers seems + expensive. As a compromise, the stack is used when there are no more than + OP_RECURSE_STACK_SAVE_MAX values to store; otherwise malloc is used. + + There are also other values that have to be saved. We use a chained + sequence of blocks that actually live on the stack. Thanks to Robin Houston + for the original version of this logic. It has, however, been hacked around + a lot, so he is not to blame for the current way it works. */ + + case OP_RECURSE: + { + ovecsave_frame *fr; + recursion_info *ri; + uint32_t recno; + + callpat = mb->start_code + GET(ecode, 1); + recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); + + /* Check for repeating a pattern recursion without advancing the subject + pointer. This should catch convoluted mutual recursions. (Some simple + cases are caught at compile time.) */ + + for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && eptr == ri->subject_position) + RRETURN(PCRE2_ERROR_RECURSELOOP); + + /* Add to "recursing stack" */ + + new_recursive.group_num = recno; + new_recursive.saved_capture_last = mb->capture_last; + new_recursive.subject_position = eptr; + new_recursive.prevrec = mb->recursive; + mb->recursive = &new_recursive; + + /* Where to continue from afterwards */ + + ecode += 1 + LINK_SIZE; + + /* When we are using the system stack for match() recursion we can call a + function that uses the system stack for preserving the ovector while + processing the pattern recursion, but only if the ovector is small + enough. */ + +#ifndef HEAP_MATCH_RECURSE + if (mb->offset_end <= OP_RECURSE_STACK_SAVE_MAX) + { + rrc = op_recurse_ovecsave(eptr, callpat, mstart, offset_top, mb, + eptrb, rdepth); + mb->recursive = new_recursive.prevrec; + if (rrc != MATCH_MATCH && rrc != MATCH_ACCEPT) RRETURN(rrc); + + /* Set where we got to in the subject, and reset the start, in case + it was changed by \K. This *is* propagated back out of a recursion, + for Perl compatibility. */ + + eptr = mb->end_match_ptr; + mstart = mb->start_match_ptr; + break; /* End of processing OP_RECURSE */ + } +#endif + /* If the ovector is too big, or if we are using the heap for match() + recursion, we have to use the heap for saving the ovector. Used ovecsave + frames are kept on a chain and re-used. This makes a small improvement in + execution time on Linux. */ + + if (mb->ovecsave_chain != NULL) + { + new_recursive.ovec_save = mb->ovecsave_chain->saved_ovec; + mb->ovecsave_chain = mb->ovecsave_chain->next; + } + else + { + fr = (ovecsave_frame *)(mb->memctl.malloc(sizeof(ovecsave_frame *) + + mb->offset_end * sizeof(PCRE2_SIZE), mb->memctl.memory_data)); + if (fr == NULL) RRETURN(PCRE2_ERROR_NOMEMORY); + new_recursive.ovec_save = fr->saved_ovec; + } + + memcpy(new_recursive.ovec_save, mb->ovector, + mb->offset_end * sizeof(PCRE2_SIZE)); + + /* Do the recursion. After processing each alternative, restore the + ovector data and the last captured value. This code has the same overall + logic as the code in the op_recurse_ovecsave() function, but is adapted + to use RMATCH/RRETURN and to release the heap block containing the saved + ovector. */ + + cbegroup = (*callpat >= OP_SBRA); + do + { + if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP; + RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, + mb, eptrb, RM6); + memcpy(mb->ovector, new_recursive.ovec_save, + mb->offset_end * sizeof(PCRE2_SIZE)); + mb->capture_last = new_recursive.saved_capture_last; + mb->recursive = new_recursive.prevrec; + + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) + { + fr = (ovecsave_frame *) + ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *)); + fr->next = mb->ovecsave_chain; + mb->ovecsave_chain = fr; + + /* Set where we got to in the subject, and reset the start, in case + it was changed by \K. This *is* propagated back out of a recursion, + for Perl compatibility. */ + + eptr = mb->end_match_ptr; + mstart = mb->start_match_ptr; + goto RECURSION_MATCHED; /* Exit loop; end processing */ + } + + /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a + recursion; they cause a NOMATCH for the entire recursion. These codes + are defined in a range that can be tested for. */ + + if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX) + { + rrc = MATCH_NOMATCH; + goto RECURSION_RETURN; + } + + /* Any return code other than NOMATCH is an error. */ + + if (rrc != MATCH_NOMATCH) goto RECURSION_RETURN; + mb->recursive = &new_recursive; + callpat += GET(callpat, 1); + } + while (*callpat == OP_ALT); + + RECURSION_RETURN: + mb->recursive = new_recursive.prevrec; + fr = (ovecsave_frame *) + ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *)); + fr->next = mb->ovecsave_chain; + mb->ovecsave_chain = fr; + RRETURN(rrc); + } + + RECURSION_MATCHED: + break; + + /* An alternation is the end of a branch; scan along to find the end of the + bracketed group and go to there. */ + + case OP_ALT: + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + break; + + /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group, + indicating that it may occur zero times. It may repeat infinitely, or not + at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets + with fixed upper repeat limits are compiled as a number of copies, with the + optional ones preceded by BRAZERO or BRAMINZERO. */ + + case OP_BRAZERO: + next_ecode = ecode + 1; + RMATCH(eptr, next_ecode, offset_top, mb, eptrb, RM10); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT); + ecode = next_ecode + 1 + LINK_SIZE; + break; + + case OP_BRAMINZERO: + next_ecode = ecode + 1; + do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT); + RMATCH(eptr, next_ecode + 1+LINK_SIZE, offset_top, mb, eptrb, RM11); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode++; + break; + + case OP_SKIPZERO: + next_ecode = ecode+1; + do next_ecode += GET(next_ecode,1); while (*next_ecode == OP_ALT); + ecode = next_ecode + 1 + LINK_SIZE; + break; + + /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything + here; just jump to the group, with allow_zero set TRUE. */ + + case OP_BRAPOSZERO: + op = *(++ecode); + allow_zero = TRUE; + if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE; + goto POSSESSIVE_NON_CAPTURE; + + /* End of a group, repeated or non-repeating. */ + + case OP_KET: + case OP_KETRMIN: + case OP_KETRMAX: + case OP_KETRPOS: + prev = ecode - GET(ecode, 1); + + /* If this was a group that remembered the subject start, in order to break + infinite repeats of empty string matches, retrieve the subject start from + the chain. Otherwise, set it NULL. */ + + if (*prev >= OP_SBRA || *prev == OP_ONCE) + { + saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ + eptrb = eptrb->epb_prev; /* Backup to previous group */ + } + else saved_eptr = NULL; + + /* If we are at the end of an assertion group or a non-capturing atomic + group, stop matching and return MATCH_MATCH, but record the current high + water mark for use by positive assertions. We also need to record the match + start in case it was changed by \K. */ + + if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) || + *prev == OP_ONCE_NC) + { + mb->end_match_ptr = eptr; /* For ONCE_NC */ + mb->end_offset_top = offset_top; + mb->start_match_ptr = mstart; + if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; + RRETURN(MATCH_MATCH); /* Sets mb->mark */ + } + + /* For capturing groups we have to check the group number back at the start + and if necessary complete handling an extraction by setting the offsets and + bumping the high water mark. Whole-pattern recursion is coded as a recurse + into group 0, so it won't be picked up here. Instead, we catch it when the + OP_END is reached. Other recursion is handled here. We just have to record + the current subject position and start match pointer and give a MATCH + return. */ + + if (*prev == OP_CBRA || *prev == OP_SCBRA || + *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS) + { + number = GET2(prev, 1+LINK_SIZE); + offset = number << 1; + + /* Handle a recursively called group. */ + + if (mb->recursive != NULL && mb->recursive->group_num == number) + { + mb->end_match_ptr = eptr; + mb->start_match_ptr = mstart; + if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; + RRETURN(MATCH_MATCH); + } + + /* Deal with capturing */ + + mb->capture_last = (mb->capture_last & OVFLMASK) | number; + if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else + { + /* If offset is greater than offset_top, it means that we are + "skipping" a capturing group, and that group's offsets must be marked + unset. In earlier versions of PCRE, all the offsets were unset at the + start of matching, but this doesn't work because atomic groups and + assertions can cause a value to be set that should later be unset. + Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as + part of the atomic group, but this is not on the final matching path, + so must be unset when 2 is set. (If there is no group 2, there is no + problem, because offset_top will then be 2, indicating no capture.) */ + + if (offset > offset_top) + { + register PCRE2_SIZE *iptr = mb->ovector + offset_top; + register PCRE2_SIZE *iend = mb->ovector + offset; + while (iptr < iend) *iptr++ = PCRE2_UNSET; + } + + /* Now make the extraction */ + + mb->ovector[offset] = mb->ovector[mb->offset_end - number]; + mb->ovector[offset+1] = eptr - mb->start_subject; + if (offset_top <= offset) offset_top = offset + 2; + } + } + + /* OP_KETRPOS is a possessive repeating ket. Remember the current position, + and return the MATCH_KETRPOS. This makes it possible to do the repeats one + at a time from the outer level, thus saving stack. This must precede the + empty string test - in this case that test is done at the outer level. */ + + if (*ecode == OP_KETRPOS) + { + mb->start_match_ptr = mstart; /* In case \K reset it */ + mb->end_match_ptr = eptr; + mb->end_offset_top = offset_top; + if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; + RRETURN(MATCH_KETRPOS); + } + + /* For an ordinary non-repeating ket, just continue at this level. This + also happens for a repeating ket if no characters were matched in the + group. This is the forcible breaking of infinite loops as implemented in + Perl 5.005. For a non-repeating atomic group that includes captures, + establish a backup point by processing the rest of the pattern at a lower + level. If this results in a NOMATCH return, pass MATCH_ONCE back to the + original OP_ONCE level, thereby bypassing intermediate backup points, but + resetting any captures that happened along the way. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM12); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + ecode += 1 + LINK_SIZE; /* Carry on at this level */ + break; + } + + /* The normal repeating kets try the rest of the pattern or restart from + the preceding bracket, in the appropriate order. In the second case, we can + use tail recursion to avoid using another stack frame, unless we have an + an atomic group or an unlimited repeat of a group that can match an empty + string. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM7); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (*prev == OP_ONCE) + { + RMATCH(eptr, prev, offset_top, mb, eptrb, RM8); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + if (*prev >= OP_SBRA) /* Could match an empty string */ + { + RMATCH(eptr, prev, offset_top, mb, eptrb, RM50); + RRETURN(rrc); + } + ecode = prev; + goto TAIL_RECURSE; + } + else /* OP_KETRMAX */ + { + RMATCH(eptr, prev, offset_top, mb, eptrb, RM13); + if (rrc == MATCH_ONCE && mb->once_target == prev) rrc = MATCH_NOMATCH; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM9); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->once_target = prev; + RRETURN(MATCH_ONCE); + } + ecode += 1 + LINK_SIZE; + goto TAIL_RECURSE; + } + /* Control never gets here */ + + /* Not multiline mode: start of subject assertion, unless notbol. */ + + case OP_CIRC: + if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject) + RRETURN(MATCH_NOMATCH); + + /* Start of subject assertion */ + + case OP_SOD: + if (eptr != mb->start_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Multiline mode: start of subject unless notbol, or after any newline + except for one at the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */ + + case OP_CIRCM: + if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject) + RRETURN(MATCH_NOMATCH); + if (eptr != mb->start_subject && + ((eptr == mb->end_subject && + (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) || + !WAS_NEWLINE(eptr))) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Start of match assertion */ + + case OP_SOM: + if (eptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Reset the start of match point */ + + case OP_SET_SOM: + mstart = eptr; + ecode++; + break; + + /* Multiline mode: assert before any newline, or before end of subject + unless noteol is set. */ + + case OP_DOLLM: + if (eptr < mb->end_subject) + { + if (!IS_NEWLINE(eptr)) + { + if (mb->partial != 0 && + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } + } + else + { + if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + } + ecode++; + break; + + /* Not multiline mode: assert before a terminating newline or before end of + subject unless noteol is set. */ + + case OP_DOLL: + if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); + if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; + + /* ... else fall through for endonly */ + + /* End of subject assertion (\z) */ + + case OP_EOD: + if (eptr < mb->end_subject) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + ecode++; + break; + + /* End of subject or ending \n assertion (\Z) */ + + case OP_EODN: + ASSERT_NL_OR_EOS: + if (eptr < mb->end_subject && + (!IS_NEWLINE(eptr) || eptr != mb->end_subject - mb->nllen)) + { + if (mb->partial != 0 && + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } + + /* Either at end of string or \n before end. */ + + SCHECK_PARTIAL(); + ecode++; + break; + + /* Word boundary assertions */ + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + { + + /* Find out if the previous and current characters are "word" characters. + It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to + be "non-word" characters. Remember the earliest consulted character for + partial matching. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + /* Get status of previous character */ + + if (eptr == mb->start_subject) prev_is_word = FALSE; else + { + PCRE2_SPTR lastptr = eptr - 1; + BACKCHAR(lastptr); + if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr; + GETCHAR(c, lastptr); + if ((mb->poptions & PCRE2_UCP) != 0) + { + if (c == '_') prev_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + prev_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else + prev_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0; + } + + /* Get status of next character */ + + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + cur_is_word = FALSE; + } + else + { + PCRE2_SPTR nextptr = eptr + 1; + FORWARDCHARTEST(nextptr, mb->end_subject); + if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr; + GETCHAR(c, eptr); + if ((mb->poptions & PCRE2_UCP) != 0) + { + if (c == '_') cur_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + cur_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else + cur_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0; + } + } + else +#endif /* SUPPORT UTF */ + + /* Not in UTF-8 mode, but we may still have PCRE2_UCP set, and for + consistency with the behaviour of \w we do use it in this case. */ + + { + /* Get status of previous character */ + + if (eptr == mb->start_subject) prev_is_word = FALSE; else + { + if (eptr <= mb->start_used_ptr) mb->start_used_ptr = eptr - 1; +#ifdef SUPPORT_UNICODE + if ((mb->poptions & PCRE2_UCP) != 0) + { + c = eptr[-1]; + if (c == '_') prev_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + prev_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + prev_is_word = MAX_255(eptr[-1]) + && ((mb->ctypes[eptr[-1]] & ctype_word) != 0); + } + + /* Get status of next character */ + + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + cur_is_word = FALSE; + } + else + { + if (eptr >= mb->last_used_ptr) mb->last_used_ptr = eptr + 1; +#ifdef SUPPORT_UNICODE + if ((mb->poptions & PCRE2_UCP) != 0) + { + c = *eptr; + if (c == '_') cur_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + cur_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + cur_is_word = MAX_255(*eptr) + && ((mb->ctypes[*eptr] & ctype_word) != 0); + } + } + + /* Now see if the situation is what we want */ + + if ((*ecode++ == OP_WORD_BOUNDARY)? + cur_is_word == prev_is_word : cur_is_word != prev_is_word) + RRETURN(MATCH_NOMATCH); + } + break; + + /* Match any single character type except newline; have to take care with + CRLF newlines and partial matching. */ + + case OP_ANY: + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (mb->partial != 0 && + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + + /* Fall through */ + + /* Match any single character whatsoever. */ + + case OP_ALLANY: + if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; +#ifdef SUPPORT_UNICODE + if (utf) ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); +#endif + ecode++; + break; + + /* Match a single code unit, even in UTF-8 mode. This opcode really does + match any code unit, even newline. (It really should be called ANYCODEUNIT, + of course - the byte name is from pre-16 bit days.) */ + + case OP_ANYBYTE: + if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; + ecode++; + break; + + case OP_NOT_DIGIT: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c < 256 && +#endif + (mb->ctypes[c] & ctype_digit) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_DIGIT: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c > 255 || +#endif + (mb->ctypes[c] & ctype_digit) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WHITESPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c < 256 && +#endif + (mb->ctypes[c] & ctype_space) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WHITESPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c > 255 || +#endif + (mb->ctypes[c] & ctype_space) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WORDCHAR: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c < 256 && +#endif + (mb->ctypes[c] & ctype_word) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WORDCHAR: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_WIDE_CHARS + c > 255 || +#endif + (mb->ctypes[c] & ctype_word) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_ANYNL: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + } + else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); + break; + } + ecode++; + break; + + case OP_NOT_HSPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ + default: break; + } + ecode++; + break; + + case OP_HSPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: break; /* Byte and multibyte cases */ + default: RRETURN(MATCH_NOMATCH); + } + ecode++; + break; + + case OP_NOT_VSPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + ecode++; + break; + + case OP_VSPACE: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + ecode++; + break; + +#ifdef SUPPORT_UNICODE + /* Check the next character by Unicode property. We will get here only + if the support is in the binary; otherwise a compile-time error occurs. */ + + case OP_PROP: + case OP_NOTPROP: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + { + const uint32_t *cp; + const ucd_record *prop = GET_UCD(c); + + switch(ecode[1]) + { + case PT_ANY: + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); + break; + + case PT_LAMP: + if ((prop->chartype == ucp_Lu || + prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_GC: + if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_PC: + if ((ecode[2] != prop->chartype) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_SC: + if ((ecode[2] != prop->script) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + break; + + /* These are specials */ + + case PT_ALNUM: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == + (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); + break; + } + break; + + case PT_WORD: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + ecode[2]; + for (;;) + { + if (c < *cp) + { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; } + if (c == *cp++) + { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } } + } + break; + + case PT_UCNC: + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + /* This should never occur */ + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + + ecode += 3; + } + break; + + /* Match an extended Unicode sequence. We will get here only if the support + is in the binary; otherwise a compile-time error occurs. */ + + case OP_EXTUNI: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < mb->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + ecode++; + break; +#endif /* SUPPORT_UNICODE */ + + + /* Match a back reference, possibly repeatedly. Look past the end of the + item to see if there is repeat information following. + + The OP_REF and OP_REFI opcodes are used for a reference to a numbered group + or to a non-duplicated named group. For a duplicated named group, OP_DNREF + and OP_DNREFI are used. In this case we must scan the list of groups to + which the name refers, and use the first one that is set. */ + + case OP_DNREF: + case OP_DNREFI: + caseless = op == OP_DNREFI; + { + int count = GET2(ecode, 1+IMM2_SIZE); + PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; + ecode += 1 + 2*IMM2_SIZE; + + /* Initializing 'offset' avoids a compiler warning in the REF_REPEAT + code. */ + + offset = 0; + while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) break; + slot += mb->name_entry_size; + } + } + goto REF_REPEAT; + + case OP_REF: + case OP_REFI: + caseless = op == OP_REFI; + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 1 + IMM2_SIZE; + + /* Set up for repetition, or handle the non-repeated case */ + + REF_REPEAT: + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + { + int rc = match_ref(offset, offset_top, eptr, mb, caseless, &length); + if (rc != 0) + { + if (rc > 0) eptr = mb->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + } + eptr += length; + continue; /* With the main loop */ + } + + /* Handle repeated back references. If a set group has length zero, just + continue with the main loop, because it matches however many times. For an + unset reference, if the minimum is zero, we can also just continue. We an + also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset + group be have as a zero-length group. For any other unset cases, carrying + on will result in NOMATCH. */ + + if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) + { + if (mb->ovector[offset] == mb->ovector[offset + 1]) continue; + } + else /* Group is not set */ + { + if (min == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0) + continue; + } + + /* First, ensure the minimum number of matches are present. We get back + the length of the reference string explicitly rather than passing the + address of eptr, so that eptr can be a register variable. */ + + for (i = 1; i <= min; i++) + { + PCRE2_SIZE slength; + int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); + if (rc != 0) + { + if (rc > 0) eptr = mb->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += slength; + } + + /* If min = max, continue at the same level without recursion. + They are not both allowed to be zero. */ + + if (min == max) continue; + + /* If minimizing, keep trying and advancing the pointer */ + + if (minimize) + { + for (fi = min;; fi++) + { + int rc; + PCRE2_SIZE slength; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM14); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); + if (rc != 0) + { + if (rc > 0) eptr = mb->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += slength; + } + /* Control never gets here */ + } + + /* If maximizing, find the longest string and work backwards, as long as + the matched lengths for each iteration are the same. */ + + else + { + BOOL samelengths = TRUE; + pp = eptr; + length = mb->ovector[offset+1] - mb->ovector[offset]; + + for (i = min; i < max; i++) + { + PCRE2_SIZE slength; + int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); + + if (rc != 0) + { + /* Can't use CHECK_PARTIAL because we don't want to update eptr in + the soft partial matching case. */ + + if (rc > 0 && mb->partial != 0 && + mb->end_subject > mb->start_used_ptr) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + break; + } + + if (slength != length) samelengths = FALSE; + eptr += slength; + } + + /* If the length matched for each repetition is the same as the length of + the captured group, we can easily work backwards. This is the normal + case. However, in caseless UTF-8 mode there are pairs of case-equivalent + characters whose lengths (in terms of code units) differ. However, this + is very rare, so we handle it by re-matching fewer and fewer times. */ + + if (samelengths) + { + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM15); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr -= length; + } + } + + /* The rare case of non-matching lengths. Re-scan the repetition for each + iteration. We know that match_ref() will succeed every time. */ + + else + { + max = i; + for (;;) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM68); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr == pp) break; /* Failed after minimal repetition */ + eptr = pp; + max--; + for (i = min; i < max; i++) + { + PCRE2_SIZE slength; + (void)match_ref(offset, offset_top, eptr, mb, caseless, &slength); + eptr += slength; + } + } + } + + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + /* Match a bit-mapped character class, possibly repeatedly. This op code is + used when all the characters in the class have values in the range 0-255, + and either the matching is caseful, or the characters are in the range + 0-127 when UTF-8 processing is enabled. The only difference between + OP_CLASS and OP_NCLASS occurs when a data character outside the range is + encountered. + + First, look past the end of the item to see if there is repeat information + following. Then obey similar code to character type repeats - written out + again for speed. */ + + case OP_NCLASS: + case OP_CLASS: + { + /* The data variable is saved across frames, so the byte map needs to + be stored there. */ +#define BYTE_MAP ((uint8_t *)data) + data = ecode + 1; /* Save for matching */ + ecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */ + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + c = *ecode++ - OP_CRSTAR; + if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; + else possessive = TRUE; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + minimize = (*ecode == OP_CRMINRANGE); + possessive = (*ecode == OP_CRPOSRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + c = *eptr++; +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM16); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM17); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + c = *eptr++; +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UNICODE + if (utf) + { + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c > 255) + { + if (op == OP_CLASS) break; + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; + eptr += len; + } + + if (possessive) continue; /* No backtracking */ + + for (;;) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM18); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + c = *eptr; +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) + { + if (op == OP_CLASS) break; + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; + eptr++; + } + + if (possessive) continue; /* No backtracking */ + + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM19); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } +#undef BYTE_MAP + } + /* Control never gets here */ + + + /* Match an extended character class. In the 8-bit library, this opcode is + encountered only when UTF-8 mode mode is supported. In the 16-bit and + 32-bit libraries, codepoints greater than 255 may be encountered even when + UTF is not supported. */ + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + { + data = ecode + 1 + LINK_SIZE; /* Save for matching */ + ecode += GET(ecode, 1); /* Advance past the item */ + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + c = *ecode++ - OP_CRSTAR; + if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; + else possessive = TRUE; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + minimize = (*ecode == OP_CRMINRANGE); + possessive = (*ecode == OP_CRPOSRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM20); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } +#ifdef SUPPORT_UNICODE + GETCHARLENTEST(c, eptr, len); +#else + c = *eptr; +#endif + if (!PRIV(xclass)(c, data, utf)) break; + eptr += len; + } + + if (possessive) continue; /* No backtracking */ + + for(;;) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM21); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ +#ifdef SUPPORT_UNICODE + if (utf) BACKCHAR(eptr); +#endif + } + RRETURN(MATCH_NOMATCH); + } + + /* Control never gets here */ + } +#endif /* End of XCLASS */ + + /* Match a single character, casefully */ + + case OP_CHAR: +#ifdef SUPPORT_UNICODE + if (utf) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + if (length > (PCRE2_SIZE)(mb->end_subject - eptr)) + { + CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ + RRETURN(MATCH_NOMATCH); + } + for (; length > 0; length--) + { + if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + if (mb->end_subject - eptr < 1) + { + SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ + RRETURN(MATCH_NOMATCH); + } + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* Match a single character, caselessly. If we are at the end of the + subject, give up immediately. */ + + case OP_CHARI: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + +#ifdef SUPPORT_UNICODE + if (utf) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + + /* If the pattern character's value is < 128, we have only one byte, and + we know that its other case must also be one byte long, so we can use the + fast lookup table. We know that there is at least one byte left in the + subject. */ + + if (fc < 128) + { + uint32_t cc = UCHAR21(eptr); + if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH); + ecode++; + eptr++; + } + + /* Otherwise we must pick up the subject character. Note that we cannot + use the value of "length" to check for sufficient bytes left, because the + other case of the character may have more or fewer bytes. */ + + else + { + uint32_t dc; + GETCHARINC(dc, eptr); + ecode += length; + + /* If we have Unicode property support, we can use it to test the other + case of the character, if there is one. */ + + if (fc != dc) + { +#ifdef SUPPORT_UNICODE + if (dc != UCD_OTHERCASE(fc)) +#endif + RRETURN(MATCH_NOMATCH); + } + } + } + else +#endif /* SUPPORT_UNICODE */ + + /* Not UTF mode */ + { + if (TABLE_GET(ecode[1], mb->lcc, ecode[1]) + != TABLE_GET(*eptr, mb->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + eptr++; + ecode += 2; + } + break; + + /* Match a single character repeatedly. */ + + case OP_EXACT: + case OP_EXACTI: + min = max = GET2(ecode, 1); + ecode += 1 + IMM2_SIZE; + goto REPEATCHAR; + + case OP_POSUPTO: + case OP_POSUPTOI: + possessive = TRUE; + /* Fall through */ + + case OP_UPTO: + case OP_UPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; + ecode += 1 + IMM2_SIZE; + goto REPEATCHAR; + + case OP_POSSTAR: + case OP_POSSTARI: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATCHAR; + + case OP_POSPLUS: + case OP_POSPLUSI: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATCHAR; + + case OP_POSQUERY: + case OP_POSQUERYI: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + goto REPEATCHAR; + + case OP_STAR: + case OP_STARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_PLUS: + case OP_PLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_QUERY: + case OP_QUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI); + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single-character matches. We first check + for the minimum number of characters. If the minimum equals the maximum, we + are done. Otherwise, if minimizing, check the rest of the pattern for a + match; if there isn't one, advance up to the maximum, one character at a + time. + + If maximizing, advance up to the maximum number of matching characters, + until eptr is past the end of the maximum run. If possessive, we are + then done (no backing up). Otherwise, match at this position; anything + other than no match is immediately returned. For nomatch, back up one + character, unless we are matching \R and the last thing matched was + \r\n, in which case, back up two bytes. When we reach the first optional + character position, we can save stack by doing a tail recurse. + + The various UTF/non-UTF and caseful/caseless cases are handled separately, + for speed. */ + + REPEATCHAR: +#ifdef SUPPORT_UNICODE + if (utf) + { + length = 1; + charptr = ecode; + GETCHARLEN(fc, ecode, length); + ecode += length; + + /* Handle multibyte character matching specially here. There is + support for caseless matching if UCP support is present. */ + + if (length > 1) + { + uint32_t othercase; + if (op >= OP_STARI && /* Caseless */ + (othercase = UCD_OTHERCASE(fc)) != fc) + oclength = PRIV(ord2utf)(othercase, occhars); + else oclength = 0; + + for (i = 1; i <= min; i++) + { + if (eptr <= mb->end_subject - length && + memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; + else if (oclength > 0 && + eptr <= mb->end_subject - oclength && + memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; + else + { + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + } + + if (min == max) continue; + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM22); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr <= mb->end_subject - length && + memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; + else if (oclength > 0 && + eptr <= mb->end_subject - oclength && + memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; + else + { + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr <= mb->end_subject - length && + memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; + else if (oclength > 0 && + eptr <= mb->end_subject - oclength && + memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; + else + { + CHECK_PARTIAL(); + break; + } + } + + if (possessive) continue; /* No backtracking */ + + /* After \C in UTF mode, pp might be in the middle of a Unicode + character. Use <= pp to ensure backtracking doesn't go too far. */ + + for(;;) + { + if (eptr <= pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM23); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + BACKCHAR(eptr); + } + } + /* Control never gets here */ + } + + /* If the length of a UTF-8 character is 1, we fall through here, and + obey the code as for non-UTF-8 characters below, though in this case the + value of fc will always be < 128. */ + } + else +#endif /* SUPPORT_UNICODE */ + + /* When not in UTF-8 mode, load a single-byte character. */ + fc = *ecode++; + + /* The value of fc at this point is always one character, though we may + or may not be in UTF mode. The code is duplicated for the caseless and + caseful cases, for speed, since matching characters is likely to be quite + common. First, ensure the minimum number of matches are present. If min = + max, continue at the same level without recursing. Otherwise, if + minimizing, keep trying the rest of the expression and advancing one + matching character if failing, up to the maximum. Alternatively, if + maximizing, find the maximum number of characters and work backwards. */ + + if (op >= OP_STARI) /* Caseless */ + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + /* fc must be < 128 if UTF is enabled. */ + foc = mb->fcc[fc]; +#else +#ifdef SUPPORT_UNICODE + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); + else +#endif /* SUPPORT_UNICODE */ + foc = TABLE_GET(fc, mb->fcc, fc); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + + for (i = 1; i <= min; i++) + { + uint32_t cc; /* Faster than PCRE2_UCHAR */ + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21TEST(eptr); + if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + eptr++; + } + if (min == max) continue; + if (minimize) + { + for (fi = min;; fi++) + { + uint32_t cc; /* Faster than PCRE2_UCHAR */ + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM24); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21TEST(eptr); + if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + eptr++; + } + /* Control never gets here */ + } + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + uint32_t cc; /* Faster than PCRE2_UCHAR */ + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + cc = UCHAR21TEST(eptr); + if (fc != cc && foc != cc) break; + eptr++; + } + if (possessive) continue; /* No backtracking */ + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM25); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + /* Control never gets here */ + } + } + + /* Caseful comparisons (includes all multi-byte characters) */ + + else + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); + } + + if (min == max) continue; + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM26); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc != UCHAR21TEST(eptr)) break; + eptr++; + } + if (possessive) continue; /* No backtracking */ + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM27); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + /* Control never gets here */ + } + } + /* Control never gets here */ + + /* Match a negated single one-byte character. The character we are + checking can be multibyte. */ + + case OP_NOT: + case OP_NOTI: + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t ch, och; + + ecode++; + GETCHARINC(ch, ecode); + GETCHARINC(c, eptr); + + if (op == OP_NOT) + { + if (ch == c) RRETURN(MATCH_NOMATCH); + } + else + { + if (ch > 127) + och = UCD_OTHERCASE(ch); + else + och = TABLE_GET(ch, mb->fcc, ch); + if (ch == c || och == c) RRETURN(MATCH_NOMATCH); + } + } + else +#endif /* SUPPORT_UNICODE */ + { + register uint32_t ch = ecode[1]; + c = *eptr++; + if (ch == c || (op == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == c)) + RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* Match a negated single one-byte character repeatedly. This is almost a + repeat of the code for a repeated single character, but I haven't found a + nice way of commoning these up that doesn't require a test of the + positive/negative option for each character match. Maybe that wouldn't add + very much to the time taken, but character matching *is* what this is all + about... */ + + case OP_NOTEXACT: + case OP_NOTEXACTI: + min = max = GET2(ecode, 1); + ecode += 1 + IMM2_SIZE; + goto REPEATNOTCHAR; + + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; + ecode += 1 + IMM2_SIZE; + goto REPEATNOTCHAR; + + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + possessive = TRUE; + min = 0; + max = GET2(ecode, 1); + ecode += 1 + IMM2_SIZE; + goto REPEATNOTCHAR; + + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR); + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single-byte matches. */ + + REPEATNOTCHAR: + GETCHARINCTEST(fc, ecode); + + /* The code is duplicated for the caseless and caseful cases, for speed, + since matching characters is likely to be quite common. First, ensure the + minimum number of matches are present. If min = max, continue at the same + level without recursing. Otherwise, if minimizing, keep trying the rest of + the expression and advancing one matching character if failing, up to the + maximum. Alternatively, if maximizing, find the maximum number of + characters and work backwards. */ + + if (op >= OP_NOTSTARI) /* Caseless */ + { +#ifdef SUPPORT_UNICODE + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); + else +#endif /* SUPPORT_UNICODE */ + foc = TABLE_GET(fc, mb->fcc, fc); + +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif /* SUPPORT_UNICODE */ + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; + } + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM28); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif /*SUPPORT_UNICODE */ + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM29); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(d, eptr, len); + if (fc == d || (uint32_t)foc == d) break; + eptr += len; + } + if (possessive) continue; /* No backtracking */ + + /* After \C in UTF mode, pp might be in the middle of a Unicode + character. Use <= pp to ensure backtracking doesn't go too far. */ + + for(;;) + { + if (eptr <= pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM30); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + BACKCHAR(eptr); + } + } + else +#endif /* SUPPORT_UNICODE */ + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc == *eptr || foc == *eptr) break; + eptr++; + } + if (possessive) continue; /* No backtracking */ + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM31); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + /* Control never gets here */ + } + } + + /* Caseful comparisons */ + + else + { +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); + } + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM32); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM33); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UNICODE + if (utf) + { + register uint32_t d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(d, eptr, len); + if (fc == d) break; + eptr += len; + } + if (possessive) continue; /* No backtracking */ + + /* After \C in UTF mode, pp might be in the middle of a Unicode + character. Use <= pp to ensure backtracking doesn't go too far. */ + + for(;;) + { + if (eptr <= pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM34); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + BACKCHAR(eptr); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc == *eptr) break; + eptr++; + } + if (possessive) continue; /* No backtracking */ + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM35); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + /* Control never gets here */ + } + } + /* Control never gets here */ + + /* Match a single character type repeatedly; several different opcodes + share code. This is very similar to the code for single characters, but we + repeat it in the interests of efficiency. */ + + case OP_TYPEEXACT: + min = max = GET2(ecode, 1); + minimize = TRUE; + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_TYPEMINUPTO; + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPEPOSSTAR: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSPLUS: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSQUERY: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSUPTO: + possessive = TRUE; + min = 0; + max = GET2(ecode, 1); + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + c = *ecode++ - OP_TYPESTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single character type matches. Note that + in UTF-8 mode, '.' matches a character of any length, but for the other + character types, the valid characters are all one-byte long. */ + + REPEATTYPE: + ctype = *ecode++; /* Code for the character type */ + +#ifdef SUPPORT_UNICODE + if (ctype == OP_PROP || ctype == OP_NOTPROP) + { + prop_fail_result = ctype == OP_NOTPROP; + prop_type = *ecode++; + prop_value = *ecode++; + } + else prop_type = -1; +#endif + + /* First, ensure the minimum number of matches are present. Use inline + code for maximizing the speed, and do the type test once at the start + (i.e. keep it out of the loop). Separate the UTF-8 code completely as that + is tidier. Also separate the UCP code, which can be the same for both UTF-8 + and single-bytes. */ + + if (min > 0) + { +#ifdef SUPPORT_UNICODE + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + } + break; + + case PT_LAMP: + for (i = 1; i <= min; i++) + { + int chartype; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_GC: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_PC: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_SC: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_ALNUM: + for (i = 1; i <= min; i++) + { + int category; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + break; + } + } + break; + + case PT_WORD: + for (i = 1; i <= min; i++) + { + int category; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_CLIST: + for (i = 1; i <= min; i++) + { + const uint32_t *cp; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } + if (c == *cp++) + { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } + } + } + break; + + case PT_UCNC: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + /* This should not occur */ + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < mb->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + } + + else +#endif /* SUPPORT_UNICODE */ + +/* Handle all other cases when the coding is UTF-8 */ + +#ifdef SUPPORT_UNICODE + if (utf) switch(ctype) + { + case OP_ANY: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (mb->partial != 0 && + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + UCHAR21(eptr) == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + break; + + case OP_ALLANY: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + break; + + case OP_ANYBYTE: + if (eptr > mb->end_subject - min) RRETURN(MATCH_NOMATCH); + eptr += min; + break; + + case OP_ANYNL: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); + break; + } + } + break; + + case OP_NOT_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ + default: break; + } + } + break; + + case OP_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + HSPACE_CASES: break; /* Byte and multibyte cases */ + default: RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_NOT_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + } + break; + + case OP_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c < 128 && (mb->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + { + uint32_t cc; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21(eptr); + if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + { + uint32_t cc; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21(eptr); + if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + { + uint32_t cc; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21(eptr); + if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + { + uint32_t cc; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21(eptr); + if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + { + uint32_t cc; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = UCHAR21(eptr); + if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } /* End switch(ctype) */ + + else +#endif /* SUPPORT_UNICODE */ + + /* Code for the non-UTF-8 case for minimum matching of operators other + than OP_PROP and OP_NOTPROP. */ + + switch(ctype) + { + case OP_ANY: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (mb->partial != 0 && + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + eptr++; + } + break; + + case OP_ALLANY: + if (eptr > mb->end_subject - min) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += min; + break; + + case OP_ANYBYTE: + if (eptr > mb->end_subject - min) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += min; + break; + + case OP_ANYNL: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#if PCRE2_CODE_UNIT_WIDTH != 8 + case 0x2028: + case 0x2029: +#endif + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); + break; + } + } + break; + + case OP_NOT_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: break; + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + break; + } + } + break; + + case OP_NOT_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + default: break; + } + } + break; + + case OP_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + break; + } + } + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + } + + /* If min = max, continue at the same level without recursing */ + + if (min == max) continue; + + /* If minimizing, we have to test the rest of the pattern before each + subsequent match. Again, separate the UTF-8 case for speed, and also + separate the UCP cases. */ + + if (minimize) + { +#ifdef SUPPORT_UNICODE + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM36); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_LAMP: + for (fi = min;; fi++) + { + int chartype; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM37); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_GC: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM38); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_PC: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM39); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_SC: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM40); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_ALNUM: + for (fi = min;; fi++) + { + int category; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM59); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM61); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + break; + } + } + /* Control never gets here */ + + case PT_WORD: + for (fi = min;; fi++) + { + int category; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM62); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || + category == ucp_N || + c == CHAR_UNDERSCORE) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_CLIST: + for (fi = min;; fi++) + { + const uint32_t *cp; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM67); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } + if (c == *cp++) + { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } + } + } + /* Control never gets here */ + + case PT_UCNC: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM60); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + /* This should never occur */ + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM41); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < mb->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + } + else +#endif /* SUPPORT_UNICODE */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM42); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (ctype == OP_ANY && IS_NEWLINE(eptr)) + RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + switch(ctype) + { + case OP_ANY: /* This is the non-NL case */ + if (mb->partial != 0 && /* Take care with CRLF partial */ + eptr >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + break; + + case OP_ALLANY: + case OP_ANYBYTE: + break; + + case OP_ANYNL: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + case CHAR_CR: + if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); + break; + } + break; + + case OP_NOT_HSPACE: + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + break; + + case OP_HSPACE: + switch(c) + { + HSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + break; + + case OP_NOT_VSPACE: + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + break; + + case OP_VSPACE: + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + break; + + case OP_NOT_DIGIT: + if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if (c >= 256 || (mb->ctypes[c] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + if (c >= 256 || (mb->ctypes[c] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM43); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (ctype == OP_ANY && IS_NEWLINE(eptr)) + RRETURN(MATCH_NOMATCH); + c = *eptr++; + switch(ctype) + { + case OP_ANY: /* This is the non-NL case */ + if (mb->partial != 0 && /* Take care with CRLF partial */ + eptr >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + break; + + case OP_ALLANY: + case OP_ANYBYTE: + break; + + case OP_ANYNL: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + case CHAR_CR: + if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#if PCRE2_CODE_UNIT_WIDTH != 8 + case 0x2028: + case 0x2029: +#endif + if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); + break; + } + break; + + case OP_NOT_HSPACE: + switch(c) + { + default: break; + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_HSPACE: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + break; + } + break; + + case OP_NOT_VSPACE: + switch(c) + { + default: break; + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_VSPACE: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + break; + } + break; + + case OP_NOT_DIGIT: + if (MAX_255(c) && (mb->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if (!MAX_255(c) || (mb->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if (MAX_255(c) && (mb->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + if (!MAX_255(c) || (mb->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + if (MAX_255(c) && (mb->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if (!MAX_255(c) || (mb->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + } + } + /* Control never gets here */ + } + + /* If maximizing, it is worth using inline code for speed, doing the type + test once at the start (i.e. keep it out of the loop). Again, keep the + UTF-8 and UCP stuff separate. */ + + else + { + pp = eptr; /* Remember where we started */ + +#ifdef SUPPORT_UNICODE + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if (prop_fail_result) break; + eptr+= len; + } + break; + + case PT_LAMP: + for (i = min; i < max; i++) + { + int chartype; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_GC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_PC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_SC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_ALNUM: + for (i = min; i < max; i++) + { + int category; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + break; + eptr+= len; + } + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) goto ENDLOOP99; /* Break the loop */ + break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + goto ENDLOOP99; /* Break the loop */ + break; + } + eptr+= len; + } + ENDLOOP99: + break; + + case PT_WORD: + for (i = min; i < max; i++) + { + int category; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || + c == CHAR_UNDERSCORE) == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_CLIST: + for (i = min; i < max; i++) + { + const uint32_t *cp; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else goto GOT_MAX; } + if (c == *cp++) + { if (prop_fail_result) goto GOT_MAX; else break; } + } + eptr += len; + } + GOT_MAX: + break; + + case PT_UCNC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + break; + eptr += len; + } + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run */ + + if (possessive) continue; /* No backtracking */ + + /* After \C in UTF mode, pp might be in the middle of a Unicode + character. Use <= pp to ensure backtracking doesn't go too far. */ + + for(;;) + { + if (eptr <= pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM44); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + if (utf) BACKCHAR(eptr); + } + } + + /* Match extended Unicode grapheme clusters. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < mb->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + + /* eptr is now past the end of the maximum run */ + + if (possessive) continue; /* No backtracking */ + + /* We use <= pp rather than == pp to detect the start of the run while + backtracking because the use of \C in UTF mode can cause BACKCHAR to + move back past pp. This is just palliative; the use of \C in UTF mode + is fraught with danger. */ + + for(;;) + { + int lgb, rgb; + PCRE2_SPTR fptr; + + if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */ + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM45); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + + /* Backtracking over an extended grapheme cluster involves inspecting + the previous two characters (if present) to see if a break is + permitted between them. */ + + eptr--; + if (!utf) c = *eptr; else + { + BACKCHAR(eptr); + GETCHAR(c, eptr); + } + rgb = UCD_GRAPHBREAK(c); + + for (;;) + { + if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */ + fptr = eptr - 1; + if (!utf) c = *fptr; else + { + BACKCHAR(fptr); + GETCHAR(c, fptr); + } + lgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + eptr = fptr; + rgb = lgb; + } + } + } + + else +#endif /* SUPPORT_UNICODE */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + switch(ctype) + { + case OP_ANY: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (IS_NEWLINE(eptr)) break; + if (mb->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + UCHAR21(eptr) == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + break; + + case OP_ALLANY: + if (max < INT_MAX) + { + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + eptr++; + ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); + } + } + else + { + eptr = mb->end_subject; /* Unlimited UTF-8 repeat */ + SCHECK_PARTIAL(); + } + break; + + /* The byte case is the same as non-UTF8 */ + + case OP_ANYBYTE: + c = max - min; + if (c > (uint32_t)(mb->end_subject - eptr)) + { + eptr = mb->end_subject; + SCHECK_PARTIAL(); + } + else eptr += c; + break; + + case OP_ANYNL: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c == CHAR_CR) + { + if (++eptr >= mb->end_subject) break; + if (UCHAR21(eptr) == CHAR_LF) eptr++; + } + else + { + if (c != CHAR_LF && + (mb->bsr_convention == PCRE2_BSR_ANYCRLF || + (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL +#ifndef EBCDIC + && c != 0x2028 && c != 0x2029 +#endif /* Not EBCDIC */ + ))) + break; + eptr += len; + } + } + break; + + case OP_NOT_HSPACE: + case OP_HSPACE: + for (i = min; i < max; i++) + { + BOOL gotspace; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + switch(c) + { + HSPACE_CASES: gotspace = TRUE; break; + default: gotspace = FALSE; break; + } + if (gotspace == (ctype == OP_NOT_HSPACE)) break; + eptr += len; + } + break; + + case OP_NOT_VSPACE: + case OP_VSPACE: + for (i = min; i < max; i++) + { + BOOL gotspace; + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + switch(c) + { + VSPACE_CASES: gotspace = TRUE; break; + default: gotspace = FALSE; break; + } + if (gotspace == (ctype == OP_NOT_VSPACE)) break; + eptr += len; + } + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) break; + eptr+= len; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(mb->ctypes[c] & ctype_digit) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) break; + eptr+= len; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(mb->ctypes[c] & ctype_space) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) break; + eptr+= len; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) break; + eptr+= len; + } + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + + if (possessive) continue; /* No backtracking */ + + /* After \C in UTF mode, pp might be in the middle of a Unicode + character. Use <= pp to ensure backtracking doesn't go too far. */ + + for(;;) + { + if (eptr <= pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM46); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + BACKCHAR(eptr); + if (ctype == OP_ANYNL && eptr > pp && UCHAR21(eptr) == CHAR_NL && + UCHAR21(eptr - 1) == CHAR_CR) eptr--; + } + } + else +#endif /* SUPPORT_UNICODE */ + /* Not UTF mode */ + { + switch(ctype) + { + case OP_ANY: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (IS_NEWLINE(eptr)) break; + if (mb->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= mb->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + mb->hitend = TRUE; + if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); + } + eptr++; + } + break; + + case OP_ALLANY: + case OP_ANYBYTE: + c = max - min; + if (c > (uint32_t)(mb->end_subject - eptr)) + { + eptr = mb->end_subject; + SCHECK_PARTIAL(); + } + else eptr += c; + break; + + case OP_ANYNL: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + c = *eptr; + if (c == CHAR_CR) + { + if (++eptr >= mb->end_subject) break; + if (*eptr == CHAR_LF) eptr++; + } + else + { + if (c != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF || + (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL +#if PCRE2_CODE_UNIT_WIDTH != 8 + && c != 0x2028 && c != 0x2029 +#endif + ))) break; + eptr++; + } + } + break; + + case OP_NOT_HSPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: eptr++; break; + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + goto ENDLOOP00; + } + } + ENDLOOP00: + break; + + case OP_HSPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: goto ENDLOOP01; + HSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + HSPACE_MULTIBYTE_CASES: +#endif + eptr++; break; + } + } + ENDLOOP01: + break; + + case OP_NOT_VSPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: eptr++; break; + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + goto ENDLOOP02; + } + } + ENDLOOP02: + break; + + case OP_VSPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: goto ENDLOOP03; + VSPACE_BYTE_CASES: +#if PCRE2_CODE_UNIT_WIDTH != 8 + VSPACE_MULTIBYTE_CASES: +#endif + eptr++; break; + } + } + ENDLOOP03: + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) break; + eptr++; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) break; + eptr++; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) break; + eptr++; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) break; + eptr++; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) break; + eptr++; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) break; + eptr++; + } + break; + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + + if (possessive) continue; /* No backtracking */ + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; + RMATCH(eptr, ecode, offset_top, mb, eptrb, RM47); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF && + eptr[-1] == CHAR_CR) eptr--; + } + } + + /* Control never gets here */ + } + + /* There's been some horrible disaster. Arrival here can only mean there is + something seriously wrong in the code above or the OP_xxx definitions. */ + + default: + RRETURN(PCRE2_ERROR_INTERNAL); + } + + /* Do not stick any code in here without much thought; it is assumed + that "continue" in the code above comes out to here to repeat the main + loop. */ + + } /* End of main loop */ +/* Control never reaches here */ + + +/* When compiling to use the heap rather than the stack for recursive calls to +match(), the RRETURN() macro jumps here. The number that is saved in +frame->Xwhere indicates which label we actually want to return to. */ + +#ifdef HEAP_MATCH_RECURSE +#define LBL(val) case val: goto L_RM##val; +HEAP_RETURN: +switch (frame->Xwhere) + { + LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8) + LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) + LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) + LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) + LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) + LBL(65) LBL(66) LBL(68) +#ifdef SUPPORT_WIDE_CHARS + LBL(20) LBL(21) +#endif +#ifdef SUPPORT_UNICODE + LBL(16) LBL(18) + LBL(22) LBL(23) LBL(28) LBL(30) + LBL(32) LBL(34) LBL(42) LBL(46) + LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) + LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) +#endif /* SUPPORT_UNICODE */ + default: + return PCRE2_ERROR_INTERNAL; + } +#undef LBL +#endif /* HEAP_MATCH_RECURSE */ +} + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +Undefine all the macros that were defined above to handle this. */ + +#ifdef HEAP_MATCH_RECURSE +#undef eptr +#undef ecode +#undef mstart +#undef offset_top +#undef eptrb +#undef flags + +#undef callpat +#undef charptr +#undef data +#undef next_ecode +#undef pp +#undef prev +#undef saved_eptr + +#undef new_recursive + +#undef cur_is_word +#undef condition +#undef prev_is_word + +#undef ctype +#undef length +#undef max +#undef min +#undef number +#undef offset +#undef op +#undef save_capture_last +#undef save_offset1 +#undef save_offset2 +#undef save_offset3 + +#undef newptrb +#endif /* HEAP_MATCH_RECURSE */ + +/* These two are defined as macros in both cases */ + +#undef fc +#undef fi + +/*************************************************************************** +***************************************************************************/ + + +#ifdef HEAP_MATCH_RECURSE +/************************************************* +* Release allocated heap frames * +*************************************************/ + +/* This function releases all the allocated frames. The base frame is on the +machine stack, and so must not be freed. + +Argument: + frame_base the address of the base frame + mb the match block + +Returns: nothing +*/ + +static void +release_match_heapframes (heapframe *frame_base, match_block *mb) +{ +heapframe *nextframe = frame_base->Xnextframe; +while (nextframe != NULL) + { + heapframe *oldframe = nextframe; + nextframe = nextframe->Xnextframe; + mb->stack_memctl.free(oldframe, mb->stack_memctl.memory_data); + } +} +#endif /* HEAP_MATCH_RECURSE */ + + + +/************************************************* +* Match a Regular Expression * +*************************************************/ + +/* This function applies a compiled pattern to a subject string and picks out +portions of the string if it matches. Two elements in the vector are set for +each substring: the offsets to the start and end of the substring. + +Arguments: + code points to the compiled expression + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + match_data points to a match_data block + mcontext points a PCRE2 context + +Returns: > 0 => success; value is the number of ovector pairs filled + = 0 => success, but ovector is not big enough + -1 => failed to match (PCRE2_ERROR_NOMATCH) + -2 => partial match (PCRE2_ERROR_PARTIAL) + < -2 => some kind of unexpected problem +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, + PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, + pcre2_match_context *mcontext) +{ +int rc; +int ocount; + +const uint8_t *start_bits = NULL; + +const pcre2_real_code *re = (const pcre2_real_code *)code; + +BOOL anchored; +BOOL firstline; +BOOL has_first_cu = FALSE; +BOOL has_req_cu = FALSE; +BOOL startline; +BOOL using_temporary_offsets = FALSE; +BOOL utf; + +PCRE2_UCHAR first_cu = 0; +PCRE2_UCHAR first_cu2 = 0; +PCRE2_UCHAR req_cu = 0; +PCRE2_UCHAR req_cu2 = 0; + +PCRE2_SPTR bumpalong_limit; +PCRE2_SPTR end_subject; +PCRE2_SPTR start_match = subject + start_offset; +PCRE2_SPTR req_cu_ptr = start_match - 1; +PCRE2_SPTR start_partial = NULL; +PCRE2_SPTR match_partial = NULL; + +/* We need to have mb pointing to a match block, because the IS_NEWLINE macro +is used below, and it expects NLBLOCK to be defined as a pointer. */ + +match_block actual_match_block; +match_block *mb = &actual_match_block; + +#ifdef HEAP_MATCH_RECURSE +heapframe frame_zero; +frame_zero.Xprevframe = NULL; /* Marks the top level */ +frame_zero.Xnextframe = NULL; /* None are allocated yet */ +mb->match_frames_base = &frame_zero; +#endif + +/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated +subject string. */ + +if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); +end_subject = subject + length; + +/* Plausibility checks */ + +if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; +if (code == NULL || subject == NULL || match_data == NULL) + return PCRE2_ERROR_NULL; +if (start_offset > length) return PCRE2_ERROR_BADOFFSET; + +/* Check that the first field in the block is the magic number. */ + +if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; + +/* Check the code unit width. */ + +if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) + return PCRE2_ERROR_BADMODE; + +/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the +options variable for this function. Users of PCRE2 who are not calling the +function directly would like to have a way of setting these flags, in the same +way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with +constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and +(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be +transferred to the options for this function. The bits are guaranteed to be +adjacent, but do not have the same values. This bit of Boolean trickery assumes +that the match-time bits are not more significant than the flag bits. If by +accident this is not the case, a compile-time division by zero error will +occur. */ + +#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET) +#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART) +options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1))); +#undef FF +#undef OO + +/* A NULL match context means "use a default context" */ + +if (mcontext == NULL) + mcontext = (pcre2_match_context *)(&PRIV(default_match_context)); + +/* These two settings are used in the code for checking a UTF string that +follows immediately afterwards. Other values in the mb block are used only +during interpretive pcre_match() processing, not when the JIT support is in +use, so they are set up later. */ + +utf = (re->overall_options & PCRE2_UTF) != 0; +mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 : + ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0; + +/* Check a UTF string for validity if required. For 8-bit and 16-bit strings, +we must also check that a starting offset does not point into the middle of a +multiunit character. We check only the portion of the subject that is going to +be inspected during matching - from the offset minus the maximum back reference +to the given length. This saves time when a small part of a large subject is +being matched by the use of a starting offset. Note that the maximum lookbehind +is a number of characters, not code units. */ + +#ifdef SUPPORT_UNICODE +if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) + { + PCRE2_SPTR check_subject = start_match; /* start_match includes offset */ + + if (start_offset > 0) + { +#if PCRE2_CODE_UNIT_WIDTH != 32 + unsigned int i; + if (start_match < end_subject && NOT_FIRSTCU(*start_match)) + return PCRE2_ERROR_BADUTFOFFSET; + for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--) + { + check_subject--; + while (check_subject > subject && +#if PCRE2_CODE_UNIT_WIDTH == 8 + (*check_subject & 0xc0) == 0x80) +#else /* 16-bit */ + (*check_subject & 0xfc00) == 0xdc00) +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + check_subject--; + } +#else + /* In the 32-bit library, one code unit equals one character. However, + we cannot just subtract the lookbehind and then compare pointers, because + a very large lookbehind could create an invalid pointer. */ + + if (start_offset >= re->max_lookbehind) + check_subject -= re->max_lookbehind; + else + check_subject = subject; +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + } + + /* Validate the relevant portion of the subject. After an error, adjust the + offset to be an absolute offset in the whole string. */ + + match_data->rc = PRIV(valid_utf)(check_subject, + length - (check_subject - subject), &(match_data->startchar)); + if (match_data->rc != 0) + { + match_data->startchar += check_subject - subject; + return match_data->rc; + } + } +#endif /* SUPPORT_UNICODE */ + +/* It is an error to set an offset limit without setting the flag at compile +time. */ + +if (mcontext->offset_limit != PCRE2_UNSET && + (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) + return PCRE2_ERROR_BADOFFSETLIMIT; + +/* If the pattern was successfully studied with JIT support, run the JIT +executable instead of the rest of this function. Most options must be set at +compile time for the JIT code to be usable. Fallback to the normal code path if +an unsupported option is set or if JIT returns BADOPTION (which means that the +selected normal or partial matching mode was not compiled). */ + +#ifdef SUPPORT_JIT +if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0) + { + rc = pcre2_jit_match(code, subject, length, start_offset, options, + match_data, mcontext); + if (rc != PCRE2_ERROR_JIT_BADOPTION) return rc; + } +#endif + +/* Carry on with non-JIT matching. */ + +anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0; +firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +startline = (re->flags & PCRE2_STARTLINE) != 0; +bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? + end_subject : subject + mcontext->offset_limit; + +/* Fill in the fields in the match block. */ + +mb->callout = mcontext->callout; +mb->callout_data = mcontext->callout_data; +mb->memctl = mcontext->memctl; +#ifdef HEAP_MATCH_RECURSE +mb->stack_memctl = mcontext->stack_memctl; +#endif + +mb->start_subject = subject; +mb->start_offset = start_offset; +mb->end_subject = end_subject; +mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0; + +mb->moptions = options; /* Match options */ +mb->poptions = re->overall_options; /* Pattern options */ + +mb->ignore_skip_arg = 0; +mb->mark = mb->nomatch_mark = NULL; /* In case never set */ +mb->recursive = NULL; /* No recursion at top level */ +mb->ovecsave_chain = NULL; /* No ovecsave blocks yet */ +mb->hitend = FALSE; + +/* The name table is needed for finding all the numbers associated with a +given name, for condition testing. The code follows the name table. */ + +mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); +mb->name_count = re->name_count; +mb->name_entry_size = re->name_entry_size; +mb->start_code = mb->name_table + re->name_count * re->name_entry_size; + +/* Limits set in the pattern override the match context only if they are +smaller. */ + +mb->match_limit = (mcontext->match_limit < re->limit_match)? + mcontext->match_limit : re->limit_match; +mb->match_limit_recursion = (mcontext->recursion_limit < re->limit_recursion)? + mcontext->recursion_limit : re->limit_recursion; + +/* Pointers to the individual character tables */ + +mb->lcc = re->tables + lcc_offset; +mb->fcc = re->tables + fcc_offset; +mb->ctypes = re->tables + ctypes_offset; + +/* Process the \R and newline settings. */ + +mb->bsr_convention = re->bsr_convention; +mb->nltype = NLTYPE_FIXED; +switch(re->newline_convention) + { + case PCRE2_NEWLINE_CR: + mb->nllen = 1; + mb->nl[0] = CHAR_CR; + break; + + case PCRE2_NEWLINE_LF: + mb->nllen = 1; + mb->nl[0] = CHAR_NL; + break; + + case PCRE2_NEWLINE_CRLF: + mb->nllen = 2; + mb->nl[0] = CHAR_CR; + mb->nl[1] = CHAR_NL; + break; + + case PCRE2_NEWLINE_ANY: + mb->nltype = NLTYPE_ANY; + break; + + case PCRE2_NEWLINE_ANYCRLF: + mb->nltype = NLTYPE_ANYCRLF; + break; + + default: return PCRE2_ERROR_INTERNAL; + } + +/* If the expression has got more back references than the offsets supplied can +hold, we get a temporary chunk of memory to use during the matching. Otherwise, +we can use the vector supplied. The size of the ovector is three times the +value in the oveccount field. Two-thirds of it is pairs for storing matching +offsets, and the top third is working space. */ + +if (re->top_backref >= match_data->oveccount) + { + ocount = re->top_backref * 3 + 3; + mb->ovector = (PCRE2_SIZE *)(mb->memctl.malloc(ocount * sizeof(PCRE2_SIZE), + mb->memctl.memory_data)); + if (mb->ovector == NULL) return PCRE2_ERROR_NOMEMORY; + using_temporary_offsets = TRUE; + } +else + { + ocount = 3 * match_data->oveccount; + mb->ovector = match_data->ovector; + } + +mb->offset_end = ocount; +mb->offset_max = (2*ocount)/3; + +/* Reset the working variable associated with each extraction. These should +never be used unless previously set, but they get saved and restored, and so we +initialize them to avoid reading uninitialized locations. Also, unset the +offsets for the matched string. This is really just for tidiness with callouts, +in case they inspect these fields. */ + +if (ocount > 0) + { + register PCRE2_SIZE *iptr = mb->ovector + ocount; + register PCRE2_SIZE *iend = iptr - re->top_bracket; + if (iend < mb->ovector + 2) iend = mb->ovector + 2; + while (--iptr >= iend) *iptr = PCRE2_UNSET; + mb->ovector[0] = mb->ovector[1] = PCRE2_UNSET; + } + +/* Set up the first code unit to match, if available. The first_codeunit value +is never set for an anchored regular expression, but the anchoring may be +forced at run time, so we have to test for anchoring. The first code unit may +be unset for an unanchored pattern, of course. If there's no first code unit +there may be a bitmap of possible first characters. */ + +if (!anchored) + { + if ((re->flags & PCRE2_FIRSTSET) != 0) + { + has_first_cu = TRUE; + first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit); + if ((re->flags & PCRE2_FIRSTCASELESS) != 0) + { + first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); +#endif + } + } + else + if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0) + start_bits = re->start_bitmap; + } + +/* For anchored or unanchored matches, there may be a "last known required +character" set. */ + +if ((re->flags & PCRE2_LASTSET) != 0) + { + has_req_cu = TRUE; + req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit); + if ((re->flags & PCRE2_LASTCASELESS) != 0) + { + req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 + if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); +#endif + } + } + + +/* ==========================================================================*/ + +/* Loop for handling unanchored repeated matching attempts; for anchored regexs +the loop runs just once. */ + +for(;;) + { + PCRE2_SPTR new_start_match; + mb->capture_last = 0; + + /* ----------------- Start of match optimizations ---------------- */ + + /* There are some optimizations that avoid running the match if a known + starting point is not found, or if a known later code unit is not present. + However, there is an option (settable at compile time) that disables these, + for testing and for ensuring that all callouts do actually occur. */ + + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + { + PCRE2_SPTR save_end_subject = end_subject; + + /* If firstline is TRUE, the start of the match is constrained to the first + line of a multiline string. That is, the match must be before or at the + first newline. Implement this by temporarily adjusting end_subject so that + we stop the optimization scans at a newline. If the match fails at the + newline, later code breaks this loop. */ + + if (firstline) + { + PCRE2_SPTR t = start_match; +#ifdef SUPPORT_UNICODE + if (utf) + { + while (t < mb->end_subject && !IS_NEWLINE(t)) + { + t++; + ACROSSCHAR(t < end_subject, *t, t++); + } + } + else +#endif + while (t < mb->end_subject && !IS_NEWLINE(t)) t++; + end_subject = t; + } + + /* Advance to a unique first code unit if there is one. In 8-bit mode, the + use of memchr() gives a big speed up. */ + + if (has_first_cu) + { + PCRE2_UCHAR smc; + if (first_cu != first_cu2) + while (start_match < end_subject && + (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) + start_match++; + else + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu) + start_match++; +#else + start_match = memchr(start_match, first_cu, end_subject - start_match); + if (start_match == NULL) start_match = end_subject; +#endif + } + } + + /* Or to just after a linebreak for a multiline match */ + + else if (startline) + { + if (start_match > mb->start_subject + start_offset) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + { + start_match++; + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); + } + } + else +#endif + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + start_match++; + + /* If we have just passed a CR and the newline option is ANY or + ANYCRLF, and we are now at a LF, advance the match position by one more + code unit. */ + + if (start_match[-1] == CHAR_CR && + (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) && + start_match < end_subject && + UCHAR21TEST(start_match) == CHAR_NL) + start_match++; + } + } + + /* Or to a non-unique first code unit if any have been identified. The + bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all + code units greater than 254 set the 255 bit. */ + + else if (start_bits != NULL) + { + while (start_match < end_subject) + { + register uint32_t c = UCHAR21TEST(start_match); +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) c = 255; +#endif + if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + start_match++; + } + } + + /* Restore fudged end_subject */ + + end_subject = save_end_subject; + + /* The following two optimizations are disabled for partial matching. */ + + if (!mb->partial) + { + /* The minimum matching length is a lower bound; no actual string of that + length may actually match the pattern. Although the value is, strictly, + in characters, we treat it as code units to avoid spending too much time + in this optimization. */ + + if (end_subject - start_match < re->minlength) + { + rc = MATCH_NOMATCH; + break; + } + + /* If req_cu is set, we know that that code unit must appear in the + subject for the match to succeed. If the first code unit is set, req_cu + must be later in the subject; otherwise the test starts at the match + point. This optimization can save a huge amount of backtracking in + patterns with nested unlimited repeats that aren't going to match. + Writing separate code for cased/caseless versions makes it go faster, as + does using an autoincrement and backing off on a match. + + HOWEVER: when the subject string is very, very long, searching to its end + can take a long time, and give bad performance on quite ordinary + patterns. This showed up when somebody was matching something like + /^\d+C/ on a 32-megabyte string... so we don't do this when the string is + sufficiently long. */ + + if (has_req_cu && end_subject - start_match < REQ_CU_MAX) + { + register PCRE2_SPTR p = start_match + (has_first_cu? 1:0); + + /* We don't need to repeat the search if we haven't yet reached the + place we found it at last time. */ + + if (p > req_cu_ptr) + { + if (req_cu != req_cu2) + { + while (p < end_subject) + { + register uint32_t pp = UCHAR21INCTEST(p); + if (pp == req_cu || pp == req_cu2) { p--; break; } + } + } + else + { + while (p < end_subject) + { + if (UCHAR21INCTEST(p) == req_cu) { p--; break; } + } + } + + /* If we can't find the required code unit, break the matching loop, + forcing a match failure. */ + + if (p >= end_subject) + { + rc = MATCH_NOMATCH; + break; + } + + /* If we have found the required code unit, save the point where we + found it, so that we don't search again next time round the loop if + the start hasn't passed this code unit yet. */ + + req_cu_ptr = p; + } + } + } + } + + /* ------------ End of start of match optimizations ------------ */ + + /* Give no match if we have passed the bumpalong limit. */ + + if (start_match > bumpalong_limit) + { + rc = MATCH_NOMATCH; + break; + } + + /* OK, we can now run the match. If "hitend" is set afterwards, remember the + first starting point for which a partial match was found. */ + + mb->start_match_ptr = start_match; + mb->start_used_ptr = start_match; + mb->last_used_ptr = start_match; + mb->match_call_count = 0; + mb->match_function_type = 0; + mb->end_offset_top = 0; + mb->skip_arg_count = 0; + rc = match(start_match, mb->start_code, start_match, 2, mb, NULL, 0); + + if (mb->hitend && start_partial == NULL) + { + start_partial = mb->start_used_ptr; + match_partial = start_match; + } + + switch(rc) + { + /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched + the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP + entirely. The only way we can do that is to re-do the match at the same + point, with a flag to force SKIP with an argument to be ignored. Just + treating this case as NOMATCH does not work because it does not check other + alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */ + + case MATCH_SKIP_ARG: + new_start_match = start_match; + mb->ignore_skip_arg = mb->skip_arg_count; + break; + + /* SKIP passes back the next starting point explicitly, but if it is no + greater than the match we have just done, treat it as NOMATCH. */ + + case MATCH_SKIP: + if (mb->start_match_ptr > start_match) + { + new_start_match = mb->start_match_ptr; + break; + } + /* Fall through */ + + /* NOMATCH and PRUNE advance by one character. THEN at this level acts + exactly like PRUNE. Unset ignore SKIP-with-argument. */ + + case MATCH_NOMATCH: + case MATCH_PRUNE: + case MATCH_THEN: + mb->ignore_skip_arg = 0; + new_start_match = start_match + 1; +#ifdef SUPPORT_UNICODE + if (utf) + ACROSSCHAR(new_start_match < end_subject, *new_start_match, + new_start_match++); +#endif + break; + + /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */ + + case MATCH_COMMIT: + rc = MATCH_NOMATCH; + goto ENDLOOP; + + /* Any other return is either a match, or some kind of error. */ + + default: + goto ENDLOOP; + } + + /* Control reaches here for the various types of "no match at this point" + result. Reset the code to MATCH_NOMATCH for subsequent checking. */ + + rc = MATCH_NOMATCH; + + /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first + newline in the subject (though it may continue over the newline). Therefore, + if we have just failed to match, starting at a newline, do not continue. */ + + if (firstline && IS_NEWLINE(start_match)) break; + + /* Advance to new matching position */ + + start_match = new_start_match; + + /* Break the loop if the pattern is anchored or if we have passed the end of + the subject. */ + + if (anchored || start_match > end_subject) break; + + /* If we have just passed a CR and we are now at a LF, and the pattern does + not contain any explicit matches for \r or \n, and the newline option is CRLF + or ANY or ANYCRLF, advance the match position by one more code unit. In + normal matching start_match will aways be greater than the first position at + this stage, but a failed *SKIP can cause a return at the same point, which is + why the first test exists. */ + + if (start_match > subject + start_offset && + start_match[-1] == CHAR_CR && + start_match < end_subject && + *start_match == CHAR_NL && + (re->flags & PCRE2_HASCRORLF) == 0 && + (mb->nltype == NLTYPE_ANY || + mb->nltype == NLTYPE_ANYCRLF || + mb->nllen == 2)) + start_match++; + + mb->mark = NULL; /* Reset for start of next match attempt */ + } /* End of for(;;) "bumpalong" loop */ + +/* ==========================================================================*/ + +/* When we reach here, one of the stopping conditions is true: + +(1) The match succeeded, either completely, or partially; + +(2) The pattern is anchored or the match was failed by (*COMMIT); + +(3) We are past the end of the subject or the bumpalong limit; + +(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because + this option requests that a match occur at or before the first newline in + the subject. + +(5) Some kind of error occurred. + +*/ + +ENDLOOP: + +#ifdef HEAP_MATCH_RECURSE +release_match_heapframes(&frame_zero, mb); +#endif + +/* Release any frames that were saved from recursions. */ + +while (mb->ovecsave_chain != NULL) + { + ovecsave_frame *this = mb->ovecsave_chain; + mb->ovecsave_chain = this->next; + mb->memctl.free(this, mb->memctl.memory_data); + } + +/* Fill in fields that are always returned in the match data. */ + +match_data->code = re; +match_data->subject = subject; +match_data->mark = mb->mark; +match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER; + +/* Handle a fully successful match. */ + +if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) + { + uint32_t arg_offset_max = 2 * match_data->oveccount; + + /* When the offset vector is big enough to deal with any backreferences, + captured substring offsets will already be set up. In the case where we had + to get some local memory to hold offsets for backreference processing, copy + those that we can. In this case there need not be overflow if certain parts + of the pattern were not used, even though there are more capturing + parentheses than vector slots. */ + + if (using_temporary_offsets) + { + if (arg_offset_max >= 4) + { + memcpy(match_data->ovector + 2, mb->ovector + 2, + (arg_offset_max - 2) * sizeof(PCRE2_SIZE)); + } + if (mb->end_offset_top > arg_offset_max) mb->capture_last |= OVFLBIT; + mb->memctl.free(mb->ovector, mb->memctl.memory_data); + } + + /* Set the return code to the number of captured strings, or 0 if there were + too many to fit into the ovector. */ + + match_data->rc = ((mb->capture_last & OVFLBIT) != 0)? + 0 : mb->end_offset_top/2; + + /* If there is space in the offset vector, set any pairs that follow the + highest-numbered captured string but are less than the number of capturing + groups in the pattern (and are within the ovector) to PCRE2_UNSET. It is + documented that this happens. In earlier versions, the whole set of potential + capturing offsets was initialized each time round the loop, but this is + handled differently now. "Gaps" are set to PCRE2_UNSET dynamically instead + (this fixed a bug). Thus, it is only those at the end that need setting here. + We can't just mark them all unset at the start of the whole thing because + they may get set in one branch that is not the final matching branch. */ + + if (mb->end_offset_top/2 <= re->top_bracket) + { + register PCRE2_SIZE *iptr, *iend; + int resetcount = re->top_bracket + 1; + if (resetcount > match_data->oveccount) resetcount = match_data->oveccount; + iptr = match_data->ovector + mb->end_offset_top; + iend = match_data->ovector + 2 * resetcount; + while (iptr < iend) *iptr++ = PCRE2_UNSET; + } + + /* If there is space, set up the whole thing as substring 0. The value of + mb->start_match_ptr might be modified if \K was encountered on the success + matching path. */ + + if (match_data->oveccount < 1) rc = 0; else + { + match_data->ovector[0] = mb->start_match_ptr - mb->start_subject; + match_data->ovector[1] = mb->end_match_ptr - mb->start_subject; + } + + /* Set the remaining returned values */ + + match_data->startchar = start_match - subject; + match_data->leftchar = mb->start_used_ptr - subject; + match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)? + mb->last_used_ptr : mb->end_match_ptr) - subject; + return match_data->rc; + } + +/* Control gets here if there has been a partial match, an error, or if the +overall match attempt has failed at all permitted starting positions. Any mark +data is in the nomatch_mark field. */ + +match_data->mark = mb->nomatch_mark; + +/* For anything other than nomatch or partial match, just return the code. */ + +if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) + match_data->rc = rc; + +/* Else handle a partial match. */ + +else if (match_partial != NULL) + { + if (match_data->oveccount > 0) + { + match_data->ovector[0] = match_partial - subject; + match_data->ovector[1] = end_subject - subject; + } + match_data->startchar = match_partial - subject; + match_data->leftchar = start_partial - subject; + match_data->rightchar = end_subject - subject; + match_data->rc = PCRE2_ERROR_PARTIAL; + } + +/* Else this is the classic nomatch case. */ + +else match_data->rc = PCRE2_ERROR_NOMATCH; + +/* Free any temporary offsets. */ + +if (using_temporary_offsets) + mb->memctl.free(mb->ovector, mb->memctl.memory_data); +return match_data->rc; +} + +/* End of pcre2_match.c */ diff --git a/pcre2/src/pcre2_match_data.c b/pcre2/src/pcre2_match_data.c new file mode 100644 index 000000000..85ac99834 --- /dev/null +++ b/pcre2/src/pcre2_match_data.c @@ -0,0 +1,147 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + + +/************************************************* +* Create a match data block given ovector size * +*************************************************/ + +/* A minimum of 1 is imposed on the number of ovector triplets. */ + +PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION +pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext) +{ +pcre2_match_data *yield; +if (oveccount < 1) oveccount = 1; +yield = PRIV(memctl_malloc)( + sizeof(pcre2_match_data) + 3*oveccount*sizeof(PCRE2_SIZE), + (pcre2_memctl *)gcontext); +if (yield == NULL) return NULL; +yield->oveccount = oveccount; +return yield; +} + + + +/************************************************* +* Create a match data block using pattern data * +*************************************************/ + +/* If no context is supplied, use the memory allocator from the code. */ + +PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION +pcre2_match_data_create_from_pattern(const pcre2_code *code, + pcre2_general_context *gcontext) +{ +if (gcontext == NULL) gcontext = (pcre2_general_context *)code; +return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1, + gcontext); +} + + + +/************************************************* +* Free a match data block * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_match_data_free(pcre2_match_data *match_data) +{ +if (match_data != NULL) + match_data->memctl.free(match_data, match_data->memctl.memory_data); +} + + + +/************************************************* +* Get last mark in match * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION +pcre2_get_mark(pcre2_match_data *match_data) +{ +return match_data->mark; +} + + + +/************************************************* +* Get pointer to ovector * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION +pcre2_get_ovector_pointer(pcre2_match_data *match_data) +{ +return match_data->ovector; +} + + + +/************************************************* +* Get number of ovector slots * +*************************************************/ + +PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION +pcre2_get_ovector_count(pcre2_match_data *match_data) +{ +return match_data->oveccount; +} + + + +/************************************************* +* Get starting code unit in match * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION +pcre2_get_startchar(pcre2_match_data *match_data) +{ +return match_data->startchar; +} + +/* End of pcre2_match_data.c */ diff --git a/pcre2/src/pcre2_newline.c b/pcre2/src/pcre2_newline.c new file mode 100644 index 000000000..6e9366db9 --- /dev/null +++ b/pcre2/src/pcre2_newline.c @@ -0,0 +1,243 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains internal functions for testing newlines when more than +one kind of newline is to be recognized. When a newline is found, its length is +returned. In principle, we could implement several newline "types", each +referring to a different set of newline characters. At present, PCRE2 supports +only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, +and NLTYPE_ANY. The full list of Unicode newline characters is taken from +http://unicode.org/unicode/reports/tr18/. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + + +/************************************************* +* Check for newline at given position * +*************************************************/ + +/* This function is called only via the IS_NEWLINE macro, which does so only +when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed +newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit +pointed to by ptr is less than the end of the string. + +Arguments: + ptr pointer to possible newline + type the newline type + endptr pointer to the end of the string + lenptr where to return the length + utf TRUE if in utf mode + +Returns: TRUE or FALSE +*/ + +BOOL +PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr, + uint32_t *lenptr, BOOL utf) +{ +uint32_t c; + +#ifdef SUPPORT_UNICODE +if (utf) { GETCHAR(c, ptr); } else c = *ptr; +#else +(void)utf; +c = *ptr; +#endif /* SUPPORT_UNICODE */ + +if (type == NLTYPE_ANYCRLF) switch(c) + { + case CHAR_LF: + *lenptr = 1; + return TRUE; + + case CHAR_CR: + *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; + return TRUE; + + default: + return FALSE; + } + +/* NLTYPE_ANY */ + +else switch(c) + { +#ifdef EBCDIC + case CHAR_NEL: +#endif + case CHAR_LF: + case CHAR_VT: + case CHAR_FF: + *lenptr = 1; + return TRUE; + + case CHAR_CR: + *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; + return TRUE; + +#ifndef EBCDIC +#if PCRE2_CODE_UNIT_WIDTH == 8 + case CHAR_NEL: + *lenptr = utf? 2 : 1; + return TRUE; + + case 0x2028: /* LS */ + case 0x2029: /* PS */ + *lenptr = 3; + return TRUE; + +#else /* 16-bit or 32-bit code units */ + case CHAR_NEL: + case 0x2028: /* LS */ + case 0x2029: /* PS */ + *lenptr = 1; + return TRUE; +#endif +#endif /* Not EBCDIC */ + + default: + return FALSE; + } +} + + + +/************************************************* +* Check for newline at previous position * +*************************************************/ + +/* This function is called only via the WAS_NEWLINE macro, which does so only +when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed +newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial +value of ptr is greater than the start of the string that is being processed. + +Arguments: + ptr pointer to possible newline + type the newline type + startptr pointer to the start of the string + lenptr where to return the length + utf TRUE if in utf mode + +Returns: TRUE or FALSE +*/ + +BOOL +PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr, + uint32_t *lenptr, BOOL utf) +{ +uint32_t c; +ptr--; + +#ifdef SUPPORT_UNICODE +if (utf) + { + BACKCHAR(ptr); + GETCHAR(c, ptr); + } +else c = *ptr; +#else +(void)utf; +c = *ptr; +#endif /* SUPPORT_UNICODE */ + +if (type == NLTYPE_ANYCRLF) switch(c) + { + case CHAR_LF: + *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; + return TRUE; + + case CHAR_CR: + *lenptr = 1; + return TRUE; + + default: + return FALSE; + } + +/* NLTYPE_ANY */ + +else switch(c) + { + case CHAR_LF: + *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; + return TRUE; + +#ifdef EBCDIC + case CHAR_NEL: +#endif + case CHAR_VT: + case CHAR_FF: + case CHAR_CR: + *lenptr = 1; + return TRUE; + +#ifndef EBCDIC +#if PCRE2_CODE_UNIT_WIDTH == 8 + case CHAR_NEL: + *lenptr = utf? 2 : 1; + return TRUE; + + case 0x2028: /* LS */ + case 0x2029: /* PS */ + *lenptr = 3; + return TRUE; + +#else /* 16-bit or 32-bit code units */ + case CHAR_NEL: + case 0x2028: /* LS */ + case 0x2029: /* PS */ + *lenptr = 1; + return TRUE; +#endif +#endif /* Not EBCDIC */ + + default: + return FALSE; + } +} + +/* End of pcre2_newline.c */ diff --git a/pcre2/src/pcre2_ord2utf.c b/pcre2/src/pcre2_ord2utf.c new file mode 100644 index 000000000..75252b763 --- /dev/null +++ b/pcre2/src/pcre2_ord2utf.c @@ -0,0 +1,120 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This file contains a function that converts a Unicode character code point +into a UTF string. The behaviour is different for each code unit width. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + +/* If SUPPORT_UNICODE is not defined, this function will never be called. +Supply a dummy function because some compilers do not like empty source +modules. */ + +#ifndef SUPPORT_UNICODE +unsigned int +PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) +{ +(void)(cvalue); +(void)(buffer); +return 0; +} +#else /* SUPPORT_UNICODE */ + + +/************************************************* +* Convert code point to UTF * +*************************************************/ + +/* +Arguments: + cvalue the character value + buffer pointer to buffer for result + +Returns: number of code units placed in the buffer +*/ + +unsigned int +PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) +{ +/* Convert to UTF-8 */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +register int i, j; +for (i = 0; i < PRIV(utf8_table1_size); i++) + if ((int)cvalue <= PRIV(utf8_table1)[i]) break; +buffer += i; +for (j = i; j > 0; j--) + { + *buffer-- = 0x80 | (cvalue & 0x3f); + cvalue >>= 6; + } +*buffer = PRIV(utf8_table2)[i] | cvalue; +return i + 1; + +/* Convert to UTF-16 */ + +#elif PCRE2_CODE_UNIT_WIDTH == 16 +if (cvalue <= 0xffff) + { + *buffer = (PCRE2_UCHAR)cvalue; + return 1; + } +cvalue -= 0x10000; +*buffer++ = 0xd800 | (cvalue >> 10); +*buffer = 0xdc00 | (cvalue & 0x3ff); +return 2; + +/* Convert to UTF-32 */ + +#else +*buffer = (PCRE2_UCHAR)cvalue; +return 1; +#endif +} +#endif /* SUPPORT_UNICODE */ + +/* End of pcre_ord2utf.c */ diff --git a/pcre2/src/pcre2_pattern_info.c b/pcre2/src/pcre2_pattern_info.c new file mode 100644 index 000000000..5b32a905b --- /dev/null +++ b/pcre2/src/pcre2_pattern_info.c @@ -0,0 +1,410 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + +/************************************************* +* Return info about compiled pattern * +*************************************************/ + +/* +Arguments: + code points to compiled code + what what information is required + where where to put the information; if NULL, return length + +Returns: 0 when data returned + > 0 when length requested + < 0 on error or unset value +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where) +{ +const pcre2_real_code *re = (pcre2_real_code *)code; + +if (where == NULL) /* Requests field length */ + { + switch(what) + { + case PCRE2_INFO_ALLOPTIONS: + case PCRE2_INFO_ARGOPTIONS: + case PCRE2_INFO_BACKREFMAX: + case PCRE2_INFO_BSR: + case PCRE2_INFO_CAPTURECOUNT: + case PCRE2_INFO_FIRSTCODETYPE: + case PCRE2_INFO_FIRSTCODEUNIT: + case PCRE2_INFO_HASBACKSLASHC: + case PCRE2_INFO_HASCRORLF: + case PCRE2_INFO_JCHANGED: + case PCRE2_INFO_LASTCODETYPE: + case PCRE2_INFO_LASTCODEUNIT: + case PCRE2_INFO_MATCHEMPTY: + case PCRE2_INFO_MATCHLIMIT: + case PCRE2_INFO_MAXLOOKBEHIND: + case PCRE2_INFO_MINLENGTH: + case PCRE2_INFO_NAMEENTRYSIZE: + case PCRE2_INFO_NAMECOUNT: + case PCRE2_INFO_NEWLINE: + case PCRE2_INFO_RECURSIONLIMIT: + return sizeof(uint32_t); + + case PCRE2_INFO_FIRSTBITMAP: + return sizeof(const uint8_t *); + + case PCRE2_INFO_JITSIZE: + case PCRE2_INFO_SIZE: + return sizeof(size_t); + + case PCRE2_INFO_NAMETABLE: + return sizeof(PCRE2_SPTR); + } + } + +if (re == NULL) return PCRE2_ERROR_NULL; + +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE2_ERROR_BADMAGIC. */ + +if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; + +/* Check that this pattern was compiled in the correct bit mode */ + +if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; + +switch(what) + { + case PCRE2_INFO_ALLOPTIONS: + *((uint32_t *)where) = re->overall_options; + break; + + case PCRE2_INFO_ARGOPTIONS: + *((uint32_t *)where) = re->compile_options; + break; + + case PCRE2_INFO_BACKREFMAX: + *((uint32_t *)where) = re->top_backref; + break; + + case PCRE2_INFO_BSR: + *((uint32_t *)where) = re->bsr_convention; + break; + + case PCRE2_INFO_CAPTURECOUNT: + *((uint32_t *)where) = re->top_bracket; + break; + + case PCRE2_INFO_FIRSTCODETYPE: + *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 : + ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0; + break; + + case PCRE2_INFO_FIRSTCODEUNIT: + *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? + re->first_codeunit : 0; + break; + + case PCRE2_INFO_FIRSTBITMAP: + *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)? + &(re->start_bitmap[0]) : NULL; + break; + + case PCRE2_INFO_HASBACKSLASHC: + *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0; + break; + + case PCRE2_INFO_HASCRORLF: + *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0; + break; + + case PCRE2_INFO_JCHANGED: + *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0; + break; + + case PCRE2_INFO_JITSIZE: +#ifdef SUPPORT_JIT + *((size_t *)where) = (re->executable_jit != NULL)? + PRIV(jit_get_size)(re->executable_jit) : 0; +#else + *((size_t *)where) = 0; +#endif + break; + + case PCRE2_INFO_LASTCODETYPE: + *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0; + break; + + case PCRE2_INFO_LASTCODEUNIT: + *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? + re->last_codeunit : 0; + break; + + case PCRE2_INFO_MATCHEMPTY: + *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0; + break; + + case PCRE2_INFO_MATCHLIMIT: + *((uint32_t *)where) = re->limit_match; + if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET; + break; + + case PCRE2_INFO_MAXLOOKBEHIND: + *((uint32_t *)where) = re->max_lookbehind; + break; + + case PCRE2_INFO_MINLENGTH: + *((uint32_t *)where) = re->minlength; + break; + + case PCRE2_INFO_NAMEENTRYSIZE: + *((uint32_t *)where) = re->name_entry_size; + break; + + case PCRE2_INFO_NAMECOUNT: + *((uint32_t *)where) = re->name_count; + break; + + case PCRE2_INFO_NAMETABLE: + *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code)); + break; + + case PCRE2_INFO_NEWLINE: + *((uint32_t *)where) = re->newline_convention; + break; + + case PCRE2_INFO_RECURSIONLIMIT: + *((uint32_t *)where) = re->limit_recursion; + if (re->limit_recursion == UINT32_MAX) return PCRE2_ERROR_UNSET; + break; + + case PCRE2_INFO_SIZE: + *((size_t *)where) = re->blocksize; + break; + + default: return PCRE2_ERROR_BADOPTION; + } + +return 0; +} + + + +/************************************************* +* Callout enumerator * +*************************************************/ + +/* +Arguments: + code points to compiled code + callback function called for each callout block + callout_data user data passed to the callback + +Returns: 0 when successfully completed + < 0 on local error + != 0 for callback error +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_callout_enumerate(const pcre2_code *code, + int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data) +{ +pcre2_real_code *re = (pcre2_real_code *)code; +pcre2_callout_enumerate_block cb; +PCRE2_SPTR cc; +#ifdef SUPPORT_UNICODE +BOOL utf = (re->overall_options & PCRE2_UTF) != 0; +#endif + +if (re == NULL) return PCRE2_ERROR_NULL; + +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE2_ERROR_BADMAGIC. */ + +if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; + +/* Check that this pattern was compiled in the correct bit mode */ + +if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; + +cb.version = 0; +cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_count * re->name_entry_size; + +while (TRUE) + { + int rc; + switch (*cc) + { + case OP_END: + return 0; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + cc += PRIV(OP_lengths)[*cc]; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + cc += PRIV(OP_lengths)[*cc]; +#ifdef SUPPORT_UNICODE + if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2; +#endif + break; + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + cc += GET(cc, 1); + break; +#endif + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += PRIV(OP_lengths)[*cc] + cc[1]; + break; + + case OP_CALLOUT: + cb.pattern_position = GET(cc, 1); + cb.next_item_length = GET(cc, 1 + LINK_SIZE); + cb.callout_number = cc[1 + 2*LINK_SIZE]; + cb.callout_string_offset = 0; + cb.callout_string_length = 0; + cb.callout_string = NULL; + rc = callback(&cb, callout_data); + if (rc != 0) return rc; + cc += PRIV(OP_lengths)[*cc]; + break; + + case OP_CALLOUT_STR: + cb.pattern_position = GET(cc, 1); + cb.next_item_length = GET(cc, 1 + LINK_SIZE); + cb.callout_number = 0; + cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE); + cb.callout_string_length = + GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2; + cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1; + rc = callback(&cb, callout_data); + if (rc != 0) return rc; + cc += GET(cc, 1 + 2*LINK_SIZE); + break; + + default: + cc += PRIV(OP_lengths)[*cc]; + break; + } + } +} + +/* End of pcre2_pattern_info.c */ diff --git a/pcre2/src/pcre2_printint.c b/pcre2/src/pcre2_printint.c new file mode 100644 index 000000000..40a633cfd --- /dev/null +++ b/pcre2/src/pcre2_printint.c @@ -0,0 +1,832 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains a PCRE private debugging function for printing out the +internal form of a compiled regular expression, along with some supporting +local functions. This source file is #included in pcre2test.c at each supported +code unit width, with PCRE2_SUFFIX set appropriately, just like the functions +that comprise the library. It can also optionally be included in +pcre2_compile.c for detailed debugging in error situations. */ + + +/* Tables of operator names. The same 8-bit table is used for all code unit +widths, so it must be defined only once. The list itself is defined in +pcre2_internal.h, which is #included by pcre2test before this file. */ + +#ifndef OP_LISTS_DEFINED +static const char *OP_names[] = { OP_NAME_LIST }; +#define OP_LISTS_DEFINED +#endif + +/* The functions and tables herein must all have mode-dependent names. */ + +#define OP_lengths PCRE2_SUFFIX(OP_lengths_) +#define get_ucpname PCRE2_SUFFIX(get_ucpname_) +#define pcre2_printint PCRE2_SUFFIX(pcre2_printint_) +#define print_char PCRE2_SUFFIX(print_char_) +#define print_custring PCRE2_SUFFIX(print_custring_) +#define print_custring_bylen PCRE2_SUFFIX(print_custring_bylen_) +#define print_prop PCRE2_SUFFIX(print_prop_) + +/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that +the definition is next to the definition of the opcodes in pcre2_internal.h. +The contents of the table are, however, mode-dependent. */ + +static const uint8_t OP_lengths[] = { OP_LENGTHS }; + + + +/************************************************* +* Print one character from a string * +*************************************************/ + +/* In UTF mode the character may occupy more than one code unit. + +Arguments: + f file to write to + ptr pointer to first code unit of the character + utf TRUE if string is UTF (will be FALSE if UTF is not supported) + +Returns: number of additional code units used +*/ + +static unsigned int +print_char(FILE *f, PCRE2_SPTR ptr, BOOL utf) +{ +uint32_t c = *ptr; +BOOL one_code_unit = !utf; + +/* If UTF is supported and requested, check for a valid single code unit. */ + +#ifdef SUPPORT_UNICODE +if (utf) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + one_code_unit = c < 0x80; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + one_code_unit = (c & 0xfc00) != 0xd800; +#else + one_code_unit = (c & 0xfffff800u) != 0xd800u; +#endif /* CODE_UNIT_WIDTH */ + } +#endif /* SUPPORT_UNICODE */ + +/* Handle a valid one-code-unit character at any width. */ + +if (one_code_unit) + { + if (PRINTABLE(c)) fprintf(f, "%c", (char)c); + else if (c < 0x80) fprintf(f, "\\x%02x", c); + else fprintf(f, "\\x{%02x}", c); + return 0; + } + +/* Code for invalid UTF code units and multi-unit UTF characters is different +for each width. If UTF is not supported, control should never get here, but we +need a return statement to keep the compiler happy. */ + +#ifndef SUPPORT_UNICODE +return 0; +#else + +/* Malformed UTF-8 should occur only if the sanity check has been turned off. +Rather than swallow random bytes, just stop if we hit a bad one. Print it with +\X instead of \x as an indication. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +if ((c & 0xc0) != 0xc0) + { + fprintf(f, "\\X{%x}", c); /* Invalid starting byte */ + return 0; + } +else + { + int i; + int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ + int s = 6*a; + c = (c & PRIV(utf8_table3)[a]) << s; + for (i = 1; i <= a; i++) + { + if ((ptr[i] & 0xc0) != 0x80) + { + fprintf(f, "\\X{%x}", c); /* Invalid secondary byte */ + return i - 1; + } + s -= 6; + c |= (ptr[i] & 0x3f) << s; + } + fprintf(f, "\\x{%x}", c); + return a; +} +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + +/* UTF-16: rather than swallow a low surrogate, just stop if we hit a bad one. +Print it with \X instead of \x as an indication. */ + +#if PCRE2_CODE_UNIT_WIDTH == 16 +if ((ptr[1] & 0xfc00) != 0xdc00) + { + fprintf(f, "\\X{%x}", c); + return 0; + } +c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000; +fprintf(f, "\\x{%x}", c); +return 1; +#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */ + +/* For UTF-32 we get here only for a malformed code unit, which should only +occur if the sanity check has been turned off. Print it with \X instead of \x +as an indication. */ + +#if PCRE2_CODE_UNIT_WIDTH == 32 +fprintf(f, "\\X{%x}", c); +return 0; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ +#endif /* SUPPORT_UNICODE */ +} + + + +/************************************************* +* Print string as a list of code units * +*************************************************/ + +/* These take no account of UTF as they always print each individual code unit. +The string is zero-terminated for print_custring(); the length is given for +print_custring_bylen(). + +Arguments: + f file to write to + ptr point to the string + len length for print_custring_bylen() + +Returns: nothing +*/ + +static void +print_custring(FILE *f, PCRE2_SPTR ptr) +{ +while (*ptr != '\0') + { + register uint32_t c = *ptr++; + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); + } +} + +static void +print_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len) +{ +while (len-- > 0) + { + register uint32_t c = *ptr++; + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); + } +} + + + +/************************************************* +* Find Unicode property name * +*************************************************/ + +/* When there is no UTF/UCP support, the table of names does not exist. This +function should not be called in such configurations, because a pattern that +tries to use Unicode properties won't compile. Rather than put lots of #ifdefs +into the main code, however, we just put one into this function. */ + +static const char * +get_ucpname(unsigned int ptype, unsigned int pvalue) +{ +#ifdef SUPPORT_UNICODE +int i; +for (i = PRIV(utt_size) - 1; i >= 0; i--) + { + if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break; + } +return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??"; +#else /* No UTF support */ +(void)ptype; +(void)pvalue; +return "??"; +#endif /* SUPPORT_UNICODE */ +} + + + +/************************************************* +* Print Unicode property value * +*************************************************/ + +/* "Normal" properties can be printed from tables. The PT_CLIST property is a +pseudo-property that contains a pointer to a list of case-equivalent +characters. + +Arguments: + f file to write to + code pointer in the compiled code + before text to print before + after text to print after + +Returns: nothing +*/ + +static void +print_prop(FILE *f, PCRE2_SPTR code, const char *before, const char *after) +{ +if (code[1] != PT_CLIST) + { + fprintf(f, "%s%s %s%s", before, OP_names[*code], get_ucpname(code[1], + code[2]), after); + } +else + { + const char *not = (*code == OP_PROP)? "" : "not "; + const uint32_t *p = PRIV(ucd_caseless_sets) + code[2]; + fprintf (f, "%s%sclist", before, not); + while (*p < NOTACHAR) fprintf(f, " %04x", *p++); + fprintf(f, "%s", after); + } +} + + + +/************************************************* +* Print compiled pattern * +*************************************************/ + +/* The print_lengths flag controls whether offsets and lengths of items are +printed. Lenths can be turned off from pcre2test so that automatic tests on +bytecode can be written that do not depend on the value of LINK_SIZE. + +Arguments: + re a compiled pattern + f the file to write to + print_lengths show various lengths + +Returns: nothing +*/ + +static void +pcre2_printint(pcre2_code *re, FILE *f, BOOL print_lengths) +{ +PCRE2_SPTR codestart, nametable, code; +uint32_t nesize = re->name_entry_size; +BOOL utf = (re->overall_options & PCRE2_UTF) != 0; + +nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); +code = codestart = nametable + re->name_count * re->name_entry_size; + +for(;;) + { + PCRE2_SPTR ccode; + uint32_t c; + int i; + const char *flag = " "; + unsigned int extra = 0; + + if (print_lengths) + fprintf(f, "%3d ", (int)(code - codestart)); + else + fprintf(f, " "); + + switch(*code) + { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors OP_names or OP_lengths, which are indexed + by opcode, are not the correct length. It seems to be the only way to do + such a check at compile time, as the sizeof() operator does not work in + the C preprocessor. */ + + case OP_TABLE_LENGTH: + case OP_TABLE_LENGTH + + ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && + (sizeof(OP_lengths) == OP_TABLE_LENGTH)): + break; +/* ========================================================================== */ + + case OP_END: + fprintf(f, " %s\n", OP_names[*code]); + fprintf(f, "------------------------------------------------------------------\n"); + return; + + case OP_CHAR: + fprintf(f, " "); + do + { + code++; + code += 1 + print_char(f, code, utf); + } + while (*code == OP_CHAR); + fprintf(f, "\n"); + continue; + + case OP_CHARI: + fprintf(f, " /i "); + do + { + code++; + code += 1 + print_char(f, code, utf); + } + while (*code == OP_CHARI); + fprintf(f, "\n"); + continue; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE)); + break; + + case OP_BRA: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_ALT: + case OP_KET: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_COND: + case OP_SCOND: + case OP_REVERSE: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_CLOSE: + fprintf(f, " %s %d", OP_names[*code], GET2(code, 1)); + break; + + case OP_CREF: + fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); + break; + + case OP_DNCREF: + { + PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; + fprintf(f, " %s Cond ref <", flag); + print_custring(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } + break; + + case OP_RREF: + c = GET2(code, 1); + if (c == RREF_ANY) + fprintf(f, " Cond recurse any"); + else + fprintf(f, " Cond recurse %d", c); + break; + + case OP_DNRREF: + { + PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; + fprintf(f, " %s Cond recurse <", flag); + print_custring(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } + break; + + case OP_FALSE: + fprintf(f, " Cond false"); + break; + + case OP_TRUE: + fprintf(f, " Cond true"); + break; + + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + flag = "/i"; + /* Fall through */ + case OP_STAR: + case OP_MINSTAR: + case OP_POSSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + fprintf(f, " %s ", flag); + + if (*code >= OP_TYPESTAR) + { + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) + { + print_prop(f, code + 1, "", " "); + extra = 2; + } + else fprintf(f, "%s", OP_names[code[1]]); + } + else extra = print_char(f, code+1, utf); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_EXACTI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + flag = "/i"; + /* Fall through */ + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + fprintf(f, " %s ", flag); + extra = print_char(f, code + 1 + IMM2_SIZE, utf); + fprintf(f, "{"); + if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?"); + else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+"); + break; + + case OP_TYPEEXACT: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + { + print_prop(f, code + IMM2_SIZE + 1, " ", " "); + extra = 2; + } + else fprintf(f, " %s", OP_names[code[1 + IMM2_SIZE]]); + fprintf(f, "{"); + if (*code != OP_TYPEEXACT) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); + else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); + break; + + case OP_NOTI: + flag = "/i"; + /* Fall through */ + case OP_NOT: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1, utf); + fprintf(f, "]"); + break; + + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + flag = "/i"; + /* Fall through */ + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPOSSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSQUERY: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1, utf); + fprintf(f, "]%s", OP_names[*code]); + break; + + case OP_NOTEXACTI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + flag = "/i"; + /* Fall through */ + + case OP_NOTEXACT: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTPOSUPTO: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1 + IMM2_SIZE, utf); + fprintf(f, "]{"); + if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); + else + if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); + break; + + case OP_RECURSE: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_REFI: + flag = "/i"; + /* Fall through */ + case OP_REF: + fprintf(f, " %s \\%d", flag, GET2(code,1)); + ccode = code + OP_lengths[*code]; + goto CLASS_REF_REPEAT; + + case OP_DNREFI: + flag = "/i"; + /* Fall through */ + case OP_DNREF: + { + PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; + fprintf(f, " %s \\k<", flag); + print_custring(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } + ccode = code + OP_lengths[*code]; + goto CLASS_REF_REPEAT; + + case OP_CALLOUT: + fprintf(f, " %s %d %d %d", OP_names[*code], code[1 + 2*LINK_SIZE], + GET(code, 1), GET(code, 1 + LINK_SIZE)); + break; + + case OP_CALLOUT_STR: + c = code[1 + 4*LINK_SIZE]; + fprintf(f, " %s %c", OP_names[*code], c); + extra = GET(code, 1 + 2*LINK_SIZE); + print_custring_bylen(f, code + 2 + 4*LINK_SIZE, extra - 3 - 4*LINK_SIZE); + for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) + if (c == PRIV(callout_start_delims)[i]) + { + c = PRIV(callout_end_delims)[i]; + break; + } + fprintf(f, "%c %d %d %d", c, GET(code, 1 + 3*LINK_SIZE), GET(code, 1), + GET(code, 1 + LINK_SIZE)); + break; + + case OP_PROP: + case OP_NOTPROP: + print_prop(f, code, " ", ""); + break; + + /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm + in having this code always here, and it makes it less messy without all + those #ifdefs. */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + unsigned int min, max; + BOOL printmap; + BOOL invertmap = FALSE; + uint8_t *map; + uint8_t inverted_map[32]; + + fprintf(f, " ["); + + if (*code == OP_XCLASS) + { + extra = GET(code, 1); + ccode = code + LINK_SIZE + 1; + printmap = (*ccode & XCL_MAP) != 0; + if ((*ccode & XCL_NOT) != 0) + { + invertmap = (*ccode & XCL_HASPROP) == 0; + fprintf(f, "^"); + } + ccode++; + } + else + { + printmap = TRUE; + ccode = code + 1; + } + + /* Print a bit map */ + + if (printmap) + { + map = (uint8_t *)ccode; + if (invertmap) + { + for (i = 0; i < 32; i++) inverted_map[i] = ~map[i]; + map = inverted_map; + } + + for (i = 0; i < 256; i++) + { + if ((map[i/8] & (1 << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((map[j/8] & (1 << (j&7))) == 0) break; + if (i == '-' || i == ']') fprintf(f, "\\"); + if (PRINTABLE(i)) fprintf(f, "%c", i); + else fprintf(f, "\\x%02x", i); + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == ']') fprintf(f, "\\"); + if (PRINTABLE(j)) fprintf(f, "%c", j); + else fprintf(f, "\\x%02x", j); + } + i = j; + } + } + ccode += 32 / sizeof(PCRE2_UCHAR); + } + + /* For an XCLASS there is always some additional data */ + + if (*code == OP_XCLASS) + { + PCRE2_UCHAR ch; + while ((ch = *ccode++) != XCL_END) + { + BOOL not = FALSE; + const char *notch = ""; + + switch(ch) + { + case XCL_NOTPROP: + not = TRUE; + notch = "^"; + /* Fall through */ + + case XCL_PROP: + { + unsigned int ptype = *ccode++; + unsigned int pvalue = *ccode++; + + switch(ptype) + { + case PT_PXGRAPH: + fprintf(f, "[:%sgraph:]", notch); + break; + + case PT_PXPRINT: + fprintf(f, "[:%sprint:]", notch); + break; + + case PT_PXPUNCT: + fprintf(f, "[:%spunct:]", notch); + break; + + default: + fprintf(f, "\\%c{%s}", (not? 'P':'p'), + get_ucpname(ptype, pvalue)); + break; + } + } + break; + + default: + ccode += 1 + print_char(f, ccode, utf); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, utf); + } + break; + } + } + } + + /* Indicate a non-UTF class which was created by negation */ + + fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); + + /* Handle repeats after a class or a back reference */ + + CLASS_REF_REPEAT: + switch(*ccode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + fprintf(f, "%s", OP_names[*ccode]); + extra += OP_lengths[*ccode]; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + min = GET2(ccode,1); + max = GET2(ccode,1 + IMM2_SIZE); + if (max == 0) fprintf(f, "{%u,}", min); + else fprintf(f, "{%u,%u}", min, max); + if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); + else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+"); + extra += OP_lengths[*ccode]; + break; + + /* Do nothing if it's not a repeat; this code stops picky compilers + warning about the lack of a default code path. */ + + default: + break; + } + } + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + fprintf(f, " %s ", OP_names[*code]); + print_custring_bylen(f, code + 2, code[1]); + extra += code[1]; + break; + + case OP_THEN: + fprintf(f, " %s", OP_names[*code]); + break; + + case OP_CIRCM: + case OP_DOLLM: + flag = "/m"; + /* Fall through */ + + /* Anything else is just an item with no data, but possibly a flag. */ + + default: + fprintf(f, " %s %s", flag, OP_names[*code]); + break; + } + + code += OP_lengths[*code] + extra; + fprintf(f, "\n"); + } +} + +/* End of pcre2_printint.c */ diff --git a/pcre2/src/pcre2_serialize.c b/pcre2/src/pcre2_serialize.c new file mode 100644 index 000000000..8c44acfdc --- /dev/null +++ b/pcre2/src/pcre2_serialize.c @@ -0,0 +1,258 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains functions for serializing and deserializing +a sequence of compiled codes. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "pcre2_internal.h" + +/* Magic number to provide a small check against being handed junk. */ + +#define SERIALIZED_DATA_MAGIC 0x50523253u + +/* Deserialization is limited to the current PCRE version and +character width. */ + +#define SERIALIZED_DATA_VERSION \ + ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16)) + +#define SERIALIZED_DATA_CONFIG \ + (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16)) + + + +/************************************************* +* Serialize compiled patterns * +*************************************************/ + +PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION +pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes, + uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size, + pcre2_general_context *gcontext) +{ +uint8_t *bytes; +uint8_t *dst_bytes; +int32_t i; +PCRE2_SIZE total_size; +const pcre2_real_code *re; +const uint8_t *tables; +pcre2_serialized_data *data; + +const pcre2_memctl *memctl = (gcontext != NULL) ? + &gcontext->memctl : &PRIV(default_compile_context).memctl; + +if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL) + return PCRE2_ERROR_NULL; + +if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; + +/* Compute total size. */ +total_size = sizeof(pcre2_serialized_data) + tables_length; +tables = NULL; + +for (i = 0; i < number_of_codes; i++) + { + if (codes[i] == NULL) return PCRE2_ERROR_NULL; + re = (const pcre2_real_code *)(codes[i]); + if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; + if (tables == NULL) + tables = re->tables; + else if (tables != re->tables) + return PCRE2_ERROR_MIXEDTABLES; + total_size += re->blocksize; + } + +/* Initialize the byte stream. */ +bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data); +if (bytes == NULL) return PCRE2_ERROR_NOMEMORY; + +/* The controller is stored as a hidden parameter. */ +memcpy(bytes, memctl, sizeof(pcre2_memctl)); +bytes += sizeof(pcre2_memctl); + +data = (pcre2_serialized_data *)bytes; +data->magic = SERIALIZED_DATA_MAGIC; +data->version = SERIALIZED_DATA_VERSION; +data->config = SERIALIZED_DATA_CONFIG; +data->number_of_codes = number_of_codes; + +/* Copy all compiled code data. */ +dst_bytes = bytes + sizeof(pcre2_serialized_data); +memcpy(dst_bytes, tables, tables_length); +dst_bytes += tables_length; + +for (i = 0; i < number_of_codes; i++) + { + re = (const pcre2_real_code *)(codes[i]); + memcpy(dst_bytes, (char *)re, re->blocksize); + dst_bytes += re->blocksize; + } + +*serialized_bytes = bytes; +*serialized_size = total_size; +return number_of_codes; +} + + +/************************************************* +* Deserialize compiled patterns * +*************************************************/ + +PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION +pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes, + const uint8_t *bytes, pcre2_general_context *gcontext) +{ +const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; +const pcre2_memctl *memctl = (gcontext != NULL) ? + &gcontext->memctl : &PRIV(default_compile_context).memctl; + +const uint8_t *src_bytes; +pcre2_real_code *dst_re; +uint8_t *tables; +int32_t i, j; + +/* Sanity checks. */ + +if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL; +if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; +if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; +if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; +if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; + +if (number_of_codes > data->number_of_codes) + number_of_codes = data->number_of_codes; + +src_bytes = bytes + sizeof(pcre2_serialized_data); + +/* Decode tables. The reference count for the tables is stored immediately +following them. */ + +tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data); +if (tables == NULL) return PCRE2_ERROR_NOMEMORY; + +memcpy(tables, src_bytes, tables_length); +*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes; +src_bytes += tables_length; + +/* Decode the byte stream. We must not try to read the size from the compiled +code block in the stream, because it might be unaligned, which causes errors on +hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type +of the blocksize field is given its own name to ensure that it is the same here +as in the block. */ + +for (i = 0; i < number_of_codes; i++) + { + CODE_BLOCKSIZE_TYPE blocksize; + memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize), + sizeof(CODE_BLOCKSIZE_TYPE)); + + /* The allocator provided by gcontext replaces the original one. */ + + dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize, + (pcre2_memctl *)gcontext); + if (dst_re == NULL) + { + memctl->free(tables, memctl->memory_data); + for (j = 0; j < i; j++) + { + memctl->free(codes[j], memctl->memory_data); + codes[j] = NULL; + } + return PCRE2_ERROR_NOMEMORY; + } + + /* The new allocator must be preserved. */ + + memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl), + src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl)); + + /* At the moment only one table is supported. */ + + dst_re->tables = tables; + dst_re->executable_jit = NULL; + dst_re->flags |= PCRE2_DEREF_TABLES; + + codes[i] = dst_re; + src_bytes += blocksize; + } + +return number_of_codes; +} + + +/************************************************* +* Get the number of serialized patterns * +*************************************************/ + +PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION +pcre2_serialize_get_number_of_codes(const uint8_t *bytes) +{ +const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; + +if (data == NULL) return PCRE2_ERROR_NULL; +if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; +if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; +if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; + +return data->number_of_codes; +} + + +/************************************************* +* Free the allocated stream * +*************************************************/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_serialize_free(uint8_t *bytes) +{ +if (bytes != NULL) + { + pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl)); + memctl->free(memctl, memctl->memory_data); + } +} + +/* End of pcre2_serialize.c */ diff --git a/pcre2/src/pcre2_string_utils.c b/pcre2/src/pcre2_string_utils.c new file mode 100644 index 000000000..2a1f28262 --- /dev/null +++ b/pcre2/src/pcre2_string_utils.c @@ -0,0 +1,201 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains internal functions for comparing and finding the length +of strings. These are used instead of strcmp() etc because the standard +functions work only on 8-bit data. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + +/************************************************* +* Compare two zero-terminated PCRE2 strings * +*************************************************/ + +/* +Arguments: + str1 first string + str2 second string + +Returns: 0, 1, or -1 +*/ + +int +PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2) +{ +PCRE2_UCHAR c1, c2; +while (*str1 != '\0' || *str2 != '\0') + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) return ((c1 > c2) << 1) - 1; + } +return 0; +} + + +/************************************************* +* Compare zero-terminated PCRE2 & 8-bit strings * +*************************************************/ + +/* As the 8-bit string is almost always a literal, its type is specified as +const char *. + +Arguments: + str1 first string + str2 second string + +Returns: 0, 1, or -1 +*/ + +int +PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2) +{ +PCRE2_UCHAR c1, c2; +while (*str1 != '\0' || *str2 != '\0') + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) return ((c1 > c2) << 1) - 1; + } +return 0; +} + + +/************************************************* +* Compare two PCRE2 strings, given a length * +*************************************************/ + +/* +Arguments: + str1 first string + str2 second string + len the length + +Returns: 0, 1, or -1 +*/ + +int +PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len) +{ +PCRE2_UCHAR c1, c2; +for (; len > 0; len--) + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) return ((c1 > c2) << 1) - 1; + } +return 0; +} + + +/************************************************* +* Compare PCRE2 string to 8-bit string by length * +*************************************************/ + +/* As the 8-bit string is almost always a literal, its type is specified as +const char *. + +Arguments: + str1 first string + str2 second string + len the length + +Returns: 0, 1, or -1 +*/ + +int +PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len) +{ +PCRE2_UCHAR c1, c2; +for (; len > 0; len--) + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) return ((c1 > c2) << 1) - 1; + } +return 0; +} + + +/************************************************* +* Find the length of a PCRE2 string * +*************************************************/ + +/* +Argument: the string +Returns: the length +*/ + +PCRE2_SIZE +PRIV(strlen)(PCRE2_SPTR str) +{ +PCRE2_SIZE c = 0; +while (*str++ != 0) c++; +return c; +} + + +/************************************************* +* Copy 8-bit 0-terminated string to PCRE2 string * +*************************************************/ + +/* Arguments: + str1 buffer to receive the string + str2 8-bit string to be copied + +Returns: the number of code units used (excluding trailing zero) +*/ + +PCRE2_SIZE +PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2) +{ +PCRE2_UCHAR *t = str1; +while (*str2 != 0) *t++ = *str2++; +*t = 0; +return t - str1; +} + +/* End of pcre2_string_utils.c */ diff --git a/pcre2/src/pcre2_study.c b/pcre2/src/pcre2_study.c new file mode 100644 index 000000000..18932adef --- /dev/null +++ b/pcre2/src/pcre2_study.c @@ -0,0 +1,1575 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains functions for scanning a compiled pattern and +collecting data (e.g. minimum matching length). */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "pcre2_internal.h" + + +/* Set a bit in the starting code unit bit map. */ + +#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1 << ((c)&7)) + +/* Returns from set_start_bits() */ + +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; + + +/************************************************* +* Find the minimum subject length for a group * +*************************************************/ + +/* Scan a parenthesized group and compute the minimum length of subject that +is needed to match it. This is a lower bound; it does not mean there is a +string of that length that matches. In UTF mode, the result is in characters +rather than code units. The field in a compiled pattern for storing the minimum +length is 16-bits long (on the grounds that anything longer than that is +pathological), so we give up when we reach that amount. This also means that +integer overflow for really crazy patterns cannot happen. + +Arguments: + re compiled pattern block + code pointer to start of group (the bracket) + startcode pointer to start of the whole pattern's code + utf UTF flag + recurses chain of recurse_check to catch mutual recursion + countptr pointer to call count (to catch over complexity) + +Returns: the minimum length + -1 \C in UTF-8 mode + or (*ACCEPT) + or pattern too complicated + or back reference to duplicate name/number + -2 internal error (missing capturing bracket) + -3 internal error (opcode not listed) +*/ + +static int +find_minlength(const pcre2_real_code *re, PCRE2_SPTR code, + PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr) +{ +int length = -1; +int prev_cap_recno = -1; +int prev_cap_d = 0; +int prev_recurse_recno = -1; +int prev_recurse_d = 0; +uint32_t once_fudge = 0; +BOOL had_recurse = FALSE; +BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0; +recurse_check this_recurse; +register int branchlength = 0; +register PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE; + +/* If this is a "could be empty" group, its minimum length is 0. */ + +if (*code >= OP_SBRA && *code <= OP_SCOND) return 0; + +/* Skip over capturing bracket number */ + +if (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE; + +/* A large and/or complex regex can take too long to process. */ + +if ((*countptr)++ > 1000) return -1; + +/* Scan along the opcodes for this branch. If we get to the end of the branch, +check the length against that of the other branches. If the accumulated length +passes 16-bits, stop. */ + +for (;;) + { + int d, min, recno; + PCRE2_UCHAR *cs, *ce; + register PCRE2_UCHAR op = *cc; + + if (branchlength >= UINT16_MAX) return UINT16_MAX; + + switch (op) + { + case OP_COND: + case OP_SCOND: + + /* If there is only one branch in a condition, the implied branch has zero + length, so we don't add anything. This covers the DEFINE "condition" + automatically. If there are two branches we can treat it the same as any + other non-capturing subpattern. */ + + cs = cc + GET(cc, 1); + if (*cs != OP_ALT) + { + cc = cs + 1 + LINK_SIZE; + break; + } + goto PROCESS_NON_CAPTURE; + + /* There's a special case of OP_ONCE, when it is wrapped round an + OP_RECURSE. We'd like to process the latter at this level so that + remembering the value works for repeated cases. So we do nothing, but + set a fudge value to skip over the OP_KET after the recurse. */ + + case OP_ONCE: + if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET) + { + once_fudge = 1 + LINK_SIZE; + cc += 1 + LINK_SIZE; + break; + } + /* Fall through */ + + case OP_ONCE_NC: + case OP_BRA: + case OP_SBRA: + case OP_BRAPOS: + case OP_SBRAPOS: + PROCESS_NON_CAPTURE: + d = find_minlength(re, cc, startcode, utf, recurses, countptr); + if (d < 0) return d; + branchlength += d; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* To save time for repeated capturing subpatterns, we remember the + length of the previous one. Unfortunately we can't do the same for + the unnumbered ones above. Nor can we do this if (?| is present in the + pattern because captures with the same number are not then identical. */ + + case OP_CBRA: + case OP_SCBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: + recno = dupcapused? prev_cap_recno - 1 : (int)GET2(cc, 1+LINK_SIZE); + if (recno != prev_cap_recno) + { + prev_cap_recno = recno; + prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr); + if (prev_cap_d < 0) return prev_cap_d; + } + branchlength += prev_cap_d; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* ACCEPT makes things far too complicated; we have to give up. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + return -1; + + /* Reached end of a branch; if it's a ket it is the end of a nested + call. If it's ALT it is an alternation in a nested call. If it is END it's + the end of the outer call. All can be handled by the same code. If an + ACCEPT was previously encountered, use the length that was in force at that + time, and pass back the shortest ACCEPT length. */ + + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_END: + if (length < 0 || (!had_recurse && branchlength < length)) + length = branchlength; + if (op != OP_ALT) return length; + cc += 1 + LINK_SIZE; + branchlength = 0; + had_recurse = FALSE; + break; + + /* Skip over assertive subpatterns */ + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do cc += GET(cc, 1); while (*cc == OP_ALT); + /* Fall through */ + + /* Skip over things that don't match chars */ + + case OP_REVERSE: + case OP_CREF: + case OP_DNCREF: + case OP_RREF: + case OP_DNRREF: + case OP_FALSE: + case OP_TRUE: + case OP_CALLOUT: + case OP_SOD: + case OP_SOM: + case OP_EOD: + case OP_EODN: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + cc += PRIV(OP_lengths)[*cc]; + break; + + case OP_CALLOUT_STR: + cc += GET(cc, 1 + 2*LINK_SIZE); + break; + + /* Skip over a subpattern that has a {0} or {0,x} quantifier */ + + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + case OP_SKIPZERO: + cc += PRIV(OP_lengths)[*cc]; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* Handle literal characters and + repetitions */ + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_PLUS: + case OP_PLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + branchlength++; + cc += 2; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + branchlength++; + cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2; + break; + + /* Handle exact repetitions. The count is already in characters, but we + may need to skip over a multibyte character in UTF mode. */ + + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + branchlength += GET2(cc,1); + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + case OP_TYPEEXACT: + branchlength += GET2(cc,1); + cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); + break; + + /* Handle single-char non-literal matchers */ + + case OP_PROP: + case OP_NOTPROP: + cc += 2; + /* Fall through */ + + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_EXTUNI: + case OP_HSPACE: + case OP_NOT_HSPACE: + case OP_VSPACE: + case OP_NOT_VSPACE: + branchlength++; + cc++; + break; + + /* "Any newline" might match two characters, but it also might match just + one. */ + + case OP_ANYNL: + branchlength += 1; + cc++; + break; + + /* The single-byte matcher means we can't proceed in UTF mode. (In + non-UTF mode \C will actually be turned into OP_ALLANY, so won't ever + appear, but leave the code, just in case.) */ + + case OP_ANYBYTE: +#ifdef SUPPORT_UNICODE + if (utf) return -1; +#endif + branchlength++; + cc++; + break; + + /* For repeated character types, we have to test for \p and \P, which have + an extra two bytes of parameters. */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSQUERY: + if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; + cc += PRIV(OP_lengths)[op]; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + if (cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; + cc += PRIV(OP_lengths)[op]; + break; + + /* Check a class for variable quantification */ + + case OP_CLASS: + case OP_NCLASS: +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + /* The original code caused an unsigned overflow in 64 bit systems, + so now we use a conditional statement. */ + if (op == OP_XCLASS) + cc += GET(cc, 1); + else + cc += PRIV(OP_lengths)[OP_CLASS]; +#else + cc += PRIV(OP_lengths)[OP_CLASS]; +#endif + + switch (*cc) + { + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + branchlength++; + /* Fall through */ + + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + branchlength += GET2(cc,1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + branchlength++; + break; + } + break; + + /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same + way: we find the minimum length for the subpattern. A recursion + (backreference or subroutine) causes an a flag to be set that causes the + length of this branch to be ignored. The logic is that a recursion can only + make sense if there is another alternative that stops the recursing. That + will provide the minimum length (when no recursion happens). + + If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket + matches an empty string (by default it causes a matching failure), so in + that case we must set the minimum length to zero. */ + + /* Duplicate named pattern back reference. We cannot reliably find a length + for this if duplicate numbers are present in the pattern. */ + + case OP_DNREF: + case OP_DNREFI: + if (dupcapused) return -1; + if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) + { + int count = GET2(cc, 1+IMM2_SIZE); + PCRE2_UCHAR *slot = + (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + GET2(cc, 1) * re->name_entry_size; + + d = INT_MAX; + + /* Scan all groups with the same name */ + + while (count-- > 0) + { + ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0)); + if (cs == NULL) return -2; + do ce += GET(ce, 1); while (*ce == OP_ALT); + if (cc > cs && cc < ce) /* Simple recursion */ + { + d = 0; + had_recurse = TRUE; + break; + } + else + { + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + d = 0; + had_recurse = TRUE; + break; + } + else + { + int dd; + this_recurse.prev = recurses; + this_recurse.group = cs; + dd = find_minlength(re, cs, startcode, utf, &this_recurse, countptr); + if (dd < d) d = dd; + } + } + slot += re->name_entry_size; + } + } + else d = 0; + cc += 1 + 2*IMM2_SIZE; + goto REPEAT_BACK_REFERENCE; + + /* Single back reference. We cannot find a length for this if duplicate + numbers are present in the pattern. */ + + case OP_REF: + case OP_REFI: + if (dupcapused) return -1; + if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) + { + ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); + if (cs == NULL) return -2; + do ce += GET(ce, 1); while (*ce == OP_ALT); + if (cc > cs && cc < ce) /* Simple recursion */ + { + d = 0; + had_recurse = TRUE; + } + else + { + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + d = 0; + had_recurse = TRUE; + } + else + { + this_recurse.prev = recurses; + this_recurse.group = cs; + d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr); + } + } + } + else d = 0; + cc += 1 + IMM2_SIZE; + + /* Handle repeated back references */ + + REPEAT_BACK_REFERENCE: + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + min = 0; + cc++; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + min = 1; + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + min = GET2(cc, 1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + min = 1; + break; + } + + /* Take care not to overflow: (1) min and d are ints, so check that their + product is not greater than INT_MAX. (2) branchlength is limited to + UINT16_MAX (checked at the top of the loop). */ + + if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d) + branchlength = UINT16_MAX; + else branchlength += min * d; + break; + + /* Recursion always refers to the first occurrence of a subpattern with a + given number. Therefore, we can always make use of caching, even when the + pattern contains multiple subpatterns with the same number. */ + + case OP_RECURSE: + cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1); + recno = GET2(cs, 1+LINK_SIZE); + if (recno == prev_recurse_recno) + { + branchlength += prev_recurse_d; + } + else + { + do ce += GET(ce, 1); while (*ce == OP_ALT); + if (cc > cs && cc < ce) /* Simple recursion */ + had_recurse = TRUE; + else + { + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + had_recurse = TRUE; + else + { + this_recurse.prev = recurses; + this_recurse.group = cs; + prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse, + countptr); + if (prev_recurse_d < 0) return prev_recurse_d; + prev_recurse_recno = recno; + branchlength += prev_recurse_d; + } + } + } + cc += 1 + LINK_SIZE + once_fudge; + once_fudge = 0; + break; + + /* Anything else does not or need not match a character. We can get the + item's length from the table, but for those that can match zero occurrences + of a character, we must take special action for UTF-8 characters. As it + happens, the "NOT" versions of these opcodes are used at present only for + ASCII characters, so they could be omitted from this list. However, in + future that may change, so we include them here so as not to leave a + gotcha for a future maintainer. */ + + case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + + cc += PRIV(OP_lengths)[op]; +#ifdef SUPPORT_UNICODE + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + /* Skip these, but we need to add in the name length. */ + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += PRIV(OP_lengths)[op] + cc[1]; + break; + + /* The remaining opcodes are just skipped over. */ + + case OP_CLOSE: + case OP_COMMIT: + case OP_FAIL: + case OP_PRUNE: + case OP_SET_SOM: + case OP_SKIP: + case OP_THEN: + cc += PRIV(OP_lengths)[op]; + break; + + /* This should not occur: we list all opcodes explicitly so that when + new ones get added they are properly considered. */ + + default: + return -3; + } + } +/* Control never gets here */ +} + + + +/************************************************* +* Set a bit and maybe its alternate case * +*************************************************/ + +/* Given a character, set its first code unit's bit in the table, and also the +corresponding bit for the other version of a letter if we are caseless. + +Arguments: + re points to the regex block + p points to the first code unit of the character + caseless TRUE if caseless + utf TRUE for UTF mode + +Returns: pointer after the character +*/ + +static PCRE2_SPTR +set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf) +{ +uint32_t c = *p++; /* First code unit */ +(void)utf; /* Stop compiler warning when UTF not supported */ + +/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for +0xff. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 +if (c > 0xff) SET_BIT(0xff); else +#endif + +SET_BIT(c); + +/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find +the end of the character, even when caseless. */ + +#ifdef SUPPORT_UNICODE +if (utf) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (c >= 0xc0) GETUTF8INC(c, p); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p); +#endif + } +#endif /* SUPPORT_UNICODE */ + +/* If caseless, handle the other case of the character. */ + +if (caseless) + { + if (utf) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + PCRE2_UCHAR buff[6]; + c = UCD_OTHERCASE(c); + (void)PRIV(ord2utf)(c, buff); + SET_BIT(buff[0]); +#else /* 16-bit or 32-bit mode */ + c = UCD_OTHERCASE(c); + if (c > 0xff) SET_BIT(0xff); else SET_BIT(c); +#endif + } + + /* Not UTF */ + + else if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]); + } + +return p; +} + + + +/************************************************* +* Set bits for a positive character type * +*************************************************/ + +/* This function sets starting bits for a character type. In UTF-8 mode, we can +only do a direct setting for bytes less than 128, as otherwise there can be +confusion with bytes in the middle of UTF-8 characters. In a "traditional" +environment, the tables will only recognize ASCII characters anyway, but in at +least one Windows environment, some higher bytes bits were set in the tables. +So we deal with that case by considering the UTF-8 encoding. + +Arguments: + re the regex block + cbit type the type of character wanted + table_limit 32 for non-UTF-8; 16 for UTF-8 + +Returns: nothing +*/ + +static void +set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit) +{ +register uint32_t c; +for (c = 0; c < table_limit; c++) + re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type]; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +if (table_limit == 32) return; +for (c = 128; c < 256; c++) + { + if ((re->tables[cbits_offset + c/8] & (1 << (c&7))) != 0) + { + PCRE2_UCHAR buff[6]; + (void)PRIV(ord2utf)(c, buff); + SET_BIT(buff[0]); + } + } +#endif /* UTF-8 */ +} + + +/************************************************* +* Set bits for a negative character type * +*************************************************/ + +/* This function sets starting bits for a negative character type such as \D. +In UTF-8 mode, we can only do a direct setting for bytes less than 128, as +otherwise there can be confusion with bytes in the middle of UTF-8 characters. +Unlike in the positive case, where we can set appropriate starting bits for +specific high-valued UTF-8 characters, in this case we have to set the bits for +all high-valued characters. The lowest is 0xc2, but we overkill by starting at +0xc0 (192) for simplicity. + +Arguments: + re the regex block + cbit type the type of character wanted + table_limit 32 for non-UTF-8; 16 for UTF-8 + +Returns: nothing +*/ + +static void +set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit) +{ +register uint32_t c; +for (c = 0; c < table_limit; c++) + re->start_bitmap[c] |= ~(re->tables[c+cbits_offset+cbit_type]); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff; +#endif +} + + + +/************************************************* +* Create bitmap of starting bytes * +*************************************************/ + +/* This function scans a compiled unanchored expression recursively and +attempts to build a bitmap of the set of possible starting code units whose +values are less than 256. In 16-bit and 32-bit mode, values above 255 all cause +the 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode +we pass a value of 16 rather than 32 as the final argument. (See comments in +those functions for the reason.) + +The SSB_CONTINUE return is useful for parenthesized groups in patterns such as +(a*)b where the group provides some optional starting code units but scanning +must continue at the outer level to find at least one mandatory code unit. At +the outermost level, this function fails unless the result is SSB_DONE. + +Arguments: + re points to the compiled regex block + code points to an expression + utf TRUE if in UTF mode + +Returns: SSB_FAIL => Failed to find any starting code units + SSB_DONE => Found mandatory starting code units + SSB_CONTINUE => Found optional starting code units + SSB_UNKNOWN => Hit an unrecognized opcode +*/ + +static int +set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf) +{ +register uint32_t c; +int yield = SSB_DONE; + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +int table_limit = utf? 16:32; +#else +int table_limit = 32; +#endif + +do + { + BOOL try_next = TRUE; + PCRE2_SPTR tcode = code + 1 + LINK_SIZE; + + if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE; + + while (try_next) /* Loop for items in this branch */ + { + int rc; + uint8_t *classmap = NULL; + + switch(*tcode) + { + /* If we reach something we don't understand, it means a new opcode has + been created that hasn't been added to this function. Hopefully this + problem will be discovered during testing. */ + + default: + return SSB_UNKNOWN; + + /* Fail for a valid opcode that implies no starting bits. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_ALLANY: + case OP_ANY: + case OP_ANYBYTE: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: + case OP_COND: + case OP_CREF: + case OP_FALSE: + case OP_TRUE: + case OP_DNCREF: + case OP_DNREF: + case OP_DNREFI: + case OP_DNRREF: + case OP_DOLL: + case OP_DOLLM: + case OP_END: + case OP_EOD: + case OP_EODN: + case OP_EXTUNI: + case OP_FAIL: + case OP_MARK: + case OP_NOT: + case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_NOTI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTPROP: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_RECURSE: + case OP_REF: + case OP_REFI: + case OP_REVERSE: + case OP_RREF: + case OP_SCOND: + case OP_SET_SOM: + case OP_SKIP: + case OP_SKIP_ARG: + case OP_SOD: + case OP_SOM: + case OP_THEN: + case OP_THEN_ARG: + return SSB_FAIL; + + /* A "real" property test implies no starting bits, but the fake property + PT_CLIST identifies a list of characters. These lists are short, as they + are used for characters with more than one "other case", so there is no + point in recognizing them for OP_NOTPROP. */ + + case OP_PROP: + if (tcode[1] != PT_CLIST) return SSB_FAIL; + { + const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2]; + while ((c = *p++) < NOTACHAR) + { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (utf) + { + PCRE2_UCHAR buff[6]; + (void)PRIV(ord2utf)(c, buff); + c = buff[0]; + } +#endif + if (c > 0xff) SET_BIT(0xff); else SET_BIT(c); + } + } + try_next = FALSE; + break; + + /* We can ignore word boundary tests. */ + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + tcode++; + break; + + /* If we hit a bracket or a positive lookahead assertion, recurse to set + bits from within the subpattern. If it can't find anything, we have to + give up. If it finds some mandatory character(s), we are done for this + branch. Otherwise, carry on scanning after the subpattern. */ + + case OP_BRA: + case OP_SBRA: + case OP_CBRA: + case OP_SCBRA: + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_ONCE: + case OP_ONCE_NC: + case OP_ASSERT: + rc = set_start_bits(re, tcode, utf); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; + if (rc == SSB_DONE) try_next = FALSE; else + { + do tcode += GET(tcode, 1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + } + break; + + /* If we hit ALT or KET, it means we haven't found anything mandatory in + this branch, though we might have found something optional. For ALT, we + continue with the next alternative, but we have to arrange that the final + result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET, + return SSB_CONTINUE: if this is the top level, that indicates failure, + but after a nested subpattern, it causes scanning to continue. */ + + case OP_ALT: + yield = SSB_CONTINUE; + try_next = FALSE; + break; + + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + return SSB_CONTINUE; + + /* Skip over callout */ + + case OP_CALLOUT: + tcode += PRIV(OP_lengths)[OP_CALLOUT]; + break; + + case OP_CALLOUT_STR: + tcode += GET(tcode, 1 + 2*LINK_SIZE); + break; + + /* Skip over lookbehind and negative lookahead assertions */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do tcode += GET(tcode, 1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* BRAZERO does the bracket, but carries on. */ + + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + rc = set_start_bits(re, ++tcode, utf); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* SKIPZERO skips the bracket. */ + + case OP_SKIPZERO: + tcode++; + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* Single-char * or ? sets the bit and tries the next item */ + + case OP_STAR: + case OP_MINSTAR: + case OP_POSSTAR: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + tcode = set_table_bit(re, tcode + 1, FALSE, utf); + break; + + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + tcode = set_table_bit(re, tcode + 1, TRUE, utf); + break; + + /* Single-char upto sets the bit and tries the next */ + + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf); + break; + + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf); + break; + + /* At least one single char sets the bit and stops */ + + case OP_EXACT: + tcode += IMM2_SIZE; + /* Fall through */ + case OP_CHAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + (void)set_table_bit(re, tcode + 1, FALSE, utf); + try_next = FALSE; + break; + + case OP_EXACTI: + tcode += IMM2_SIZE; + /* Fall through */ + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + (void)set_table_bit(re, tcode + 1, TRUE, utf); + try_next = FALSE; + break; + + /* Special spacing and line-terminating items. These recognize specific + lists of characters. The difference between VSPACE and ANYNL is that the + latter can match the two-character CRLF sequence, but that is not + relevant for finding the first character, so their code here is + identical. */ + + case OP_HSPACE: + SET_BIT(CHAR_HT); + SET_BIT(CHAR_SPACE); + + /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set + the bits for 0xA0 and for code units >= 255, independently of UTF. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 + SET_BIT(0xA0); + SET_BIT(0xFF); +#else + /* For the 8-bit library in UTF-8 mode, set the bits for the first code + units of horizontal space characters. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + SET_BIT(0xC2); /* For U+00A0 */ + SET_BIT(0xE1); /* For U+1680, U+180E */ + SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ + SET_BIT(0xE3); /* For U+3000 */ + } + else +#endif + /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless + the code is EBCDIC. */ + { +#ifndef EBCDIC + SET_BIT(0xA0); +#endif /* Not EBCDIC */ + } +#endif /* 8-bit support */ + + try_next = FALSE; + break; + + case OP_ANYNL: + case OP_VSPACE: + SET_BIT(CHAR_LF); + SET_BIT(CHAR_VT); + SET_BIT(CHAR_FF); + SET_BIT(CHAR_CR); + + /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set + the bits for NEL and for code units >= 255, independently of UTF. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 + SET_BIT(CHAR_NEL); + SET_BIT(0xFF); +#else + /* For the 8-bit library in UTF-8 mode, set the bits for the first code + units of vertical space characters. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + SET_BIT(0xC2); /* For U+0085 (NEL) */ + SET_BIT(0xE2); /* For U+2028, U+2029 */ + } + else +#endif + /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */ + { + SET_BIT(CHAR_NEL); + } +#endif /* 8-bit support */ + + try_next = FALSE; + break; + + /* Single character types set the bits and stop. Note that if PCRE2_UCP + is set, we do not see these op codes because \d etc are converted to + properties. Therefore, these apply in the case when only characters less + than 256 are recognized to match the types. */ + + case OP_NOT_DIGIT: + set_nottype_bits(re, cbit_digit, table_limit); + try_next = FALSE; + break; + + case OP_DIGIT: + set_type_bits(re, cbit_digit, table_limit); + try_next = FALSE; + break; + + case OP_NOT_WHITESPACE: + set_nottype_bits(re, cbit_space, table_limit); + try_next = FALSE; + break; + + case OP_WHITESPACE: + set_type_bits(re, cbit_space, table_limit); + try_next = FALSE; + break; + + case OP_NOT_WORDCHAR: + set_nottype_bits(re, cbit_word, table_limit); + try_next = FALSE; + break; + + case OP_WORDCHAR: + set_type_bits(re, cbit_word, table_limit); + try_next = FALSE; + break; + + /* One or more character type fudges the pointer and restarts, knowing + it will hit a single character type and stop there. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + tcode++; + break; + + case OP_TYPEEXACT: + tcode += 1 + IMM2_SIZE; + break; + + /* Zero or more repeats of character types set the bits and then + try again. */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + tcode += IMM2_SIZE; /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + switch(tcode[1]) + { + default: + case OP_ANY: + case OP_ALLANY: + return SSB_FAIL; + + case OP_HSPACE: + SET_BIT(CHAR_HT); + SET_BIT(CHAR_SPACE); + + /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set + the bits for 0xA0 and for code units >= 255, independently of UTF. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 + SET_BIT(0xA0); + SET_BIT(0xFF); +#else + /* For the 8-bit library in UTF-8 mode, set the bits for the first code + units of horizontal space characters. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + SET_BIT(0xC2); /* For U+00A0 */ + SET_BIT(0xE1); /* For U+1680, U+180E */ + SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ + SET_BIT(0xE3); /* For U+3000 */ + } + else +#endif + /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless + the code is EBCDIC. */ + { +#ifndef EBCDIC + SET_BIT(0xA0); +#endif /* Not EBCDIC */ + } +#endif /* 8-bit support */ + break; + + case OP_ANYNL: + case OP_VSPACE: + SET_BIT(CHAR_LF); + SET_BIT(CHAR_VT); + SET_BIT(CHAR_FF); + SET_BIT(CHAR_CR); + + /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set + the bits for NEL and for code units >= 255, independently of UTF. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 + SET_BIT(CHAR_NEL); + SET_BIT(0xFF); +#else + /* For the 8-bit library in UTF-8 mode, set the bits for the first code + units of vertical space characters. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + SET_BIT(0xC2); /* For U+0085 (NEL) */ + SET_BIT(0xE2); /* For U+2028, U+2029 */ + } + else +#endif + /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */ + { + SET_BIT(CHAR_NEL); + } +#endif /* 8-bit support */ + break; + + case OP_NOT_DIGIT: + set_nottype_bits(re, cbit_digit, table_limit); + break; + + case OP_DIGIT: + set_type_bits(re, cbit_digit, table_limit); + break; + + case OP_NOT_WHITESPACE: + set_nottype_bits(re, cbit_space, table_limit); + break; + + case OP_WHITESPACE: + set_type_bits(re, cbit_space, table_limit); + break; + + case OP_NOT_WORDCHAR: + set_nottype_bits(re, cbit_word, table_limit); + break; + + case OP_WORDCHAR: + set_type_bits(re, cbit_word, table_limit); + break; + } + + tcode += 2; + break; + + /* Extended class: if there are any property checks, or if this is a + negative XCLASS without a map, give up. If there are no property checks, + there must be wide characters on the XCLASS list, because otherwise an + XCLASS would not have been created. This means that code points >= 255 + are always potential starters. */ + +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0 || + (tcode[1 + LINK_SIZE] & (XCL_MAP|XCL_NOT)) == XCL_NOT) + return SSB_FAIL; + + /* We have a positive XCLASS or a negative one without a map. Set up the + map pointer if there is one, and fall through. */ + + classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL : + (uint8_t *)(tcode + 1 + LINK_SIZE + 1); +#endif + + /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are + in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter + because it starts a character with a value > 255. In 8-bit non-UTF mode, + there is no difference between CLASS and NCLASS. In all other wide + character modes, set the 0xFF bit to indicate code units >= 255. */ + + case OP_NCLASS: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (utf) + { + re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ + memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ + } +#elif PCRE2_CODE_UNIT_WIDTH != 8 + SET_BIT(0xFF); /* For characters >= 255 */ +#endif + /* Fall through */ + + /* Enter here for a positive non-XCLASS. If we have fallen through from + an XCLASS, classmap will already be set; just advance the code pointer. + Otherwise, set up classmap for a a non-XCLASS and advance past it. */ + + case OP_CLASS: + if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else + { + classmap = (uint8_t *)(++tcode); + tcode += 32 / sizeof(PCRE2_UCHAR); + } + + /* When wide characters are supported, classmap may be NULL. In UTF-8 + (sic) mode, the bits in a class bit map correspond to character values, + not to byte values. However, the bit map we are constructing is for byte + values. So we have to do a conversion for characters whose code point is + greater than 127. In fact, there are only two possible starting bytes for + characters in the range 128 - 255. */ + + if (classmap != NULL) + { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (utf) + { + for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c]; + for (c = 128; c < 256; c++) + { + if ((classmap[c/8] && (1 << (c&7))) != 0) + { + int d = (c >> 6) | 0xc0; /* Set bit for this starter */ + re->start_bitmap[d/8] |= (1 << (d&7)); /* and then skip on to the */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + } + } + } + else +#endif + /* In all modes except UTF-8, the two bit maps are compatible. */ + + { + for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c]; + } + } + + /* Act on what follows the class. For a zero minimum repeat, continue; + otherwise stop processing. */ + + switch (*tcode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + tcode++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; + else try_next = FALSE; + break; + + default: + try_next = FALSE; + break; + } + break; /* End of class handling case */ + } /* End of switch for opcodes */ + } /* End of try_next loop */ + + code += GET(code, 1); /* Advance to next branch */ + } +while (*code == OP_ALT); + +return yield; +} + + + +/************************************************* +* Study a compiled expression * +*************************************************/ + +/* This function is handed a compiled expression that it must study to produce +information that will speed up the matching. + +Argument: points to the compiled expression +Returns: 0 normally; non-zero should never normally occur + 1 unknown opcode in set_start_bits + 2 missing capturing bracket + 3 unknown opcode in find_minlength +*/ + +int +PRIV(study)(pcre2_real_code *re) +{ +int min; +int count = 0; +PCRE2_UCHAR *code; +BOOL utf = (re->overall_options & PCRE2_UTF) != 0; + +/* Find start of compiled code */ + +code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_entry_size * re->name_count; + +/* For an anchored pattern, or an unanchored pattern that has a first code +unit, or a multiline pattern that matches only at "line start", there is no +point in seeking a list of starting code units. */ + +if ((re->overall_options & PCRE2_ANCHORED) == 0 && + (re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) + { + int rc = set_start_bits(re, code, utf); + if (rc == SSB_UNKNOWN) return 1; + if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET; + } + +/* Find the minimum length of subject string. If it can match an empty string, +the minimum length is already known. */ + +if ((re->flags & PCRE2_MATCH_EMPTY) == 0) + { + switch(min = find_minlength(re, code, code, utf, NULL, &count)) + { + case -1: /* \C in UTF mode or (*ACCEPT) or over-complex regex */ + break; /* Leave minlength unchanged (will be zero) */ + + case -2: + return 2; /* missing capturing bracket */ + + case -3: + return 3; /* unrecognized opcode */ + + default: + if (min > UINT16_MAX) min = UINT16_MAX; + re->minlength = min; + break; + } + } + +return 0; +} + +/* End of pcre2_study.c */ diff --git a/pcre2/src/pcre2_substitute.c b/pcre2/src/pcre2_substitute.c new file mode 100644 index 000000000..0bf781efc --- /dev/null +++ b/pcre2/src/pcre2_substitute.c @@ -0,0 +1,850 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + +#define PTR_STACK_SIZE 20 + +#define SUBSTITUTE_OPTIONS \ + (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \ + PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \ + PCRE2_SUBSTITUTE_UNSET_EMPTY) + + + +/************************************************* +* Find end of substitute text * +*************************************************/ + +/* In extended mode, we recognize ${name:+set text:unset text} and similar +constructions. This requires the identification of unescaped : and } +characters. This function scans for such. It must deal with nested ${ +constructions. The pointer to the text is updated, either to the required end +character, or to where an error was detected. + +Arguments: + code points to the compiled expression (for options) + ptrptr points to the pointer to the start of the text (updated) + ptrend end of the whole string + last TRUE if the last expected string (only } recognized) + +Returns: 0 on success + negative error code on failure +*/ + +static int +find_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, + BOOL last) +{ +int rc = 0; +uint32_t nestlevel = 0; +BOOL literal = FALSE; +PCRE2_SPTR ptr = *ptrptr; + +for (; ptr < ptrend; ptr++) + { + if (literal) + { + if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E) + { + literal = FALSE; + ptr += 1; + } + } + + else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + if (nestlevel == 0) goto EXIT; + nestlevel--; + } + + else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT; + + else if (*ptr == CHAR_DOLLAR_SIGN) + { + if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET) + { + nestlevel++; + ptr += 1; + } + } + + else if (*ptr == CHAR_BACKSLASH) + { + int erc; + int errorcode = 0; + uint32_t ch; + + if (ptr < ptrend - 1) switch (ptr[1]) + { + case CHAR_L: + case CHAR_l: + case CHAR_U: + case CHAR_u: + ptr += 1; + continue; + } + + erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode, + code->overall_options, FALSE, NULL); + if (errorcode != 0) + { + rc = errorcode; + goto EXIT; + } + + switch(erc) + { + case 0: /* Data character */ + case ESC_E: /* Isolated \E is ignored */ + break; + + case ESC_Q: + literal = TRUE; + break; + + default: + rc = PCRE2_ERROR_BADREPESCAPE; + goto EXIT; + } + } + } + +rc = PCRE2_ERROR_REPMISSINGBRACE; /* Terminator not found */ + +EXIT: +*ptrptr = ptr; +return rc; +} + + + +/************************************************* +* Match and substitute * +*************************************************/ + +/* This function applies a compiled re to a subject string and creates a new +string with substitutions. The first 7 arguments are the same as for +pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED. + +Arguments: + code points to the compiled expression + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + match_data points to a match_data block, or is NULL + context points a PCRE2 context + replacement points to the replacement string + rlength length of replacement string + buffer where to put the substituted string + blength points to length of buffer; updated to length of string + +Returns: >= 0 number of substitutions made + < 0 an error code + PCRE2_ERROR_BADREPLACEMENT means invalid use of $ +*/ + +/* This macro checks for space in the buffer before copying into it. On +overflow, either give an error immediately, or keep on, accumulating the +length. */ + +#define CHECKMEMCPY(from,length) \ + if (!overflowed && lengthleft < length) \ + { \ + if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ + overflowed = TRUE; \ + extra_needed = length - lengthleft; \ + } \ + else if (overflowed) \ + { \ + extra_needed += length; \ + } \ + else \ + { \ + memcpy(buffer + buff_offset, from, CU2BYTES(length)); \ + buff_offset += length; \ + lengthleft -= length; \ + } + +/* Here's the function */ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, + PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, + pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength, + PCRE2_UCHAR *buffer, PCRE2_SIZE *blength) +{ +int rc; +int subs; +int forcecase = 0; +int forcecasereset = 0; +uint32_t ovector_count; +uint32_t goptions = 0; +uint32_t suboptions; +BOOL match_data_created = FALSE; +BOOL literal = FALSE; +BOOL overflowed = FALSE; +#ifdef SUPPORT_UNICODE +BOOL utf = (code->overall_options & PCRE2_UTF) != 0; +#endif +PCRE2_UCHAR temp[6]; +PCRE2_SPTR ptr; +PCRE2_SPTR repend; +PCRE2_SIZE extra_needed = 0; +PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; +PCRE2_SIZE *ovector; + +buff_offset = 0; +lengthleft = buff_length = *blength; +*blength = PCRE2_UNSET; + +/* Partial matching is not valid. */ + +if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0) + return PCRE2_ERROR_BADOPTION; + +/* If no match data block is provided, create one. */ + +if (match_data == NULL) + { + pcre2_general_context *gcontext = (mcontext == NULL)? + (pcre2_general_context *)code : + (pcre2_general_context *)mcontext; + match_data = pcre2_match_data_create_from_pattern(code, gcontext); + if (match_data == NULL) return PCRE2_ERROR_NOMEMORY; + match_data_created = TRUE; + } +ovector = pcre2_get_ovector_pointer(match_data); +ovector_count = pcre2_get_ovector_count(match_data); + +/* Find lengths of zero-terminated strings and the end of the replacement. */ + +if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); +if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement); +repend = replacement + rlength; + +/* Check UTF replacement string if necessary. */ + +#ifdef SUPPORT_UNICODE +if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) + { + rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar)); + if (rc != 0) + { + match_data->leftchar = 0; + goto EXIT; + } + } +#endif /* SUPPORT_UNICODE */ + +/* Save the substitute options and remove them from the match options. */ + +suboptions = options & SUBSTITUTE_OPTIONS; +options &= ~SUBSTITUTE_OPTIONS; + +/* Copy up to the start offset */ + +CHECKMEMCPY(subject, start_offset); + +/* Loop for global substituting. */ + +subs = 0; +do + { + PCRE2_SPTR ptrstack[PTR_STACK_SIZE]; + uint32_t ptrstackptr = 0; + + rc = pcre2_match(code, subject, length, start_offset, options|goptions, + match_data, mcontext); + +#ifdef SUPPORT_UNICODE + if (utf) options |= PCRE2_NO_UTF_CHECK; /* Only need to check once */ +#endif + + /* Any error other than no match returns the error code. No match when not + doing the special after-empty-match global rematch, or when at the end of the + subject, breaks the global loop. Otherwise, advance the starting point by one + character, copying it to the output, and try again. */ + + if (rc < 0) + { + PCRE2_SIZE save_start; + + if (rc != PCRE2_ERROR_NOMATCH) goto EXIT; + if (goptions == 0 || start_offset >= length) break; + + /* Advance by one code point. Then, if CRLF is a valid newline sequence and + we have advanced into the middle of it, advance one more code point. In + other words, do not start in the middle of CRLF, even if CR and LF on their + own are valid newlines. */ + + save_start = start_offset++; + if (subject[start_offset-1] == CHAR_CR && + code->newline_convention != PCRE2_NEWLINE_CR && + code->newline_convention != PCRE2_NEWLINE_LF && + start_offset < length && + subject[start_offset] == CHAR_LF) + start_offset++; + + /* Otherwise, in UTF mode, advance past any secondary code points. */ + + else if ((code->overall_options & PCRE2_UTF) != 0) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80) + start_offset++; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + while (start_offset < length && + (subject[start_offset] & 0xfc00) == 0xdc00) + start_offset++; +#endif + } + + /* Copy what we have advanced past, reset the special global options, and + continue to the next match. */ + + fraglength = start_offset - save_start; + CHECKMEMCPY(subject + save_start, fraglength); + goptions = 0; + continue; + } + + /* Handle a successful match. Matches that use \K to end before they start + are not supported. */ + + if (ovector[1] < ovector[0]) + { + rc = PCRE2_ERROR_BADSUBSPATTERN; + goto EXIT; + } + + /* Count substitutions with a paranoid check for integer overflow; surely no + real call to this function would ever hit this! */ + + if (subs == INT_MAX) + { + rc = PCRE2_ERROR_TOOMANYREPLACE; + goto EXIT; + } + subs++; + + /* Copy the text leading up to the match. */ + + if (rc == 0) rc = ovector_count; + fraglength = ovector[0] - start_offset; + CHECKMEMCPY(subject + start_offset, fraglength); + + /* Process the replacement string. Literal mode is set by \Q, but only in + extended mode when backslashes are being interpreted. In extended mode we + must handle nested substrings that are to be reprocessed. */ + + ptr = replacement; + for (;;) + { + uint32_t ch; + unsigned int chlen; + + /* If at the end of a nested substring, pop the stack. */ + + if (ptr >= repend) + { + if (ptrstackptr <= 0) break; /* End of replacement string */ + repend = ptrstack[--ptrstackptr]; + ptr = ptrstack[--ptrstackptr]; + continue; + } + + /* Handle the next character */ + + if (literal) + { + if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E) + { + literal = FALSE; + ptr += 2; + continue; + } + goto LOADLITERAL; + } + + /* Not in literal mode. */ + + if (*ptr == CHAR_DOLLAR_SIGN) + { + int group, n; + uint32_t special = 0; + BOOL inparens; + BOOL star; + PCRE2_SIZE sublength; + PCRE2_SPTR text1_start = NULL; + PCRE2_SPTR text1_end = NULL; + PCRE2_SPTR text2_start = NULL; + PCRE2_SPTR text2_end = NULL; + PCRE2_UCHAR next; + PCRE2_UCHAR name[33]; + + if (++ptr >= repend) goto BAD; + if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL; + + group = -1; + n = 0; + inparens = FALSE; + star = FALSE; + + if (next == CHAR_LEFT_CURLY_BRACKET) + { + if (++ptr >= repend) goto BAD; + next = *ptr; + inparens = TRUE; + } + + if (next == CHAR_ASTERISK) + { + if (++ptr >= repend) goto BAD; + next = *ptr; + star = TRUE; + } + + if (!star && next >= CHAR_0 && next <= CHAR_9) + { + group = next - CHAR_0; + while (++ptr < repend) + { + next = *ptr; + if (next < CHAR_0 || next > CHAR_9) break; + group = group * 10 + next - CHAR_0; + + /* A check for a number greater than the hightest captured group + is sufficient here; no need for a separate overflow check. If unknown + groups are to be treated as unset, just skip over any remaining + digits and carry on. */ + + if (group > code->top_bracket) + { + if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) + { + while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9); + break; + } + else + { + rc = PCRE2_ERROR_NOSUBSTRING; + goto PTREXIT; + } + } + } + } + else + { + const uint8_t *ctypes = code->tables + ctypes_offset; + while (MAX_255(next) && (ctypes[next] & ctype_word) != 0) + { + name[n++] = next; + if (n > 32) goto BAD; + if (++ptr >= repend) break; + next = *ptr; + } + if (n == 0) goto BAD; + name[n] = 0; + } + + /* In extended mode we recognize ${name:+set text:unset text} and + ${name:-default text}. */ + + if (inparens) + { + if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && + !star && ptr < repend - 2 && next == CHAR_COLON) + { + special = *(++ptr); + if (special != CHAR_PLUS && special != CHAR_MINUS) + { + rc = PCRE2_ERROR_BADSUBSTITUTION; + goto PTREXIT; + } + + text1_start = ++ptr; + rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS); + if (rc != 0) goto PTREXIT; + text1_end = ptr; + + if (special == CHAR_PLUS && *ptr == CHAR_COLON) + { + text2_start = ++ptr; + rc = find_text_end(code, &ptr, repend, TRUE); + if (rc != 0) goto PTREXIT; + text2_end = ptr; + } + } + + else + { + if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET) + { + rc = PCRE2_ERROR_REPMISSINGBRACE; + goto PTREXIT; + } + } + + ptr++; + } + + /* Have found a syntactically correct group number or name, or *name. + Only *MARK is currently recognized. */ + + if (star) + { + if (PRIV(strcmp_c8)(name, STRING_MARK) == 0) + { + PCRE2_SPTR mark = pcre2_get_mark(match_data); + if (mark != NULL) + { + PCRE2_SPTR mark_start = mark; + while (*mark != 0) mark++; + fraglength = mark - mark_start; + CHECKMEMCPY(mark_start, fraglength); + } + } + else goto BAD; + } + + /* Substitute the contents of a group. We don't use substring_copy + functions any more, in order to support case forcing. */ + + else + { + PCRE2_SPTR subptr, subptrend; + + /* Find a number for a named group. In case there are duplicate names, + search for the first one that is set. If the name is not found when + PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a + non-existent group. */ + + if (group < 0) + { + PCRE2_SPTR first, last, entry; + rc = pcre2_substring_nametable_scan(code, name, &first, &last); + if (rc == PCRE2_ERROR_NOSUBSTRING && + (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) + { + group = code->top_bracket + 1; + } + else + { + if (rc < 0) goto PTREXIT; + for (entry = first; entry <= last; entry += rc) + { + uint32_t ng = GET2(entry, 0); + if (ng < ovector_count) + { + if (group < 0) group = ng; /* First in ovector */ + if (ovector[ng*2] != PCRE2_UNSET) + { + group = ng; /* First that is set */ + break; + } + } + } + + /* If group is still negative, it means we did not find a group + that is in the ovector. Just set the first group. */ + + if (group < 0) group = GET2(first, 0); + } + } + + /* We now have a group that is identified by number. Find the length of + the captured string. If a group in a non-special substitution is unset + when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */ + + rc = pcre2_substring_length_bynumber(match_data, group, &sublength); + if (rc < 0) + { + if (rc == PCRE2_ERROR_NOSUBSTRING && + (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) + { + rc = PCRE2_ERROR_UNSET; + } + if (rc != PCRE2_ERROR_UNSET) goto PTREXIT; /* Non-unset errors */ + if (special == 0) /* Plain substitution */ + { + if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue; + goto PTREXIT; /* Else error */ + } + } + + /* If special is '+' we have a 'set' and possibly an 'unset' text, + both of which are reprocessed when used. If special is '-' we have a + default text for when the group is unset; it must be reprocessed. */ + + if (special != 0) + { + if (special == CHAR_MINUS) + { + if (rc == 0) goto LITERAL_SUBSTITUTE; + text2_start = text1_start; + text2_end = text1_end; + } + + if (ptrstackptr >= PTR_STACK_SIZE) goto BAD; + ptrstack[ptrstackptr++] = ptr; + ptrstack[ptrstackptr++] = repend; + + if (rc == 0) + { + ptr = text1_start; + repend = text1_end; + } + else + { + ptr = text2_start; + repend = text2_end; + } + continue; + } + + /* Otherwise we have a literal substitution of a group's contents. */ + + LITERAL_SUBSTITUTE: + subptr = subject + ovector[group*2]; + subptrend = subject + ovector[group*2 + 1]; + + /* Substitute a literal string, possibly forcing alphabetic case. */ + + while (subptr < subptrend) + { + GETCHARINCTEST(ch, subptr); + if (forcecase != 0) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + uint32_t type = UCD_CHARTYPE(ch); + if (PRIV(ucp_gentype)[type] == ucp_L && + type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) + ch = UCD_OTHERCASE(ch); + } + else +#endif + { + if (((code->tables + cbits_offset + + ((forcecase > 0)? cbit_upper:cbit_lower) + )[ch/8] & (1 << (ch%8))) == 0) + ch = (code->tables + fcc_offset)[ch]; + } + forcecase = forcecasereset; + } + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + CHECKMEMCPY(temp, chlen); + } + } + } + + /* Handle an escape sequence in extended mode. We can use check_escape() + to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but + the case-forcing escapes are not supported in pcre2_compile() so must be + recognized here. */ + + else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && + *ptr == CHAR_BACKSLASH) + { + int errorcode = 0; + + if (ptr < repend - 1) switch (ptr[1]) + { + case CHAR_L: + forcecase = forcecasereset = -1; + ptr += 2; + continue; + + case CHAR_l: + forcecase = -1; + forcecasereset = 0; + ptr += 2; + continue; + + case CHAR_U: + forcecase = forcecasereset = 1; + ptr += 2; + continue; + + case CHAR_u: + forcecase = 1; + forcecasereset = 0; + ptr += 2; + continue; + + default: + break; + } + + rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode, + code->overall_options, FALSE, NULL); + if (errorcode != 0) goto BADESCAPE; + ptr++; + + switch(rc) + { + case ESC_E: + forcecase = forcecasereset = 0; + continue; + + case ESC_Q: + literal = TRUE; + continue; + + case 0: /* Data character */ + goto LITERAL; + + default: + goto BADESCAPE; + } + } + + /* Handle a literal code unit */ + + else + { + LOADLITERAL: + GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */ + + LITERAL: + if (forcecase != 0) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + uint32_t type = UCD_CHARTYPE(ch); + if (PRIV(ucp_gentype)[type] == ucp_L && + type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) + ch = UCD_OTHERCASE(ch); + } + else +#endif + { + if (((code->tables + cbits_offset + + ((forcecase > 0)? cbit_upper:cbit_lower) + )[ch/8] & (1 << (ch%8))) == 0) + ch = (code->tables + fcc_offset)[ch]; + } + forcecase = forcecasereset; + } + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + CHECKMEMCPY(temp, chlen); + } /* End handling a literal code unit */ + } /* End of loop for scanning the replacement. */ + + /* The replacement has been copied to the output. Update the start offset to + point to the rest of the subject string. If we matched an empty string, + do the magic for global matches. */ + + start_offset = ovector[1]; + goptions = (ovector[0] != ovector[1])? 0 : + PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART; + } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */ + +/* Copy the rest of the subject. */ + +fraglength = length - start_offset; +CHECKMEMCPY(subject + start_offset, fraglength); +temp[0] = 0; +CHECKMEMCPY(temp , 1); + +/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set, +and matching has carried on after a full buffer, in order to compute the length +needed. Otherwise, an overflow generates an immediate error return. */ + +if (overflowed) + { + rc = PCRE2_ERROR_NOMEMORY; + *blength = buff_length + extra_needed; + } + +/* After a successful execution, return the number of substitutions and set the +length of buffer used, excluding the trailing zero. */ + +else + { + rc = subs; + *blength = buff_offset - 1; + } + +EXIT: +if (match_data_created) pcre2_match_data_free(match_data); + else match_data->rc = rc; +return rc; + +NOROOM: +rc = PCRE2_ERROR_NOMEMORY; +goto EXIT; + +BAD: +rc = PCRE2_ERROR_BADREPLACEMENT; +goto PTREXIT; + +BADESCAPE: +rc = PCRE2_ERROR_BADREPESCAPE; + +PTREXIT: +*blength = (PCRE2_SIZE)(ptr - replacement); +goto EXIT; +} + +/* End of pcre2_substitute.c */ diff --git a/pcre2/src/pcre2_substring.c b/pcre2/src/pcre2_substring.c new file mode 100644 index 000000000..58b504d5c --- /dev/null +++ b/pcre2/src/pcre2_substring.c @@ -0,0 +1,536 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + + +/************************************************* +* Copy named captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer, +identifying it by name. If the regex permits duplicate names, the first +substring that is set is chosen. + +Arguments: + match_data points to the match data + stringname the name of the required substring + buffer where to put the substring + sizeptr the size of the buffer, updated to the size of the substring + +Returns: if successful: zero + if not successful, a negative error code: + (1) an error from nametable_scan() + (2) an error from copy_bynumber() + (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector + (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname, + PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr) +{ +PCRE2_SPTR first, last, entry; +int failrc, entrysize; +if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) + return PCRE2_ERROR_DFA_UFUNC; +entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, + &first, &last); +if (entrysize < 0) return entrysize; +failrc = PCRE2_ERROR_UNAVAILABLE; +for (entry = first; entry <= last; entry += entrysize) + { + uint32_t n = GET2(entry, 0); + if (n < match_data->oveccount) + { + if (match_data->ovector[n*2] != PCRE2_UNSET) + return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr); + failrc = PCRE2_ERROR_UNSET; + } + } +return failrc; +} + + + +/************************************************* +* Copy numbered captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer, +identifying it by number. + +Arguments: + match_data points to the match data + stringnumber the number of the required substring + buffer where to put the substring + sizeptr the size of the buffer, updated to the size of the substring + +Returns: if successful: 0 + if not successful, a negative error code: + PCRE2_ERROR_NOMEMORY: buffer too small + PCRE2_ERROR_NOSUBSTRING: no such substring + PCRE2_ERROR_UNAVAILABLE: ovector too small + PCRE2_ERROR_UNSET: substring is not set +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_copy_bynumber(pcre2_match_data *match_data, + uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr) +{ +int rc; +PCRE2_SIZE size; +rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size); +if (rc < 0) return rc; +if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY; +memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2], + CU2BYTES(size)); +buffer[size] = 0; +*sizeptr = size; +return 0; +} + + + +/************************************************* +* Extract named captured string * +*************************************************/ + +/* This function copies a single captured substring, identified by name, into +new memory. If the regex permits duplicate names, the first substring that is +set is chosen. + +Arguments: + match_data pointer to match_data + stringname the name of the required substring + stringptr where to put the pointer to the new memory + sizeptr where to put the length of the substring + +Returns: if successful: zero + if not successful, a negative value: + (1) an error from nametable_scan() + (2) an error from get_bynumber() + (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector + (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_get_byname(pcre2_match_data *match_data, + PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr) +{ +PCRE2_SPTR first, last, entry; +int failrc, entrysize; +if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) + return PCRE2_ERROR_DFA_UFUNC; +entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, + &first, &last); +if (entrysize < 0) return entrysize; +failrc = PCRE2_ERROR_UNAVAILABLE; +for (entry = first; entry <= last; entry += entrysize) + { + uint32_t n = GET2(entry, 0); + if (n < match_data->oveccount) + { + if (match_data->ovector[n*2] != PCRE2_UNSET) + return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr); + failrc = PCRE2_ERROR_UNSET; + } + } +return failrc; +} + + + +/************************************************* +* Extract captured string to new memory * +*************************************************/ + +/* This function copies a single captured substring into a piece of new +memory. + +Arguments: + match_data points to match data + stringnumber the number of the required substring + stringptr where to put a pointer to the new memory + sizeptr where to put the size of the substring + +Returns: if successful: 0 + if not successful, a negative error code: + PCRE2_ERROR_NOMEMORY: failed to get memory + PCRE2_ERROR_NOSUBSTRING: no such substring + PCRE2_ERROR_UNAVAILABLE: ovector too small + PCRE2_ERROR_UNSET: substring is not set +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_get_bynumber(pcre2_match_data *match_data, + uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr) +{ +int rc; +PCRE2_SIZE size; +PCRE2_UCHAR *yield; +rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size); +if (rc < 0) return rc; +yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) + + (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data); +if (yield == NULL) return PCRE2_ERROR_NOMEMORY; +yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl)); +memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2], + CU2BYTES(size)); +yield[size] = 0; +*stringptr = yield; +*sizeptr = size; +return 0; +} + + + +/************************************************* +* Free memory obtained by get_substring * +*************************************************/ + +/* +Argument: the result of a previous pcre2_substring_get_byxxx() +Returns: nothing +*/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_substring_free(PCRE2_UCHAR *string) +{ +pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl)); +memctl->free(memctl, memctl->memory_data); +} + + + +/************************************************* +* Get length of a named substring * +*************************************************/ + +/* This function returns the length of a named captured substring. If the regex +permits duplicate names, the first substring that is set is chosen. + +Arguments: + match_data pointer to match data + stringname the name of the required substring + sizeptr where to put the length + +Returns: 0 if successful, else a negative error number +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_length_byname(pcre2_match_data *match_data, + PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr) +{ +PCRE2_SPTR first, last, entry; +int failrc, entrysize; +if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) + return PCRE2_ERROR_DFA_UFUNC; +entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, + &first, &last); +if (entrysize < 0) return entrysize; +failrc = PCRE2_ERROR_UNAVAILABLE; +for (entry = first; entry <= last; entry += entrysize) + { + uint32_t n = GET2(entry, 0); + if (n < match_data->oveccount) + { + if (match_data->ovector[n*2] != PCRE2_UNSET) + return pcre2_substring_length_bynumber(match_data, n, sizeptr); + failrc = PCRE2_ERROR_UNSET; + } + } +return failrc; +} + + + +/************************************************* +* Get length of a numbered substring * +*************************************************/ + +/* This function returns the length of a captured substring. If the start is +beyond the end (which can happen when \K is used in an assertion), it sets the +length to zero. + +Arguments: + match_data pointer to match data + stringnumber the number of the required substring + sizeptr where to put the length, if not NULL + +Returns: if successful: 0 + if not successful, a negative error code: + PCRE2_ERROR_NOSUBSTRING: no such substring + PCRE2_ERROR_UNAVAILABLE: ovector is too small + PCRE2_ERROR_UNSET: substring is not set +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_length_bynumber(pcre2_match_data *match_data, + uint32_t stringnumber, PCRE2_SIZE *sizeptr) +{ +PCRE2_SIZE left, right; +int count = match_data->rc; +if (count == PCRE2_ERROR_PARTIAL) + { + if (stringnumber > 0) return PCRE2_ERROR_PARTIAL; + count = 0; + } +else if (count < 0) return count; /* Match failed */ + +if (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER) + { + if (stringnumber > match_data->code->top_bracket) + return PCRE2_ERROR_NOSUBSTRING; + if (stringnumber >= match_data->oveccount) + return PCRE2_ERROR_UNAVAILABLE; + if (match_data->ovector[stringnumber*2] == PCRE2_UNSET) + return PCRE2_ERROR_UNSET; + } +else /* Matched using pcre2_dfa_match() */ + { + if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE; + if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET; + } + +left = match_data->ovector[stringnumber*2]; +right = match_data->ovector[stringnumber*2+1]; +if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left; +return 0; +} + + + +/************************************************* +* Extract all captured strings to new memory * +*************************************************/ + +/* This function gets one chunk of memory and builds a list of pointers and all +the captured substrings in it. A NULL pointer is put on the end of the list. +The substrings are zero-terminated, but also, if the final argument is +non-NULL, a list of lengths is also returned. This allows binary data to be +handled. + +Arguments: + match_data points to the match data + listptr set to point to the list of pointers + lengthsptr set to point to the list of lengths (may be NULL) + +Returns: if successful: 0 + if not successful, a negative error code: + PCRE2_ERROR_NOMEMORY: failed to get memory, + or a match failure code +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr, + PCRE2_SIZE **lengthsptr) +{ +int i, count, count2; +PCRE2_SIZE size; +PCRE2_SIZE *lensp; +pcre2_memctl *memp; +PCRE2_UCHAR **listp; +PCRE2_UCHAR *sp; +PCRE2_SIZE *ovector; + +if ((count = match_data->rc) < 0) return count; /* Match failed */ +if (count == 0) count = match_data->oveccount; /* Ovector too small */ + +count2 = 2*count; +ovector = match_data->ovector; +size = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *); /* For final NULL */ +if (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count; /* For lengths */ + +for (i = 0; i < count2; i += 2) + { + size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1); + if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]); + } + +memp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data); +if (memp == NULL) return PCRE2_ERROR_NOMEMORY; + +*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl)); +lensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1)); + +if (lengthsptr == NULL) + { + sp = (PCRE2_UCHAR *)lensp; + lensp = NULL; + } +else + { + *lengthsptr = lensp; + sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count); + } + +for (i = 0; i < count2; i += 2) + { + size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0; + memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size)); + *listp++ = sp; + if (lensp != NULL) *lensp++ = size; + sp += size; + *sp++ = 0; + } + +*listp = NULL; +return 0; +} + + + +/************************************************* +* Free memory obtained by substring_list_get * +*************************************************/ + +/* +Argument: the result of a previous pcre2_substring_list_get() +Returns: nothing +*/ + +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_substring_list_free(PCRE2_SPTR *list) +{ +pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl)); +memctl->free(memctl, memctl->memory_data); +} + + + +/************************************************* +* Find (multiple) entries for named string * +*************************************************/ + +/* This function scans the nametable for a given name, using binary chop. It +returns either two pointers to the entries in the table, or, if no pointers are +given, the number of a unique group with the given name. If duplicate names are +permitted, and the name is not unique, an error is generated. + +Arguments: + code the compiled regex + stringname the name whose entries required + firstptr where to put the pointer to the first entry + lastptr where to put the pointer to the last entry + +Returns: PCRE2_ERROR_NOSUBSTRING if the name is not found + otherwise, if firstptr and lastptr are NULL: + a group number for a unique substring + else PCRE2_ERROR_NOUNIQUESUBSTRING + otherwise: + the length of each entry, having set firstptr and lastptr +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname, + PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr) +{ +uint16_t bot = 0; +uint16_t top = code->name_count; +uint16_t entrysize = code->name_entry_size; +PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code)); + +while (top > bot) + { + uint16_t mid = (top + bot) / 2; + PCRE2_SPTR entry = nametable + entrysize*mid; + int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE); + if (c == 0) + { + PCRE2_SPTR first; + PCRE2_SPTR last; + PCRE2_SPTR lastentry; + lastentry = nametable + entrysize * (code->name_count - 1); + first = last = entry; + while (first > nametable) + { + if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break; + first -= entrysize; + } + while (last < lastentry) + { + if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break; + last += entrysize; + } + if (firstptr == NULL) return (first == last)? + (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING; + *firstptr = first; + *lastptr = last; + return entrysize; + } + if (c > 0) bot = mid + 1; else top = mid; + } + +return PCRE2_ERROR_NOSUBSTRING; +} + + +/************************************************* +* Find number for named string * +*************************************************/ + +/* This function is a convenience wrapper for pcre2_substring_nametable_scan() +when it is known that names are unique. If there are duplicate names, it is not +defined which number is returned. + +Arguments: + code the compiled regex + stringname the name whose number is required + +Returns: the number of the named parenthesis, or a negative number + PCRE2_ERROR_NOSUBSTRING if not found + PCRE2_ERROR_NOUNIQUESUBSTRING if not unique +*/ + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_substring_number_from_name(const pcre2_code *code, + PCRE2_SPTR stringname) +{ +return pcre2_substring_nametable_scan(code, stringname, NULL, NULL); +} + +/* End of pcre2_substring.c */ diff --git a/pcre2/src/pcre2_tables.c b/pcre2/src/pcre2_tables.c new file mode 100644 index 000000000..b945ed7a7 --- /dev/null +++ b/pcre2/src/pcre2_tables.c @@ -0,0 +1,765 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains some fixed tables that are used by more than one of the +PCRE code modules. The tables are also #included by the pcre2test program, +which uses macros to change their names from _pcre2_xxx to xxxx, thereby +avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is +defined. */ + +#ifndef PCRE2_PCRE2TEST /* We're compiling the library */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "pcre2_internal.h" +#endif /* PCRE2_PCRE2TEST */ + + +/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that +the definition is next to the definition of the opcodes in pcre2_internal.h. +This is mode-dependent, so is skipped when this file is included by pcre2test. */ + +#ifndef PCRE2_PCRE2TEST +const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS }; +#endif + +/* Tables of horizontal and vertical whitespace characters, suitable for +adding to classes. */ + +const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST }; +const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST }; + +/* These tables are the pairs of delimiters that are valid for callout string +arguments. For each starting delimiter there must be a matching ending +delimiter, which in fact is different only for bracket-like delimiters. */ + +const uint32_t PRIV(callout_start_delims)[] = { + CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, + CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, + CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 }; + +const uint32_t PRIV(callout_end_delims[]) = { + CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, + CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, + CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 }; + + +/************************************************* +* Tables for UTF-8 support * +*************************************************/ + +/* These tables are required by pcre2test in 16- or 32-bit mode, as well +as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for +handling wide characters. */ + +#if defined PCRE2_PCRE2TEST || \ + (defined SUPPORT_UNICODE && \ + defined PCRE2_CODE_UNIT_WIDTH && \ + PCRE2_CODE_UNIT_WIDTH == 8) + +/* These are the breakpoints for different numbers of bytes in a UTF-8 +character. */ + +const int PRIV(utf8_table1)[] = + { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; + +const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); + +/* These are the indicator bits and the mask for the data bits to set in the +first byte of a character, indexed by the number of additional bytes. */ + +const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; +const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +/* Table of the number of extra bytes, indexed by the first byte masked with +0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ + +const uint8_t PRIV(utf8_table4)[] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; + +#endif /* UTF-8 support needed */ + + +#ifdef SUPPORT_UNICODE + +/* Table to translate from particular type value to the general value. */ + +const uint32_t PRIV(ucp_gentype)[] = { + ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ + ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ + ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ + ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ + ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ + ucp_P, ucp_P, /* Ps, Po */ + ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ + ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ +}; + +/* This table encodes the rules for finding the end of an extended grapheme +cluster. Every code point has a grapheme break property which is one of the +ucp_gbXX values defined in pcre2_ucp.h. The 2-dimensional table is indexed by +the properties of two adjacent code points. The left property selects a word +from the table, and the right property selects a bit from that word like this: + + PRIV(ucp_gbtable)[left-property] & (1 << right-property) + +The value is non-zero if a grapheme break is NOT permitted between the relevant +two code points. The breaking rules are as follows: + +1. Break at the start and end of text (pretty obviously). + +2. Do not break between a CR and LF; otherwise, break before and after + controls. + +3. Do not break Hangul syllable sequences, the rules for which are: + + L may be followed by L, V, LV or LVT + LV or V may be followed by V or T + LVT or T may be followed by T + +4. Do not break before extending characters. + +The next two rules are only for extended grapheme clusters (but that's what we +are implementing). + +5. Do not break before SpacingMarks. + +6. Do not break after Prepend characters. + +7. Otherwise, break everywhere. +*/ + +const uint32_t PRIV(ucp_gbtable)[] = { + (1< 0x10ffff is not permitted +PCRE2_ERROR_UTF8_ERR14 3-byte character with value 0xd800-0xdfff is not permitted +PCRE2_ERROR_UTF8_ERR15 Overlong 2-byte sequence +PCRE2_ERROR_UTF8_ERR16 Overlong 3-byte sequence +PCRE2_ERROR_UTF8_ERR17 Overlong 4-byte sequence +PCRE2_ERROR_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) +PCRE2_ERROR_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) +PCRE2_ERROR_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) +PCRE2_ERROR_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff +*/ + +for (p = string; length > 0; p++) + { + register uint32_t ab, d; + + c = *p; + length--; + + if (c < 128) continue; /* ASCII character */ + + if (c < 0xc0) /* Isolated 10xx xxxx byte */ + { + *erroroffset = (int)(p - string); + return PCRE2_ERROR_UTF8_ERR20; + } + + if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */ + { + *erroroffset = (int)(p - string); + return PCRE2_ERROR_UTF8_ERR21; + } + + ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes (1-5) */ + if (length < ab) /* Missing bytes */ + { + *erroroffset = (int)(p - string); + switch(ab - length) + { + case 1: return PCRE2_ERROR_UTF8_ERR1; + case 2: return PCRE2_ERROR_UTF8_ERR2; + case 3: return PCRE2_ERROR_UTF8_ERR3; + case 4: return PCRE2_ERROR_UTF8_ERR4; + case 5: return PCRE2_ERROR_UTF8_ERR5; + } + } + length -= ab; /* Length remaining */ + + /* Check top bits in the second byte */ + + if (((d = *(++p)) & 0xc0) != 0x80) + { + *erroroffset = (int)(p - string) - 1; + return PCRE2_ERROR_UTF8_ERR6; + } + + /* For each length, check that the remaining bytes start with the 0x80 bit + set and not the 0x40 bit. Then check for an overlong sequence, and for the + excluded range 0xd800 to 0xdfff. */ + + switch (ab) + { + /* 2-byte character. No further bytes to check for 0x80. Check first byte + for for xx00 000x (overlong sequence). */ + + case 1: if ((c & 0x3e) == 0) + { + *erroroffset = (int)(p - string) - 1; + return PCRE2_ERROR_UTF8_ERR15; + } + break; + + /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes + for 1110 0000, xx0x xxxx (overlong sequence) or + 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */ + + case 2: + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR7; + } + if (c == 0xe0 && (d & 0x20) == 0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR16; + } + if (c == 0xed && d >= 0xa0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR14; + } + break; + + /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 + bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a + character greater than 0x0010ffff (f4 8f bf bf) */ + + case 3: + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE2_ERROR_UTF8_ERR8; + } + if (c == 0xf0 && (d & 0x30) == 0) + { + *erroroffset = (int)(p - string) - 3; + return PCRE2_ERROR_UTF8_ERR17; + } + if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) + { + *erroroffset = (int)(p - string) - 3; + return PCRE2_ERROR_UTF8_ERR13; + } + break; + + /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be + rejected by the length test below. However, we do the appropriate tests + here so that overlong sequences get diagnosed, and also in case there is + ever an option for handling these larger code points. */ + + /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for + 1111 1000, xx00 0xxx */ + + case 4: + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE2_ERROR_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE2_ERROR_UTF8_ERR9; + } + if (c == 0xf8 && (d & 0x38) == 0) + { + *erroroffset = (int)(p - string) - 4; + return PCRE2_ERROR_UTF8_ERR18; + } + break; + + /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for + 1111 1100, xx00 00xx. */ + + case 5: + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE2_ERROR_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE2_ERROR_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE2_ERROR_UTF8_ERR9; + } + if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ + { + *erroroffset = (int)(p - string) - 5; + return PCRE2_ERROR_UTF8_ERR10; + } + if (c == 0xfc && (d & 0x3c) == 0) + { + *erroroffset = (int)(p - string) - 5; + return PCRE2_ERROR_UTF8_ERR19; + } + break; + } + + /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are + excluded by RFC 3629. The pointer p is currently at the last byte of the + character. */ + + if (ab > 3) + { + *erroroffset = (int)(p - string) - ab; + return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12; + } + } +return 0; + + +/* ----------------- Check a UTF-16 string ----------------- */ + +#elif PCRE2_CODE_UNIT_WIDTH == 16 + +/* There's not so much work, nor so many errors, for UTF-16. +PCRE2_ERROR_UTF16_ERR1 Missing low surrogate at the end of the string +PCRE2_ERROR_UTF16_ERR2 Invalid low surrogate +PCRE2_ERROR_UTF16_ERR3 Isolated low surrogate +*/ + +for (p = string; length > 0; p++) + { + c = *p; + length--; + + if ((c & 0xf800) != 0xd800) + { + /* Normal UTF-16 code point. Neither high nor low surrogate. */ + } + else if ((c & 0x0400) == 0) + { + /* High surrogate. Must be a followed by a low surrogate. */ + if (length == 0) + { + *erroroffset = p - string; + return PCRE2_ERROR_UTF16_ERR1; + } + p++; + length--; + if ((*p & 0xfc00) != 0xdc00) + { + *erroroffset = p - string; + return PCRE2_ERROR_UTF16_ERR2; + } + } + else + { + /* Isolated low surrogate. Always an error. */ + *erroroffset = p - string; + return PCRE2_ERROR_UTF16_ERR3; + } + } +return 0; + + + +/* ----------------- Check a UTF-32 string ----------------- */ + +#else + +/* There is very little to do for a UTF-32 string. +PCRE2_ERROR_UTF32_ERR1 Surrogate character +PCRE2_ERROR_UTF32_ERR2 Character > 0x10ffff +*/ + +for (p = string; length > 0; length--, p++) + { + c = *p; + if ((c & 0xfffff800u) != 0xd800u) + { + /* Normal UTF-32 code point. Neither high nor low surrogate. */ + if (c > 0x10ffffu) + { + *erroroffset = p - string; + return PCRE2_ERROR_UTF32_ERR2; + } + } + else + { + /* A surrogate */ + *erroroffset = p - string; + return PCRE2_ERROR_UTF32_ERR1; + } + } +return 0; +#endif /* CODE_UNIT_WIDTH */ +} +#endif /* SUPPORT_UNICODE */ + +/* End of pcre2_valid_utf.c */ diff --git a/pcre2/src/pcre2_xclass.c b/pcre2/src/pcre2_xclass.c new file mode 100644 index 000000000..407d3f5b8 --- /dev/null +++ b/pcre2/src/pcre2_xclass.c @@ -0,0 +1,271 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains an internal function that is used to match an extended +class. It is used by pcre2_auto_possessify() and by both pcre2_match() and +pcre2_def_match(). */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "pcre2_internal.h" + +/************************************************* +* Match character against an XCLASS * +*************************************************/ + +/* This function is called to match a character against an extended class that +might contain codepoints above 255 and/or Unicode properties. + +Arguments: + c the character + data points to the flag code unit of the XCLASS data + utf TRUE if in UTF mode + +Returns: TRUE if character matches, else FALSE +*/ + +BOOL +PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf) +{ +PCRE2_UCHAR t; +BOOL negated = (*data & XCL_NOT) != 0; + +#if PCRE2_CODE_UNIT_WIDTH == 8 +/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ +utf = TRUE; +#endif + +/* Code points < 256 are matched against a bitmap, if one is present. If not, +we still carry on, because there may be ranges that start below 256 in the +additional data. */ + +if (c < 256) + { + if ((*data & XCL_HASPROP) == 0) + { + if ((*data & XCL_MAP) == 0) return negated; + return (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0; + } + if ((*data & XCL_MAP) != 0 && + (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0) + return !negated; /* char found */ + } + +/* First skip the bit map if present. Then match against the list of Unicode +properties or large chars or ranges that end with a large char. We won't ever +encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */ + +if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR); + +while ((t = *data++) != XCL_END) + { + uint32_t x, y; + if (t == XCL_SINGLE) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + } + else +#endif + x = *data++; + if (c == x) return !negated; + } + else if (t == XCL_RANGE) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + GETCHARINC(y, data); /* macro generates multiple statements */ + } + else +#endif + { + x = *data++; + y = *data++; + } + if (c >= x && c <= y) return !negated; + } + +#ifdef SUPPORT_UNICODE + else /* XCL_PROP & XCL_NOTPROP */ + { + const ucd_record *prop = GET_UCD(c); + BOOL isprop = t == XCL_PROP; + + switch(*data) + { + case PT_ANY: + if (isprop) return !negated; + break; + + case PT_LAMP: + if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == isprop) return !negated; + break; + + case PT_GC: + if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) + return !negated; + break; + + case PT_PC: + if ((data[1] == prop->chartype) == isprop) return !negated; + break; + + case PT_SC: + if ((data[1] == prop->script) == isprop) return !negated; + break; + + case PT_ALNUM: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop) + return !negated; + break; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (isprop) return !negated; + break; + + default: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) + return !negated; + break; + } + break; + + case PT_WORD: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) + == isprop) + return !negated; + break; + + case PT_UCNC: + if (c < 0xa0) + { + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT) == isprop) + return !negated; + } + else + { + if ((c < 0xd800 || c > 0xdfff) == isprop) + return !negated; + } + break; + + /* The following three properties can occur only in an XCLASS, as there + is no \p or \P coding for them. */ + + /* Graphic character. Implement this as not Z (space or separator) and + not C (other), except for Cf (format) with a few exceptions. This seems + to be what Perl does. The exceptional characters are: + + U+061C Arabic Letter Mark + U+180E Mongolian Vowel Separator + U+2066 - U+2069 Various "isolate"s + */ + + case PT_PXGRAPH: + if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z && + (PRIV(ucp_gentype)[prop->chartype] != ucp_C || + (prop->chartype == ucp_Cf && + c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) + )) == isprop) + return !negated; + break; + + /* Printable character: same as graphic, with the addition of Zs, i.e. + not Zl and not Zp, and U+180E. */ + + case PT_PXPRINT: + if ((prop->chartype != ucp_Zl && + prop->chartype != ucp_Zp && + (PRIV(ucp_gentype)[prop->chartype] != ucp_C || + (prop->chartype == ucp_Cf && + c != 0x061c && (c < 0x2066 || c > 0x2069)) + )) == isprop) + return !negated; + break; + + /* Punctuation: all Unicode punctuation, plus ASCII characters that + Unicode treats as symbols rather than punctuation, for Perl + compatibility (these are $+<=>^`|~). */ + + case PT_PXPUNCT: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || + (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) + return !negated; + break; + + /* This should never occur, but compilers may mutter if there is no + default. */ + + default: + return FALSE; + } + + data += 2; + } +#else + (void)utf; /* Avoid compiler warning */ +#endif /* SUPPORT_UNICODE */ + } + +return negated; /* char did not match */ +} + +/* End of pcre2_xclass.c */ diff --git a/pcre2/src/pcre2demo.c b/pcre2/src/pcre2demo.c new file mode 100644 index 000000000..ec51cf11c --- /dev/null +++ b/pcre2/src/pcre2demo.c @@ -0,0 +1,423 @@ +/************************************************* +* PCRE2 DEMONSTRATION PROGRAM * +*************************************************/ + +/* This is a demonstration program to illustrate a straightforward way of +calling the PCRE2 regular expression library from a C program. See the +pcre2sample documentation for a short discussion ("man pcre2sample" if you have +the PCRE2 man pages installed). PCRE2 is a revised API for the library, and is +incompatible with the original PCRE API. + +There are actually three libraries, each supporting a different code unit +width. This demonstration program uses the 8-bit library. + +In Unix-like environments, if PCRE2 is installed in your standard system +libraries, you should be able to compile this program using this command: + +gcc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo + +If PCRE2 is not installed in a standard place, it is likely to be installed +with support for the pkg-config mechanism. If you have pkg-config, you can +compile this program using this command: + +gcc -Wall pcre2demo.c `pkg-config --cflags --libs libpcre2-8` -o pcre2demo + +If you do not have pkg-config, you may have to use this: + +gcc -Wall pcre2demo.c -I/usr/local/include -L/usr/local/lib \ + -R/usr/local/lib -lpcre2-8 -o pcre2demo + +Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and +library files for PCRE2 are installed on your system. Only some operating +systems (Solaris is one) use the -R option. + +Building under Windows: + +If you want to statically link this program against a non-dll .a file, you must +define PCRE2_STATIC before including pcre2.h, so in this environment, uncomment +the following line. */ + +/* #define PCRE2_STATIC */ + +/* This macro must be defined before including pcre2.h. For a program that uses +only one code unit width, it makes it possible to use generic function names +such as pcre2_compile(). */ + +#define PCRE2_CODE_UNIT_WIDTH 8 + +#include +#include +#include + + +/************************************************************************** +* Here is the program. The API includes the concept of "contexts" for * +* setting up unusual interface requirements for compiling and matching, * +* such as custom memory managers and non-standard newline definitions. * +* This program does not do any of this, so it makes no use of contexts, * +* always passing NULL where a context could be given. * +**************************************************************************/ + +int main(int argc, char **argv) +{ +pcre2_code *re; +PCRE2_SPTR pattern; /* PCRE2_SPTR is a pointer to unsigned code units of */ +PCRE2_SPTR subject; /* the appropriate width (8, 16, or 32 bits). */ +PCRE2_SPTR name_table; + +int crlf_is_newline; +int errornumber; +int find_all; +int i; +int namecount; +int name_entry_size; +int rc; +int utf8; + +uint32_t option_bits; +uint32_t newline; + +PCRE2_SIZE erroroffset; +PCRE2_SIZE *ovector; + +size_t subject_length; +pcre2_match_data *match_data; + + + +/************************************************************************** +* First, sort out the command line. There is only one possible option at * +* the moment, "-g" to request repeated matching to find all occurrences, * +* like Perl's /g option. We set the variable find_all to a non-zero value * +* if the -g option is present. Apart from that, there must be exactly two * +* arguments. * +**************************************************************************/ + +find_all = 0; +for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-g") == 0) find_all = 1; + else break; + } + +/* After the options, we require exactly two arguments, which are the pattern, +and the subject string. */ + +if (argc - i != 2) + { + printf("Two arguments required: a regex and a subject string\n"); + return 1; + } + +/* As pattern and subject are char arguments, they can be straightforwardly +cast to PCRE2_SPTR as we are working in 8-bit code units. */ + +pattern = (PCRE2_SPTR)argv[i]; +subject = (PCRE2_SPTR)argv[i+1]; +subject_length = strlen((char *)subject); + + +/************************************************************************* +* Now we are going to compile the regular expression pattern, and handle * +* any errors that are detected. * +*************************************************************************/ + +re = pcre2_compile( + pattern, /* the pattern */ + PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */ + 0, /* default options */ + &errornumber, /* for error number */ + &erroroffset, /* for error offset */ + NULL); /* use default compile context */ + +/* Compilation failed: print the error message and exit. */ + +if (re == NULL) + { + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message(errornumber, buffer, sizeof(buffer)); + printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, + buffer); + return 1; + } + + +/************************************************************************* +* If the compilation succeeded, we call PCRE again, in order to do a * +* pattern match against the subject string. This does just ONE match. If * +* further matching is needed, it will be done below. Before running the * +* match we must set up a match_data block for holding the result. * +*************************************************************************/ + +/* Using this function ensures that the block is exactly the right size for +the number of capturing parentheses in the pattern. */ + +match_data = pcre2_match_data_create_from_pattern(re, NULL); + +rc = pcre2_match( + re, /* the compiled pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + match_data, /* block for storing the result */ + NULL); /* use default match context */ + +/* Matching failed: handle error cases */ + +if (rc < 0) + { + switch(rc) + { + case PCRE2_ERROR_NOMATCH: printf("No match\n"); break; + /* + Handle other special cases if you like + */ + default: printf("Matching error %d\n", rc); break; + } + pcre2_match_data_free(match_data); /* Release memory used for the match */ + pcre2_code_free(re); /* data and the compiled pattern. */ + return 1; + } + +/* Match succeded. Get a pointer to the output vector, where string offsets are +stored. */ + +ovector = pcre2_get_ovector_pointer(match_data); +printf("\nMatch succeeded at offset %d\n", (int)ovector[0]); + + +/************************************************************************* +* We have found the first match within the subject string. If the output * +* vector wasn't big enough, say so. Then output any substrings that were * +* captured. * +*************************************************************************/ + +/* The output vector wasn't big enough. This should not happen, because we used +pcre2_match_data_create_from_pattern() above. */ + +if (rc == 0) + printf("ovector was not big enough for all the captured substrings\n"); + +/* Show substrings stored in the output vector by number. Obviously, in a real +application you might want to do things other than print them. */ + +for (i = 0; i < rc; i++) + { + PCRE2_SPTR substring_start = subject + ovector[2*i]; + size_t substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start); + } + + +/************************************************************************** +* That concludes the basic part of this demonstration program. We have * +* compiled a pattern, and performed a single match. The code that follows * +* shows first how to access named substrings, and then how to code for * +* repeated matches on the same subject. * +**************************************************************************/ + +/* See if there are any named substrings, and if so, show them by name. First +we have to extract the count of named parentheses from the pattern. */ + +(void)pcre2_pattern_info( + re, /* the compiled pattern */ + PCRE2_INFO_NAMECOUNT, /* get the number of named substrings */ + &namecount); /* where to put the answer */ + +if (namecount <= 0) printf("No named substrings\n"); else + { + PCRE2_SPTR tabptr; + printf("Named substrings\n"); + + /* Before we can access the substrings, we must extract the table for + translating names to numbers, and the size of each entry in the table. */ + + (void)pcre2_pattern_info( + re, /* the compiled pattern */ + PCRE2_INFO_NAMETABLE, /* address of the table */ + &name_table); /* where to put the answer */ + + (void)pcre2_pattern_info( + re, /* the compiled pattern */ + PCRE2_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ + &name_entry_size); /* where to put the answer */ + + /* Now we can scan the table and, for each entry, print the number, the name, + and the substring itself. In the 8-bit library the number is held in two + bytes, most significant first. */ + + tabptr = name_table; + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + + +/************************************************************************* +* If the "-g" option was given on the command line, we want to continue * +* to search for additional matches in the subject string, in a similar * +* way to the /g option in Perl. This turns out to be trickier than you * +* might think because of the possibility of matching an empty string. * +* What happens is as follows: * +* * +* If the previous match was NOT for an empty string, we can just start * +* the next match at the end of the previous one. * +* * +* If the previous match WAS for an empty string, we can't do that, as it * +* would lead to an infinite loop. Instead, a call of pcre2_match() is * +* made with the PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set. The * +* first of these tells PCRE2 that an empty string at the start of the * +* subject is not a valid match; other possibilities must be tried. The * +* second flag restricts PCRE2 to one match attempt at the initial string * +* position. If this match succeeds, an alternative to the empty string * +* match has been found, and we can print it and proceed round the loop, * +* advancing by the length of whatever was found. If this match does not * +* succeed, we still stay in the loop, advancing by just one character. * +* In UTF-8 mode, which can be set by (*UTF) in the pattern, this may be * +* more than one byte. * +* * +* However, there is a complication concerned with newlines. When the * +* newline convention is such that CRLF is a valid newline, we must * +* advance by two characters rather than one. The newline convention can * +* be set in the regex by (*CR), etc.; if not, we must find the default. * +*************************************************************************/ + +if (!find_all) /* Check for -g */ + { + pcre2_match_data_free(match_data); /* Release the memory that was used */ + pcre2_code_free(re); /* for the match data and the pattern. */ + return 0; /* Exit the program. */ + } + +/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline +sequence. First, find the options with which the regex was compiled and extract +the UTF state. */ + +(void)pcre2_pattern_info(re, PCRE2_INFO_ALLOPTIONS, &option_bits); +utf8 = (option_bits & PCRE2_UTF) != 0; + +/* Now find the newline convention and see whether CRLF is a valid newline +sequence. */ + +(void)pcre2_pattern_info(re, PCRE2_INFO_NEWLINE, &newline); +crlf_is_newline = newline == PCRE2_NEWLINE_ANY || + newline == PCRE2_NEWLINE_CRLF || + newline == PCRE2_NEWLINE_ANYCRLF; + +/* Loop for second and subsequent matches */ + +for (;;) + { + uint32_t options = 0; /* Normally no options */ + PCRE2_SIZE start_offset = ovector[1]; /* Start at end of previous match */ + + /* If the previous match was for an empty string, we are finished if we are + at the end of the subject. Otherwise, arrange to run another match at the + same point to see if a non-empty match can be found. */ + + if (ovector[0] == ovector[1]) + { + if (ovector[0] == subject_length) break; + options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; + } + + /* Run the next matching operation */ + + rc = pcre2_match( + re, /* the compiled pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + start_offset, /* starting offset in the subject */ + options, /* options */ + match_data, /* block for storing the result */ + NULL); /* use default match context */ + + /* This time, a result of NOMATCH isn't an error. If the value in "options" + is zero, it just means we have found all possible matches, so the loop ends. + Otherwise, it means we have failed to find a non-empty-string match at a + point where there was a previous empty-string match. In this case, we do what + Perl does: advance the matching position by one character, and continue. We + do this by setting the "end of previous match" offset, because that is picked + up at the top of the loop as the point at which to start again. + + There are two complications: (a) When CRLF is a valid newline sequence, and + the current position is just before it, advance by an extra byte. (b) + Otherwise we must ensure that we skip an entire UTF character if we are in + UTF mode. */ + + if (rc == PCRE2_ERROR_NOMATCH) + { + if (options == 0) break; /* All matches found */ + ovector[1] = start_offset + 1; /* Advance one code unit */ + if (crlf_is_newline && /* If CRLF is newline & */ + start_offset < subject_length - 1 && /* we are at CRLF, */ + subject[start_offset] == '\r' && + subject[start_offset + 1] == '\n') + ovector[1] += 1; /* Advance by one more. */ + else if (utf8) /* Otherwise, ensure we */ + { /* advance a whole UTF-8 */ + while (ovector[1] < subject_length) /* character. */ + { + if ((subject[ovector[1]] & 0xc0) != 0x80) break; + ovector[1] += 1; + } + } + continue; /* Go round the loop again */ + } + + /* Other matching errors are not recoverable. */ + + if (rc < 0) + { + printf("Matching error %d\n", rc); + pcre2_match_data_free(match_data); + pcre2_code_free(re); + return 1; + } + + /* Match succeded */ + + printf("\nMatch succeeded again at offset %d\n", (int)ovector[0]); + + /* The match succeeded, but the output vector wasn't big enough. This + should not happen. */ + + if (rc == 0) + printf("ovector was not big enough for all the captured substrings\n"); + + /* As before, show substrings stored in the output vector by number, and then + also any named substrings. */ + + for (i = 0; i < rc; i++) + { + PCRE2_SPTR substring_start = subject + ovector[2*i]; + size_t substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start); + } + + if (namecount <= 0) printf("No named substrings\n"); else + { + PCRE2_SPTR tabptr = name_table; + printf("Named substrings\n"); + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + } /* End of loop to find second and subsequent matches */ + +printf("\n"); +pcre2_match_data_free(match_data); +pcre2_code_free(re); +return 0; +} + +/* End of pcre2demo.c */ diff --git a/pcre2/src/pcre2grep.c b/pcre2/src/pcre2grep.c new file mode 100644 index 000000000..aadb22a57 --- /dev/null +++ b/pcre2/src/pcre2grep.c @@ -0,0 +1,3270 @@ +/************************************************* +* pcre2grep program * +*************************************************/ + +/* This is a grep program that uses the 8-bit PCRE regular expression library +via the PCRE2 updated API to do its pattern matching. On Unix-like, Windows, +and native z/OS systems it can recurse into directories, and in z/OS it can +handle PDS files. + +Note that for native z/OS, in addition to defining the NATIVE_ZOS macro, an +additional header is required. That header is not included in the main PCRE2 +distribution because other apparatus is needed to compile pcre2grep for z/OS. +The header can be found in the special z/OS distribution, which is available +from www.zaconsultants.net or from www.cbttape.org. + + Copyright (c) 1997-2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef SUPPORT_LIBZ +#include +#endif + +#ifdef SUPPORT_LIBBZ2 +#include +#endif + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include "pcre2.h" + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; + +#define OFFSET_SIZE 33 + +#if BUFSIZ > 8192 +#define MAXPATLEN BUFSIZ +#else +#define MAXPATLEN 8192 +#endif + +#define PATBUFSIZE (MAXPATLEN + 10) /* Allows for prefix+suffix */ + +/* Values for the "filenames" variable, which specifies options for file name +output. The order is important; it is assumed that a file name is wanted for +all values greater than FN_DEFAULT. */ + +enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE }; + +/* File reading styles */ + +enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 }; + +/* Actions for the -d and -D options */ + +enum { dee_READ, dee_SKIP, dee_RECURSE }; +enum { DEE_READ, DEE_SKIP }; + +/* Actions for special processing options (flag bits) */ + +#define PO_WORD_MATCH 0x0001 +#define PO_LINE_MATCH 0x0002 +#define PO_FIXED_STRINGS 0x0004 + +/* Binary file options */ + +enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT }; + +/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some +environments), a warning is issued if the value of fwrite() is ignored. +Unfortunately, casting to (void) does not suppress the warning. To get round +this, we use a macro that compiles a fudge. Oddly, this does not also seem to +apply to fprintf(). */ + +#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {} + + + +/************************************************* +* Global variables * +*************************************************/ + +/* Jeffrey Friedl has some debugging requirements that are not part of the +regular code. */ + +#ifdef JFRIEDL_DEBUG +static int S_arg = -1; +static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */ +static unsigned int jfriedl_XT = 0; /* replicate text this many times */ +static const char *jfriedl_prefix = ""; +static const char *jfriedl_postfix = ""; +#endif + +static char *colour_string = (char *)"1;31"; +static char *colour_option = NULL; +static char *dee_option = NULL; +static char *DEE_option = NULL; +static char *locale = NULL; +static char *main_buffer = NULL; +static char *newline_arg = NULL; +static char *om_separator = (char *)""; +static char *stdin_name = (char *)"(standard input)"; + +static int after_context = 0; +static int before_context = 0; +static int binary_files = BIN_BINARY; +static int both_context = 0; +static int bufthird = PCRE2GREP_BUFSIZE; +static int bufsize = 3*PCRE2GREP_BUFSIZE; +static int endlinetype; + +#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H +static int dee_action = dee_SKIP; +#else +static int dee_action = dee_READ; +#endif +static int DEE_action = DEE_READ; +static int error_count = 0; +static int filenames = FN_DEFAULT; + +#ifdef SUPPORT_PCRE2GREP_JIT +static BOOL use_jit = TRUE; +#else +static BOOL use_jit = FALSE; +#endif + +static const uint8_t *character_tables = NULL; + +static uint32_t pcre2_options = 0; +static uint32_t process_options = 0; +static uint32_t match_limit = 0; +static uint32_t recursion_limit = 0; + +static pcre2_compile_context *compile_context; +static pcre2_match_context *match_context; +static pcre2_match_data *match_data; +static PCRE2_SIZE *offsets; + +static BOOL count_only = FALSE; +static BOOL do_colour = FALSE; +static BOOL file_offsets = FALSE; +static BOOL hyphenpending = FALSE; +static BOOL invert = FALSE; +static BOOL line_buffered = FALSE; +static BOOL line_offsets = FALSE; +static BOOL multiline = FALSE; +static BOOL number = FALSE; +static BOOL omit_zero_count = FALSE; +static BOOL resource_error = FALSE; +static BOOL quiet = FALSE; +static BOOL show_only_matching = FALSE; +static BOOL silent = FALSE; +static BOOL utf = FALSE; + +/* Structure for list of --only-matching capturing numbers. */ + +typedef struct omstr { + struct omstr *next; + int groupnum; +} omstr; + +static omstr *only_matching = NULL; +static omstr *only_matching_last = NULL; + +/* Structure for holding the two variables that describe a number chain. */ + +typedef struct omdatastr { + omstr **anchor; + omstr **lastptr; +} omdatastr; + +static omdatastr only_matching_data = { &only_matching, &only_matching_last }; + +/* Structure for list of file names (for -f and --{in,ex}clude-from) */ + +typedef struct fnstr { + struct fnstr *next; + char *name; +} fnstr; + +static fnstr *exclude_from = NULL; +static fnstr *exclude_from_last = NULL; +static fnstr *include_from = NULL; +static fnstr *include_from_last = NULL; + +static fnstr *file_lists = NULL; +static fnstr *file_lists_last = NULL; +static fnstr *pattern_files = NULL; +static fnstr *pattern_files_last = NULL; + +/* Structure for holding the two variables that describe a file name chain. */ + +typedef struct fndatastr { + fnstr **anchor; + fnstr **lastptr; +} fndatastr; + +static fndatastr exclude_from_data = { &exclude_from, &exclude_from_last }; +static fndatastr include_from_data = { &include_from, &include_from_last }; +static fndatastr file_lists_data = { &file_lists, &file_lists_last }; +static fndatastr pattern_files_data = { &pattern_files, &pattern_files_last }; + +/* Structure for pattern and its compiled form; used for matching patterns and +also for include/exclude patterns. */ + +typedef struct patstr { + struct patstr *next; + char *string; + pcre2_code *compiled; +} patstr; + +static patstr *patterns = NULL; +static patstr *patterns_last = NULL; +static patstr *include_patterns = NULL; +static patstr *include_patterns_last = NULL; +static patstr *exclude_patterns = NULL; +static patstr *exclude_patterns_last = NULL; +static patstr *include_dir_patterns = NULL; +static patstr *include_dir_patterns_last = NULL; +static patstr *exclude_dir_patterns = NULL; +static patstr *exclude_dir_patterns_last = NULL; + +/* Structure holding the two variables that describe a pattern chain. A pointer +to such structures is used for each appropriate option. */ + +typedef struct patdatastr { + patstr **anchor; + patstr **lastptr; +} patdatastr; + +static patdatastr match_patdata = { &patterns, &patterns_last }; +static patdatastr include_patdata = { &include_patterns, &include_patterns_last }; +static patdatastr exclude_patdata = { &exclude_patterns, &exclude_patterns_last }; +static patdatastr include_dir_patdata = { &include_dir_patterns, &include_dir_patterns_last }; +static patdatastr exclude_dir_patdata = { &exclude_dir_patterns, &exclude_dir_patterns_last }; + +static patstr **incexlist[4] = { &include_patterns, &exclude_patterns, + &include_dir_patterns, &exclude_dir_patterns }; + +static const char *incexname[4] = { "--include", "--exclude", + "--include-dir", "--exclude-dir" }; + +/* Structure for options and list of them */ + +enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_U32NUMBER, + OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES }; + +typedef struct option_item { + int type; + int one_char; + void *dataptr; + const char *long_name; + const char *help_text; +} option_item; + +/* Options without a single-letter equivalent get a negative value. This can be +used to identify them. */ + +#define N_COLOUR (-1) +#define N_EXCLUDE (-2) +#define N_EXCLUDE_DIR (-3) +#define N_HELP (-4) +#define N_INCLUDE (-5) +#define N_INCLUDE_DIR (-6) +#define N_LABEL (-7) +#define N_LOCALE (-8) +#define N_NULL (-9) +#define N_LOFFSETS (-10) +#define N_FOFFSETS (-11) +#define N_LBUFFER (-12) +#define N_M_LIMIT (-13) +#define N_M_LIMIT_REC (-14) +#define N_BUFSIZE (-15) +#define N_NOJIT (-16) +#define N_FILE_LIST (-17) +#define N_BINARY_FILES (-18) +#define N_EXCLUDE_FROM (-19) +#define N_INCLUDE_FROM (-20) +#define N_OM_SEPARATOR (-21) + +static option_item optionlist[] = { + { OP_NODATA, N_NULL, NULL, "", "terminate options" }, + { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" }, + { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" }, + { OP_NODATA, 'a', NULL, "text", "treat binary files as text" }, + { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" }, + { OP_BINFILES, N_BINARY_FILES, NULL, "binary-files=word", "set treatment of binary files" }, + { OP_NUMBER, N_BUFSIZE,&bufthird, "buffer-size=number", "set processing buffer size parameter" }, + { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" }, + { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" }, + { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" }, + { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" }, + { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" }, + { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" }, + { OP_PATLIST, 'e', &match_patdata, "regex(p)=pattern", "specify pattern (may be used more than once)" }, + { OP_NODATA, 'F', NULL, "fixed-strings", "patterns are sets of newline-separated strings" }, + { OP_FILELIST, 'f', &pattern_files_data, "file=path", "read patterns from file" }, + { OP_FILELIST, N_FILE_LIST, &file_lists_data, "file-list=path","read files to search from file" }, + { OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" }, + { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" }, + { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" }, + { OP_NODATA, 'I', NULL, "", "treat binary files as not matching (ignore)" }, + { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" }, +#ifdef SUPPORT_PCRE2GREP_JIT + { OP_NODATA, N_NOJIT, NULL, "no-jit", "do not use just-in-time compiler optimization" }, +#else + { OP_NODATA, N_NOJIT, NULL, "no-jit", "ignored: this pcre2grep does not support JIT" }, +#endif + { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" }, + { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" }, + { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" }, + { OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" }, + { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" }, + { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, + { OP_U32NUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE match limit option" }, + { OP_U32NUMBER, N_M_LIMIT_REC, &recursion_limit, "recursion-limit=number", "set PCRE match recursion limit option" }, + { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, + { OP_STRING, 'N', &newline_arg, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, + { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, + { OP_OP_NUMBERS, 'o', &only_matching_data, "only-matching=n", "show only the part of the line that matched" }, + { OP_STRING, N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" }, + { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, + { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, + { OP_PATLIST, N_EXCLUDE,&exclude_patdata, "exclude=pattern","exclude matching files when recursing" }, + { OP_PATLIST, N_INCLUDE,&include_patdata, "include=pattern","include matching files when recursing" }, + { OP_PATLIST, N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude-dir=pattern","exclude matching directories when recursing" }, + { OP_PATLIST, N_INCLUDE_DIR,&include_dir_patdata, "include-dir=pattern","include matching directories when recursing" }, + { OP_FILELIST, N_EXCLUDE_FROM,&exclude_from_data, "exclude-from=path", "read exclude list from file" }, + { OP_FILELIST, N_INCLUDE_FROM,&include_from_data, "include-from=path", "read include list from file" }, +#ifdef JFRIEDL_DEBUG + { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, +#endif + { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, + { OP_NODATA, 'u', NULL, "utf", "use UTF mode" }, + { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, + { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, + { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" }, + { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" }, + { OP_NODATA, 0, NULL, NULL, NULL } +}; + +/* Table of names for newline types. Must be kept in step with the definitions +of PCRE2_NEWLINE_xx in pcre2.h. */ + +static const char *newlines[] = { + "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" }; + +/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F +options. These set the 1, 2, and 4 bits in process_options, respectively. Note +that the combination of -w and -x has the same effect as -x on its own, so we +can treat them as the same. Note that the MAXPATLEN macro assumes the longest +prefix+suffix is 10 characters; if anything longer is added, it must be +adjusted. */ + +static const char *prefix[] = { + "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" }; + +static const char *suffix[] = { + "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" }; + +/* UTF-8 tables - used only when the newline setting is "any". */ + +const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +const char utf8_table4[] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; + + + +/************************************************* +* Case-independent string compare * +*************************************************/ + +static int +strcmpic(const char *str1, const char *str2) +{ +unsigned int c1, c2; +while (*str1 != '\0' || *str2 != '\0') + { + c1 = tolower(*str1++); + c2 = tolower(*str2++); + if (c1 != c2) return ((c1 > c2) << 1) - 1; + } +return 0; +} + + + +/************************************************* +* Exit from the program * +*************************************************/ + +/* If there has been a resource error, give a suitable message. + +Argument: the return code +Returns: does not return +*/ + +static void +pcre2grep_exit(int rc) +{ +if (resource_error) + { + fprintf(stderr, "pcre2grep: Error %d, %d or %d means that a resource limit " + "was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT, + PCRE2_ERROR_RECURSIONLIMIT); + fprintf(stderr, "pcre2grep: Check your regex for nested unlimited loops.\n"); + } +exit(rc); +} + + +/************************************************* +* Add item to chain of patterns * +*************************************************/ + +/* Used to add an item onto a chain, or just return an unconnected item if the +"after" argument is NULL. + +Arguments: + s pattern string to add + after if not NULL points to item to insert after + +Returns: new pattern block or NULL on error +*/ + +static patstr * +add_pattern(char *s, patstr *after) +{ +patstr *p = (patstr *)malloc(sizeof(patstr)); +if (p == NULL) + { + fprintf(stderr, "pcre2grep: malloc failed\n"); + pcre2grep_exit(2); + } +if (strlen(s) > MAXPATLEN) + { + fprintf(stderr, "pcre2grep: pattern is too long (limit is %d bytes)\n", + MAXPATLEN); + free(p); + return NULL; + } +p->next = NULL; +p->string = s; +p->compiled = NULL; + +if (after != NULL) + { + p->next = after->next; + after->next = p; + } +return p; +} + + +/************************************************* +* Free chain of patterns * +*************************************************/ + +/* Used for several chains of patterns. + +Argument: pointer to start of chain +Returns: nothing +*/ + +static void +free_pattern_chain(patstr *pc) +{ +while (pc != NULL) + { + patstr *p = pc; + pc = p->next; + if (p->compiled != NULL) pcre2_code_free(p->compiled); + free(p); + } +} + + +/************************************************* +* Free chain of file names * +*************************************************/ + +/* +Argument: pointer to start of chain +Returns: nothing +*/ + +static void +free_file_chain(fnstr *fn) +{ +while (fn != NULL) + { + fnstr *f = fn; + fn = f->next; + free(f); + } +} + + +/************************************************* +* OS-specific functions * +*************************************************/ + +/* These functions are defined so that they can be made system specific. +At present there are versions for Unix-style environments, Windows, native +z/OS, and "no support". */ + + +/************* Directory scanning Unix-style and z/OS ***********/ + +#if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS +#include +#include +#include + +#if defined NATIVE_ZOS +/************* Directory and PDS/E scanning for z/OS ***********/ +/************* z/OS looks mostly like Unix with USS ************/ +/* However, z/OS needs the #include statements in this header */ +#include "pcrzosfs.h" +/* That header is not included in the main PCRE distribution because + other apparatus is needed to compile pcre2grep for z/OS. The header + can be found in the special z/OS distribution, which is available + from www.zaconsultants.net or from www.cbttape.org. */ +#endif + +typedef DIR directory_type; +#define FILESEP '/' + +static int +isdirectory(char *filename) +{ +struct stat statbuf; +if (stat(filename, &statbuf) < 0) + return 0; /* In the expectation that opening as a file will fail */ +return S_ISDIR(statbuf.st_mode); +} + +static directory_type * +opendirectory(char *filename) +{ +return opendir(filename); +} + +static char * +readdirectory(directory_type *dir) +{ +for (;;) + { + struct dirent *dent = readdir(dir); + if (dent == NULL) return NULL; + if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) + return dent->d_name; + } +/* Control never reaches here */ +} + +static void +closedirectory(directory_type *dir) +{ +closedir(dir); +} + + +/************* Test for regular file, Unix-style **********/ + +static int +isregfile(char *filename) +{ +struct stat statbuf; +if (stat(filename, &statbuf) < 0) + return 1; /* In the expectation that opening as a file will fail */ +return S_ISREG(statbuf.st_mode); +} + + +#if defined NATIVE_ZOS +/************* Test for a terminal in z/OS **********/ +/* isatty() does not work in a TSO environment, so always give FALSE.*/ + +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + + +/************* Test for a terminal, Unix-style **********/ + +#else +static BOOL +is_stdout_tty(void) +{ +return isatty(fileno(stdout)); +} + +static BOOL +is_file_tty(FILE *f) +{ +return isatty(fileno(f)); +} +#endif + +/* End of Unix-style or native z/OS environment functions. */ + + +/************* Directory scanning in Windows ***********/ + +/* I (Philip Hazel) have no means of testing this code. It was contributed by +Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES +when it did not exist. David Byron added a patch that moved the #include of + to before the INVALID_FILE_ATTRIBUTES definition rather than after. +The double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is +undefined when it is indeed undefined. */ + +#elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H + +#ifndef STRICT +# define STRICT +#endif +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#include + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF +#endif + +typedef struct directory_type +{ +HANDLE handle; +BOOL first; +WIN32_FIND_DATA data; +} directory_type; + +#define FILESEP '/' + +int +isdirectory(char *filename) +{ +DWORD attr = GetFileAttributes(filename); +if (attr == INVALID_FILE_ATTRIBUTES) + return 0; +return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +directory_type * +opendirectory(char *filename) +{ +size_t len; +char *pattern; +directory_type *dir; +DWORD err; +len = strlen(filename); +pattern = (char *)malloc(len + 3); +dir = (directory_type *)malloc(sizeof(*dir)); +if ((pattern == NULL) || (dir == NULL)) + { + fprintf(stderr, "pcre2grep: malloc failed\n"); + pcre2grep_exit(2); + } +memcpy(pattern, filename, len); +memcpy(&(pattern[len]), "\\*", 3); +dir->handle = FindFirstFile(pattern, &(dir->data)); +if (dir->handle != INVALID_HANDLE_VALUE) + { + free(pattern); + dir->first = TRUE; + return dir; + } +err = GetLastError(); +free(pattern); +free(dir); +errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; +return NULL; +} + +char * +readdirectory(directory_type *dir) +{ +for (;;) + { + if (!dir->first) + { + if (!FindNextFile(dir->handle, &(dir->data))) + return NULL; + } + else + { + dir->first = FALSE; + } + if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) + return dir->data.cFileName; + } +#ifndef _MSC_VER +return NULL; /* Keep compiler happy; never executed */ +#endif +} + +void +closedirectory(directory_type *dir) +{ +FindClose(dir->handle); +free(dir); +} + + +/************* Test for regular file in Windows **********/ + +/* I don't know how to do this, or if it can be done; assume all paths are +regular if they are not directories. */ + +int isregfile(char *filename) +{ +return !isdirectory(filename); +} + + +/************* Test for a terminal in Windows **********/ + +/* I don't know how to do this; assume never */ + +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + +/* End of Windows functions */ + + +/************* Directory scanning when we can't do it ***********/ + +/* The type is void, and apart from isdirectory(), the functions do nothing. */ + +#else + +#define FILESEP 0 +typedef void directory_type; + +int isdirectory(char *filename) { return 0; } +directory_type * opendirectory(char *filename) { return (directory_type*)0;} +char *readdirectory(directory_type *dir) { return (char*)0;} +void closedirectory(directory_type *dir) {} + + +/************* Test for regular file when we can't do it **********/ + +/* Assume all files are regular. */ + +int isregfile(char *filename) { return 1; } + + +/************* Test for a terminal when we can't do it **********/ + +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + +#endif /* End of system-specific functions */ + + + +#ifndef HAVE_STRERROR +/************************************************* +* Provide strerror() for non-ANSI libraries * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +* Usage function * +*************************************************/ + +static int +usage(int rc) +{ +option_item *op; +fprintf(stderr, "Usage: pcre2grep [-"); +for (op = optionlist; op->one_char != 0; op++) + { + if (op->one_char > 0) fprintf(stderr, "%c", op->one_char); + } +fprintf(stderr, "] [long options] [pattern] [files]\n"); +fprintf(stderr, "Type `pcre2grep --help' for more information and the long " + "options.\n"); +return rc; +} + + + +/************************************************* +* Help function * +*************************************************/ + +static void +help(void) +{ +option_item *op; + +printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); +printf("Search for PATTERN in each FILE or standard input.\n"); +printf("PATTERN must be present if neither -e nor -f is used.\n"); +printf("\"-\" can be used as a file name to mean STDIN.\n"); + +#ifdef SUPPORT_LIBZ +printf("Files whose names end in .gz are read using zlib.\n"); +#endif + +#ifdef SUPPORT_LIBBZ2 +printf("Files whose names end in .bz2 are read using bzlib2.\n"); +#endif + +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 +printf("Other files and the standard input are read as plain files.\n\n"); +#else +printf("All files are read as plain files, without any interpretation.\n\n"); +#endif + +printf("Example: pcre2grep -i 'hello.*world' menu.h main.c\n\n"); +printf("Options:\n"); + +for (op = optionlist; op->one_char != 0; op++) + { + int n; + char s[4]; + + if (op->one_char > 0 && (op->long_name)[0] == 0) + n = 31 - printf(" -%c", op->one_char); + else + { + if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); + else strcpy(s, " "); + n = 31 - printf(" %s --%s", s, op->long_name); + } + + if (n < 1) n = 1; + printf("%.*s%s\n", n, " ", op->help_text); + } + +printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n"); +printf("The default value for --buffer-size is %d.\n", PCRE2GREP_BUFSIZE); +printf("When reading patterns or file names from a file, trailing white\n"); +printf("space is removed and blank lines are ignored.\n"); +printf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN); + +printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); +printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); +} + + + +/************************************************* +* Test exclude/includes * +*************************************************/ + +/* If any exclude pattern matches, the path is excluded. Otherwise, unless +there are no includes, the path must match an include pattern. + +Arguments: + path the path to be matched + ip the chain of include patterns + ep the chain of exclude patterns + +Returns: TRUE if the path is not excluded +*/ + +static BOOL +test_incexc(char *path, patstr *ip, patstr *ep) +{ +int plen = strlen((const char *)path); + +for (; ep != NULL; ep = ep->next) + { + if (pcre2_match(ep->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0) + return FALSE; + } + +if (ip == NULL) return TRUE; + +for (; ip != NULL; ip = ip->next) + { + if (pcre2_match(ip->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0) + return TRUE; + } + +return FALSE; +} + + + +/************************************************* +* Decode integer argument value * +*************************************************/ + +/* Integer arguments can be followed by K or M. Avoid the use of strtoul() +because SunOS4 doesn't have it. This is used only for unpicking arguments, so +just keep it simple. + +Arguments: + option_data the option data string + op the option item (for error messages) + longop TRUE if option given in long form + +Returns: a long integer +*/ + +static long int +decode_number(char *option_data, option_item *op, BOOL longop) +{ +unsigned long int n = 0; +char *endptr = option_data; +while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++; +while (isdigit((unsigned char)(*endptr))) + n = n * 10 + (int)(*endptr++ - '0'); +if (toupper(*endptr) == 'K') + { + n *= 1024; + endptr++; + } +else if (toupper(*endptr) == 'M') + { + n *= 1024*1024; + endptr++; + } + +if (*endptr != 0) /* Error */ + { + if (longop) + { + char *equals = strchr(op->long_name, '='); + int nlen = (equals == NULL)? (int)strlen(op->long_name) : + (int)(equals - op->long_name); + fprintf(stderr, "pcre2grep: Malformed number \"%s\" after --%.*s\n", + option_data, nlen, op->long_name); + } + else + fprintf(stderr, "pcre2grep: Malformed number \"%s\" after -%c\n", + option_data, op->one_char); + pcre2grep_exit(usage(2)); + } + +return n; +} + + + +/************************************************* +* Add item to a chain of numbers * +*************************************************/ + +/* Used to add an item onto a chain, or just return an unconnected item if the +"after" argument is NULL. + +Arguments: + n the number to add + after if not NULL points to item to insert after + +Returns: new number block +*/ + +static omstr * +add_number(int n, omstr *after) +{ +omstr *om = (omstr *)malloc(sizeof(omstr)); + +if (om == NULL) + { + fprintf(stderr, "pcre2grep: malloc failed\n"); + pcre2grep_exit(2); + } +om->next = NULL; +om->groupnum = n; + +if (after != NULL) + { + om->next = after->next; + after->next = om; + } +return om; +} + + + +/************************************************* +* Read one line of input * +*************************************************/ + +/* Normally, input is read using fread() into a large buffer, so many lines may +be read at once. However, doing this for tty input means that no output appears +until a lot of input has been typed. Instead, tty input is handled line by +line. We cannot use fgets() for this, because it does not stop at a binary +zero, and therefore there is no way of telling how many characters it has read, +because there may be binary zeros embedded in the data. + +Arguments: + buffer the buffer to read into + length the maximum number of characters to read + f the file + +Returns: the number of characters read, zero at end of file +*/ + +static unsigned int +read_one_line(char *buffer, int length, FILE *f) +{ +int c; +int yield = 0; +while ((c = fgetc(f)) != EOF) + { + buffer[yield++] = c; + if (c == '\n' || yield >= length) break; + } +return yield; +} + + + +/************************************************* +* Find end of line * +*************************************************/ + +/* The length of the endline sequence that is found is set via lenptr. This may +be zero at the very end of the file if there is no line-ending sequence there. + +Arguments: + p current position in line + endptr end of available data + lenptr where to put the length of the eol sequence + +Returns: pointer after the last byte of the line, + including the newline byte(s) +*/ + +static char * +end_of_line(char *p, char *endptr, int *lenptr) +{ +switch(endlinetype) + { + default: /* Just in case */ + case PCRE2_NEWLINE_LF: + while (p < endptr && *p != '\n') p++; + if (p < endptr) + { + *lenptr = 1; + return p + 1; + } + *lenptr = 0; + return endptr; + + case PCRE2_NEWLINE_CR: + while (p < endptr && *p != '\r') p++; + if (p < endptr) + { + *lenptr = 1; + return p + 1; + } + *lenptr = 0; + return endptr; + + case PCRE2_NEWLINE_CRLF: + for (;;) + { + while (p < endptr && *p != '\r') p++; + if (++p >= endptr) + { + *lenptr = 0; + return endptr; + } + if (*p == '\n') + { + *lenptr = 2; + return p + 1; + } + } + break; + + case PCRE2_NEWLINE_ANYCRLF: + while (p < endptr) + { + int extra = 0; + register int c = *((unsigned char *)p); + + if (utf && c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (p[gcii] & 0x3f) << gcss; + } + } + + p += 1 + extra; + + switch (c) + { + case '\n': + *lenptr = 1; + return p; + + case '\r': + if (p < endptr && *p == '\n') + { + *lenptr = 2; + p++; + } + else *lenptr = 1; + return p; + + default: + break; + } + } /* End of loop for ANYCRLF case */ + + *lenptr = 0; /* Must have hit the end */ + return endptr; + + case PCRE2_NEWLINE_ANY: + while (p < endptr) + { + int extra = 0; + register int c = *((unsigned char *)p); + + if (utf && c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (p[gcii] & 0x3f) << gcss; + } + } + + p += 1 + extra; + + switch (c) + { + case '\n': /* LF */ + case '\v': /* VT */ + case '\f': /* FF */ + *lenptr = 1; + return p; + + case '\r': /* CR */ + if (p < endptr && *p == '\n') + { + *lenptr = 2; + p++; + } + else *lenptr = 1; + return p; + +#ifndef EBCDIC + case 0x85: /* Unicode NEL */ + *lenptr = utf? 2 : 1; + return p; + + case 0x2028: /* Unicode LS */ + case 0x2029: /* Unicode PS */ + *lenptr = 3; + return p; +#endif /* Not EBCDIC */ + + default: + break; + } + } /* End of loop for ANY case */ + + *lenptr = 0; /* Must have hit the end */ + return endptr; + } /* End of overall switch */ +} + + + +/************************************************* +* Find start of previous line * +*************************************************/ + +/* This is called when looking back for before lines to print. + +Arguments: + p start of the subsequent line + startptr start of available data + +Returns: pointer to the start of the previous line +*/ + +static char * +previous_line(char *p, char *startptr) +{ +switch(endlinetype) + { + default: /* Just in case */ + case PCRE2_NEWLINE_LF: + p--; + while (p > startptr && p[-1] != '\n') p--; + return p; + + case PCRE2_NEWLINE_CR: + p--; + while (p > startptr && p[-1] != '\n') p--; + return p; + + case PCRE2_NEWLINE_CRLF: + for (;;) + { + p -= 2; + while (p > startptr && p[-1] != '\n') p--; + if (p <= startptr + 1 || p[-2] == '\r') return p; + } + /* Control can never get here */ + + case PCRE2_NEWLINE_ANY: + case PCRE2_NEWLINE_ANYCRLF: + if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--; + if (utf) while ((*p & 0xc0) == 0x80) p--; + + while (p > startptr) + { + register unsigned int c; + char *pp = p - 1; + + if (utf) + { + int extra = 0; + while ((*pp & 0xc0) == 0x80) pp--; + c = *((unsigned char *)pp); + if (c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (pp[gcii] & 0x3f) << gcss; + } + } + } + else c = *((unsigned char *)pp); + + if (endlinetype == PCRE2_NEWLINE_ANYCRLF) switch (c) + { + case '\n': /* LF */ + case '\r': /* CR */ + return p; + + default: + break; + } + + else switch (c) + { + case '\n': /* LF */ + case '\v': /* VT */ + case '\f': /* FF */ + case '\r': /* CR */ +#ifndef EBCDIE + case 0x85: /* Unicode NEL */ + case 0x2028: /* Unicode LS */ + case 0x2029: /* Unicode PS */ +#endif /* Not EBCDIC */ + return p; + + default: + break; + } + + p = pp; /* Back one character */ + } /* End of loop for ANY case */ + + return startptr; /* Hit start of data */ + } /* End of overall switch */ +} + + + + + +/************************************************* +* Print the previous "after" lines * +*************************************************/ + +/* This is called if we are about to lose said lines because of buffer filling, +and at the end of the file. The data in the line is written using fwrite() so +that a binary zero does not terminate it. + +Arguments: + lastmatchnumber the number of the last matching line, plus one + lastmatchrestart where we restarted after the last match + endptr end of available data + printname filename for printing + +Returns: nothing +*/ + +static void +do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr, + char *printname) +{ +if (after_context > 0 && lastmatchnumber > 0) + { + int count = 0; + while (lastmatchrestart < endptr && count++ < after_context) + { + int ellength; + char *pp = lastmatchrestart; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", lastmatchnumber++); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); + lastmatchrestart = pp; + } + hyphenpending = TRUE; + } +} + + + +/************************************************* +* Apply patterns to subject till one matches * +*************************************************/ + +/* This function is called to run through all patterns, looking for a match. It +is used multiple times for the same subject when colouring is enabled, in order +to find all possible matches. + +Arguments: + matchptr the start of the subject + length the length of the subject to match + options options for pcre_exec + startoffset where to start matching + mrc address of where to put the result of pcre2_match() + +Returns: TRUE if there was a match + FALSE if there was no match + invert if there was a non-fatal error +*/ + +static BOOL +match_patterns(char *matchptr, size_t length, unsigned int options, + size_t startoffset, int *mrc) +{ +int i; +size_t slen = length; +patstr *p = patterns; +const char *msg = "this text:\n\n"; + +if (slen > 200) + { + slen = 200; + msg = "text that starts:\n\n"; + } +for (i = 1; p != NULL; p = p->next, i++) + { + *mrc = pcre2_match(p->compiled, (PCRE2_SPTR)matchptr, (int)length, + startoffset, options, match_data, match_context); + if (*mrc >= 0) return TRUE; + if (*mrc == PCRE2_ERROR_NOMATCH) continue; + fprintf(stderr, "pcre2grep: pcre2_match() gave error %d while matching ", *mrc); + if (patterns->next != NULL) fprintf(stderr, "pattern number %d to ", i); + fprintf(stderr, "%s", msg); + FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */ + fprintf(stderr, "\n\n"); + if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_RECURSIONLIMIT || + *mrc == PCRE2_ERROR_JIT_STACKLIMIT) + resource_error = TRUE; + if (error_count++ > 20) + { + fprintf(stderr, "pcre2grep: Too many errors - abandoned.\n"); + pcre2grep_exit(2); + } + return invert; /* No more matching; don't show the line again */ + } + +return FALSE; /* No match, no errors */ +} + + + +/************************************************* +* Grep an individual file * +*************************************************/ + +/* This is called from grep_or_recurse() below. It uses a buffer that is three +times the value of bufthird. The matching point is never allowed to stray into +the top third of the buffer, thus keeping more of the file available for +context printing or for multiline scanning. For large files, the pointer will +be in the middle third most of the time, so the bottom third is available for +"before" context printing. + +Arguments: + handle the fopened FILE stream for a normal file + the gzFile pointer when reading is via libz + the BZFILE pointer when reading is via libbz2 + frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2 + filename the file name or NULL (for errors) + printname the file name if it is to be printed for each match + or NULL if the file name is not to be printed + it cannot be NULL if filenames[_nomatch]_only is set + +Returns: 0 if there was at least one match + 1 otherwise (no matches) + 2 if an overlong line is encountered + 3 if there is a read error on a .bz2 file +*/ + +static int +pcre2grep(void *handle, int frtype, char *filename, char *printname) +{ +int rc = 1; +int linenumber = 1; +int lastmatchnumber = 0; +int count = 0; +int filepos = 0; +char *lastmatchrestart = NULL; +char *ptr = main_buffer; +char *endptr; +size_t bufflength; +BOOL binary = FALSE; +BOOL endhyphenpending = FALSE; +BOOL input_line_buffered = line_buffered; +FILE *in = NULL; /* Ensure initialized */ + +#ifdef SUPPORT_LIBZ +gzFile ingz = NULL; +#endif + +#ifdef SUPPORT_LIBBZ2 +BZFILE *inbz2 = NULL; +#endif + + +/* Do the first read into the start of the buffer and set up the pointer to end +of what we have. In the case of libz, a non-zipped .gz file will be read as a +plain file. However, if a .bz2 file isn't actually bzipped, the first read will +fail. */ + +(void)frtype; + +#ifdef SUPPORT_LIBZ +if (frtype == FR_LIBZ) + { + ingz = (gzFile)handle; + bufflength = gzread (ingz, main_buffer, bufsize); + } +else +#endif + +#ifdef SUPPORT_LIBBZ2 +if (frtype == FR_LIBBZ2) + { + inbz2 = (BZFILE *)handle; + bufflength = BZ2_bzread(inbz2, main_buffer, bufsize); + if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */ + } /* without the cast it is unsigned. */ +else +#endif + + { + in = (FILE *)handle; + if (is_file_tty(in)) input_line_buffered = TRUE; + bufflength = input_line_buffered? + read_one_line(main_buffer, bufsize, in) : + fread(main_buffer, 1, bufsize, in); + } + +endptr = main_buffer + bufflength; + +/* Unless binary-files=text, see if we have a binary file. This uses the same +rule as GNU grep, namely, a search for a binary zero byte near the start of the +file. */ + +if (binary_files != BIN_TEXT) + { + binary = + memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL; + if (binary && binary_files == BIN_NOMATCH) return 1; + } + +/* Loop while the current pointer is not at the end of the file. For large +files, endptr will be at the end of the buffer when we are in the middle of the +file, but ptr will never get there, because as soon as it gets over 2/3 of the +way, the buffer is shifted left and re-filled. */ + +while (ptr < endptr) + { + int endlinelength; + int mrc = 0; + unsigned int options = 0; + BOOL match; + char *matchptr = ptr; + char *t = ptr; + size_t length, linelength; + size_t startoffset = 0; + + /* At this point, ptr is at the start of a line. We need to find the length + of the subject string to pass to pcre_exec(). In multiline mode, it is the + length remainder of the data in the buffer. Otherwise, it is the length of + the next line, excluding the terminating newline. After matching, we always + advance by the length of the next line. In multiline mode the PCRE2_FIRSTLINE + option is used for compiling, so that any match is constrained to be in the + first line. */ + + t = end_of_line(t, endptr, &endlinelength); + linelength = t - ptr - endlinelength; + length = multiline? (size_t)(endptr - ptr) : linelength; + + /* Check to see if the line we are looking at extends right to the very end + of the buffer without a line terminator. This means the line is too long to + handle. */ + + if (endlinelength == 0 && t == main_buffer + bufsize) + { + fprintf(stderr, "pcre2grep: line %d%s%s is too long for the internal buffer\n" + "pcre2grep: check the --buffer-size option\n", + linenumber, + (filename == NULL)? "" : " of file ", + (filename == NULL)? "" : filename); + return 2; + } + + /* Extra processing for Jeffrey Friedl's debugging. */ + +#ifdef JFRIEDL_DEBUG + if (jfriedl_XT || jfriedl_XR) + { +# include +# include + struct timeval start_time, end_time; + struct timezone dummy; + int i; + + if (jfriedl_XT) + { + unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix); + const char *orig = ptr; + ptr = malloc(newlen + 1); + if (!ptr) { + printf("out of memory"); + pcre2grep_exit(2); + } + endptr = ptr; + strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix); + for (i = 0; i < jfriedl_XT; i++) { + strncpy(endptr, orig, length); + endptr += length; + } + strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix); + length = newlen; + } + + if (gettimeofday(&start_time, &dummy) != 0) + perror("bad gettimeofday"); + + + for (i = 0; i < jfriedl_XR; i++) + match = (pcre_exec(patterns->compiled, patterns->hint, ptr, length, 0, + PCRE2_NOTEMPTY, offsets, OFFSET_SIZE) >= 0); + + if (gettimeofday(&end_time, &dummy) != 0) + perror("bad gettimeofday"); + + double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0)) + - + (start_time.tv_sec + (start_time.tv_usec / 1000000.0))); + + printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta); + return 0; + } +#endif + + /* We come back here after a match when show_only_matching is set, in order + to find any further matches in the same line. This applies to + --only-matching, --file-offsets, and --line-offsets. */ + + ONLY_MATCHING_RESTART: + + /* Run through all the patterns until one matches or there is an error other + than NOMATCH. This code is in a subroutine so that it can be re-used for + finding subsequent matches when colouring matched lines. After finding one + match, set PCRE2_NOTEMPTY to disable any further matches of null strings in + this line. */ + + match = match_patterns(matchptr, length, options, startoffset, &mrc); + options = PCRE2_NOTEMPTY; + + /* If it's a match or a not-match (as required), do what's wanted. */ + + if (match != invert) + { + BOOL hyphenprinted = FALSE; + + /* We've failed if we want a file that doesn't have any matches. */ + + if (filenames == FN_NOMATCH_ONLY) return 1; + + /* If all we want is a yes/no answer, we can return immediately. */ + + if (quiet) return 0; + + /* Just count if just counting is wanted. */ + + else if (count_only) count++; + + /* When handling a binary file and binary-files==binary, the "binary" + variable will be set true (it's false in all other cases). In this + situation we just want to output the file name. No need to scan further. */ + + else if (binary) + { + fprintf(stdout, "Binary file %s matches\n", filename); + return 0; + } + + /* Likewise, if all we want is a file name, there is no need to scan any + more lines in the file. */ + + else if (filenames == FN_MATCH_ONLY) + { + fprintf(stdout, "%s\n", printname); + return 0; + } + + /* The --only-matching option prints just the substring that matched, + and/or one or more captured portions of it, as long as these strings are + not empty. The --file-offsets and --line-offsets options output offsets for + the matching substring (all three set show_only_matching). None of these + mutually exclusive options prints any context. Afterwards, adjust the start + and then jump back to look for further matches in the same line. If we are + in invert mode, however, nothing is printed and we do not restart - this + could still be useful because the return code is set. */ + + else if (show_only_matching) + { + if (!invert) + { + size_t oldstartoffset; + + if (printname != NULL) fprintf(stdout, "%s:", printname); + if (number) fprintf(stdout, "%d:", linenumber); + + /* Handle --line-offsets */ + + if (line_offsets) + fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), + (int)(offsets[1] - offsets[0])); + + /* Handle --file-offsets */ + + else if (file_offsets) + fprintf(stdout, "%d,%d\n", + (int)(filepos + matchptr + offsets[0] - ptr), + (int)(offsets[1] - offsets[0])); + + /* Handle --only-matching, which may occur many times */ + + else + { + BOOL printed = FALSE; + omstr *om; + + for (om = only_matching; om != NULL; om = om->next) + { + int n = om->groupnum; + if (n < mrc) + { + int plen = offsets[2*n + 1] - offsets[2*n]; + if (plen > 0) + { + if (printed) fprintf(stdout, "%s", om_separator); + if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); + FWRITE(matchptr + offsets[n*2], 1, plen, stdout); + if (do_colour) fprintf(stdout, "%c[00m", 0x1b); + printed = TRUE; + } + } + } + + if (printed || printname != NULL || number) fprintf(stdout, "\n"); + } + + /* Prepare to repeat to find the next match. If the pattern contained a + lookbehind that included \K, it is possible that the end of the match + might be at or before the actual starting offset we have just used. In + this case, start one character further on. */ + + match = FALSE; + if (line_buffered) fflush(stdout); + rc = 0; /* Had some success */ + startoffset = offsets[1]; /* Restart after the match */ + oldstartoffset = pcre2_get_startchar(match_data); + if (startoffset <= oldstartoffset) + { + if (startoffset >= length) goto END_ONE_MATCH; /* Were at end */ + startoffset = oldstartoffset + 1; + if (utf) + while ((matchptr[startoffset] & 0xc0) == 0x80) startoffset++; + } + goto ONLY_MATCHING_RESTART; + } + } + + /* This is the default case when none of the above options is set. We print + the matching lines(s), possibly preceded and/or followed by other lines of + context. */ + + else + { + /* See if there is a requirement to print some "after" lines from a + previous match. We never print any overlaps. */ + + if (after_context > 0 && lastmatchnumber > 0) + { + int ellength; + int linecount = 0; + char *p = lastmatchrestart; + + while (p < ptr && linecount < after_context) + { + p = end_of_line(p, ptr, &ellength); + linecount++; + } + + /* It is important to advance lastmatchrestart during this printing so + that it interacts correctly with any "before" printing below. Print + each line's data using fwrite() in case there are binary zeroes. */ + + while (lastmatchrestart < p) + { + char *pp = lastmatchrestart; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", lastmatchnumber++); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); + lastmatchrestart = pp; + } + if (lastmatchrestart != ptr) hyphenpending = TRUE; + } + + /* If there were non-contiguous lines printed above, insert hyphens. */ + + if (hyphenpending) + { + fprintf(stdout, "--\n"); + hyphenpending = FALSE; + hyphenprinted = TRUE; + } + + /* See if there is a requirement to print some "before" lines for this + match. Again, don't print overlaps. */ + + if (before_context > 0) + { + int linecount = 0; + char *p = ptr; + + while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && + linecount < before_context) + { + linecount++; + p = previous_line(p, main_buffer); + } + + if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) + fprintf(stdout, "--\n"); + + while (p < ptr) + { + int ellength; + char *pp = p; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", linenumber - linecount--); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(p, 1, pp - p, stdout); + p = pp; + } + } + + /* Now print the matching line(s); ensure we set hyphenpending at the end + of the file if any context lines are being output. */ + + if (after_context > 0 || before_context > 0) + endhyphenpending = TRUE; + + if (printname != NULL) fprintf(stdout, "%s:", printname); + if (number) fprintf(stdout, "%d:", linenumber); + + /* In multiline mode, we want to print to the end of the line in which + the end of the matched string is found, so we adjust linelength and the + line number appropriately, but only when there actually was a match + (invert not set). Because the PCRE2_FIRSTLINE option is set, the start of + the match will always be before the first newline sequence. */ + + if (multiline & !invert) + { + char *endmatch = ptr + offsets[1]; + t = ptr; + while (t <= endmatch) + { + t = end_of_line(t, endptr, &endlinelength); + if (t < endmatch) linenumber++; else break; + } + linelength = t - ptr - endlinelength; + } + + /*** NOTE: Use only fwrite() to output the data line, so that binary + zeroes are treated as just another data character. */ + + /* This extra option, for Jeffrey Friedl's debugging requirements, + replaces the matched string, or a specific captured string if it exists, + with X. When this happens, colouring is ignored. */ + +#ifdef JFRIEDL_DEBUG + if (S_arg >= 0 && S_arg < mrc) + { + int first = S_arg * 2; + int last = first + 1; + FWRITE(ptr, 1, offsets[first], stdout); + fprintf(stdout, "X"); + FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout); + } + else +#endif + + /* We have to split the line(s) up if colouring, and search for further + matches, but not of course if the line is a non-match. */ + + if (do_colour && !invert) + { + int plength; + FWRITE(ptr, 1, offsets[0], stdout); + fprintf(stdout, "%c[%sm", 0x1b, colour_string); + FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); + fprintf(stdout, "%c[00m", 0x1b); + for (;;) + { + startoffset = offsets[1]; + if (startoffset >= linelength + endlinelength || + !match_patterns(matchptr, length, options, startoffset, &mrc)) + break; + FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout); + fprintf(stdout, "%c[%sm", 0x1b, colour_string); + FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout); + fprintf(stdout, "%c[00m", 0x1b); + } + + /* In multiline mode, we may have already printed the complete line + and its line-ending characters (if they matched the pattern), so there + may be no more to print. */ + + plength = (int)((linelength + endlinelength) - startoffset); + if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout); + } + + /* Not colouring; no need to search for further matches */ + + else FWRITE(ptr, 1, linelength + endlinelength, stdout); + } + + /* End of doing what has to be done for a match. If --line-buffered was + given, flush the output. */ + + if (line_buffered) fflush(stdout); + rc = 0; /* Had some success */ + + /* Remember where the last match happened for after_context. We remember + where we are about to restart, and that line's number. */ + + lastmatchrestart = ptr + linelength + endlinelength; + lastmatchnumber = linenumber + 1; + } + + /* For a match in multiline inverted mode (which of course did not cause + anything to be printed), we have to move on to the end of the match before + proceeding. */ + + if (multiline && invert && match) + { + int ellength; + char *endmatch = ptr + offsets[1]; + t = ptr; + while (t < endmatch) + { + t = end_of_line(t, endptr, &ellength); + if (t <= endmatch) linenumber++; else break; + } + endmatch = end_of_line(endmatch, endptr, &ellength); + linelength = endmatch - ptr - ellength; + } + + /* Advance to after the newline and increment the line number. The file + offset to the current line is maintained in filepos. */ + + END_ONE_MATCH: + ptr += linelength + endlinelength; + filepos += (int)(linelength + endlinelength); + linenumber++; + + /* If input is line buffered, and the buffer is not yet full, read another + line and add it into the buffer. */ + + if (input_line_buffered && bufflength < (size_t)bufsize) + { + int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in); + bufflength += add; + endptr += add; + } + + /* If we haven't yet reached the end of the file (the buffer is full), and + the current point is in the top 1/3 of the buffer, slide the buffer down by + 1/3 and refill it. Before we do this, if some unprinted "after" lines are + about to be lost, print them. */ + + if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird) + { + if (after_context > 0 && + lastmatchnumber > 0 && + lastmatchrestart < main_buffer + bufthird) + { + do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); + lastmatchnumber = 0; + } + + /* Now do the shuffle */ + + memmove(main_buffer, main_buffer + bufthird, 2*bufthird); + ptr -= bufthird; + +#ifdef SUPPORT_LIBZ + if (frtype == FR_LIBZ) + bufflength = 2*bufthird + + gzread (ingz, main_buffer + 2*bufthird, bufthird); + else +#endif + +#ifdef SUPPORT_LIBBZ2 + if (frtype == FR_LIBBZ2) + bufflength = 2*bufthird + + BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird); + else +#endif + + bufflength = 2*bufthird + + (input_line_buffered? + read_one_line(main_buffer + 2*bufthird, bufthird, in) : + fread(main_buffer + 2*bufthird, 1, bufthird, in)); + endptr = main_buffer + bufflength; + + /* Adjust any last match point */ + + if (lastmatchnumber > 0) lastmatchrestart -= bufthird; + } + } /* Loop through the whole file */ + +/* End of file; print final "after" lines if wanted; do_after_lines sets +hyphenpending if it prints something. */ + +if (!show_only_matching && !count_only) + { + do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); + hyphenpending |= endhyphenpending; + } + +/* Print the file name if we are looking for those without matches and there +were none. If we found a match, we won't have got this far. */ + +if (filenames == FN_NOMATCH_ONLY) + { + fprintf(stdout, "%s\n", printname); + return 0; + } + +/* Print the match count if wanted */ + +if (count_only && !quiet) + { + if (count > 0 || !omit_zero_count) + { + if (printname != NULL && filenames != FN_NONE) + fprintf(stdout, "%s:", printname); + fprintf(stdout, "%d\n", count); + } + } + +return rc; +} + + + +/************************************************* +* Grep a file or recurse into a directory * +*************************************************/ + +/* Given a path name, if it's a directory, scan all the files if we are +recursing; if it's a file, grep it. + +Arguments: + pathname the path to investigate + dir_recurse TRUE if recursing is wanted (-r or -drecurse) + only_one_at_top TRUE if the path is the only one at toplevel + +Returns: -1 the file/directory was skipped + 0 if there was at least one match + 1 if there were no matches + 2 there was some kind of error + +However, file opening failures are suppressed if "silent" is set. +*/ + +static int +grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top) +{ +int rc = 1; +int frtype; +void *handle; +char *lastcomp; +FILE *in = NULL; /* Ensure initialized */ + +#ifdef SUPPORT_LIBZ +gzFile ingz = NULL; +#endif + +#ifdef SUPPORT_LIBBZ2 +BZFILE *inbz2 = NULL; +#endif + +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 +int pathlen; +#endif + +#if defined NATIVE_ZOS +int zos_type; +FILE *zos_test_file; +#endif + +/* If the file name is "-" we scan stdin */ + +if (strcmp(pathname, "-") == 0) + { + return pcre2grep(stdin, FR_PLAIN, stdin_name, + (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? + stdin_name : NULL); + } + +/* Inclusion and exclusion: --include-dir and --exclude-dir apply only to +directories, whereas --include and --exclude apply to everything else. The test +is against the final component of the path. */ + +lastcomp = strrchr(pathname, FILESEP); +lastcomp = (lastcomp == NULL)? pathname : lastcomp + 1; + +/* If the file is a directory, skip if not recursing or if explicitly excluded. +Otherwise, scan the directory and recurse for each path within it. The scanning +code is localized so it can be made system-specific. */ + + +/* For z/OS, determine the file type. */ + +#if defined NATIVE_ZOS +zos_test_file = fopen(pathname,"rb"); + +if (zos_test_file == NULL) + { + if (!silent) fprintf(stderr, "pcre2grep: failed to test next file %s\n", + pathname, strerror(errno)); + return -1; + } +zos_type = identifyzosfiletype (zos_test_file); +fclose (zos_test_file); + +/* Handle a PDS in separate code */ + +if (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE) + { + return travelonpdsdir (pathname, only_one_at_top); + } + +/* Deal with regular files in the normal way below. These types are: + zos_type == __ZOS_PDS_MEMBER + zos_type == __ZOS_PS + zos_type == __ZOS_VSAM_KSDS + zos_type == __ZOS_VSAM_ESDS + zos_type == __ZOS_VSAM_RRDS +*/ + +/* Handle a z/OS directory using common code. */ + +else if (zos_type == __ZOS_HFS) + { +#endif /* NATIVE_ZOS */ + + +/* Handle directories: common code for all OS */ + +if (isdirectory(pathname)) + { + if (dee_action == dee_SKIP || + !test_incexc(lastcomp, include_dir_patterns, exclude_dir_patterns)) + return -1; + + if (dee_action == dee_RECURSE) + { + char buffer[1024]; + char *nextfile; + directory_type *dir = opendirectory(pathname); + + if (dir == NULL) + { + if (!silent) + fprintf(stderr, "pcre2grep: Failed to open directory %s: %s\n", pathname, + strerror(errno)); + return 2; + } + + while ((nextfile = readdirectory(dir)) != NULL) + { + int frc; + sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile); + frc = grep_or_recurse(buffer, dir_recurse, FALSE); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + + closedirectory(dir); + return rc; + } + } + +#if defined NATIVE_ZOS + } +#endif + +/* If the file is not a directory, check for a regular file, and if it is not, +skip it if that's been requested. Otherwise, check for an explicit inclusion or +exclusion. */ + +else if ( +#if defined NATIVE_ZOS + (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) || +#else /* all other OS */ + (!isregfile(pathname) && DEE_action == DEE_SKIP) || +#endif + !test_incexc(lastcomp, include_patterns, exclude_patterns)) + return -1; /* File skipped */ + +/* Control reaches here if we have a regular file, or if we have a directory +and recursion or skipping was not requested, or if we have anything else and +skipping was not requested. The scan proceeds. If this is the first and only +argument at top level, we don't show the file name, unless we are only showing +the file name, or the filename was forced (-H). */ + +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 +pathlen = (int)(strlen(pathname)); +#endif + +/* Open using zlib if it is supported and the file name ends with .gz. */ + +#ifdef SUPPORT_LIBZ +if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0) + { + ingz = gzopen(pathname, "rb"); + if (ingz == NULL) + { + if (!silent) + fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname, + strerror(errno)); + return 2; + } + handle = (void *)ingz; + frtype = FR_LIBZ; + } +else +#endif + +/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */ + +#ifdef SUPPORT_LIBBZ2 +if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0) + { + inbz2 = BZ2_bzopen(pathname, "rb"); + handle = (void *)inbz2; + frtype = FR_LIBBZ2; + } +else +#endif + +/* Otherwise use plain fopen(). The label is so that we can come back here if +an attempt to read a .bz2 file indicates that it really is a plain file. */ + +#ifdef SUPPORT_LIBBZ2 +PLAIN_FILE: +#endif + { + in = fopen(pathname, "rb"); + handle = (void *)in; + frtype = FR_PLAIN; + } + +/* All the opening methods return errno when they fail. */ + +if (handle == NULL) + { + if (!silent) + fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname, + strerror(errno)); + return 2; + } + +/* Now grep the file */ + +rc = pcre2grep(handle, frtype, pathname, (filenames > FN_DEFAULT || + (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); + +/* Close in an appropriate manner. */ + +#ifdef SUPPORT_LIBZ +if (frtype == FR_LIBZ) + gzclose(ingz); +else +#endif + +/* If it is a .bz2 file and the result is 3, it means that the first attempt to +read failed. If the error indicates that the file isn't in fact bzipped, try +again as a normal file. */ + +#ifdef SUPPORT_LIBBZ2 +if (frtype == FR_LIBBZ2) + { + if (rc == 3) + { + int errnum; + const char *err = BZ2_bzerror(inbz2, &errnum); + if (errnum == BZ_DATA_ERROR_MAGIC) + { + BZ2_bzclose(inbz2); + goto PLAIN_FILE; + } + else if (!silent) + fprintf(stderr, "pcre2grep: Failed to read %s using bzlib: %s\n", + pathname, err); + rc = 2; /* The normal "something went wrong" code */ + } + BZ2_bzclose(inbz2); + } +else +#endif + +/* Normal file close */ + +fclose(in); + +/* Pass back the yield from pcre2grep(). */ + +return rc; +} + + + +/************************************************* +* Handle a single-letter, no data option * +*************************************************/ + +static int +handle_option(int letter, int options) +{ +switch(letter) + { + case N_FOFFSETS: file_offsets = TRUE; break; + case N_HELP: help(); pcre2grep_exit(0); + case N_LBUFFER: line_buffered = TRUE; break; + case N_LOFFSETS: line_offsets = number = TRUE; break; + case N_NOJIT: use_jit = FALSE; break; + case 'a': binary_files = BIN_TEXT; break; + case 'c': count_only = TRUE; break; + case 'F': process_options |= PO_FIXED_STRINGS; break; + case 'H': filenames = FN_FORCE; break; + case 'I': binary_files = BIN_NOMATCH; break; + case 'h': filenames = FN_NONE; break; + case 'i': options |= PCRE2_CASELESS; break; + case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break; + case 'L': filenames = FN_NOMATCH_ONLY; break; + case 'M': multiline = TRUE; options |= PCRE2_MULTILINE|PCRE2_FIRSTLINE; break; + case 'n': number = TRUE; break; + + case 'o': + only_matching_last = add_number(0, only_matching_last); + if (only_matching == NULL) only_matching = only_matching_last; + break; + + case 'q': quiet = TRUE; break; + case 'r': dee_action = dee_RECURSE; break; + case 's': silent = TRUE; break; + case 'u': options |= PCRE2_UTF; utf = TRUE; break; + case 'v': invert = TRUE; break; + case 'w': process_options |= PO_WORD_MATCH; break; + case 'x': process_options |= PO_LINE_MATCH; break; + + case 'V': + { + unsigned char buffer[128]; + (void)pcre2_config(PCRE2_CONFIG_VERSION, buffer); + fprintf(stdout, "pcre2grep version %s\n", buffer); + } + pcre2grep_exit(0); + break; + + default: + fprintf(stderr, "pcre2grep: Unknown option -%c\n", letter); + pcre2grep_exit(usage(2)); + } + +return options; +} + + + + +/************************************************* +* Construct printed ordinal * +*************************************************/ + +/* This turns a number into "1st", "3rd", etc. */ + +static char * +ordin(int n) +{ +static char buffer[14]; +char *p = buffer; +sprintf(p, "%d", n); +while (*p != 0) p++; +switch (n%10) + { + case 1: strcpy(p, "st"); break; + case 2: strcpy(p, "nd"); break; + case 3: strcpy(p, "rd"); break; + default: strcpy(p, "th"); break; + } +return buffer; +} + + + +/************************************************* +* Compile a single pattern * +*************************************************/ + +/* Do nothing if the pattern has already been compiled. This is the case for +include/exclude patterns read from a file. + +When the -F option has been used, each "pattern" may be a list of strings, +separated by line breaks. They will be matched literally. We split such a +string and compile the first substring, inserting an additional block into the +pattern chain. + +Arguments: + p points to the pattern block + options the PCRE options + popts the processing options + fromfile TRUE if the pattern was read from a file + fromtext file name or identifying text (e.g. "include") + count 0 if this is the only command line pattern, or + number of the command line pattern, or + linenumber for a pattern from a file + +Returns: TRUE on success, FALSE after an error +*/ + +static BOOL +compile_pattern(patstr *p, int options, int popts, int fromfile, + const char *fromtext, int count) +{ +unsigned char buffer[PATBUFSIZE]; +PCRE2_SIZE erroffset; +char *ps = p->string; +unsigned int patlen = strlen(ps); +int errcode; + +if (p->compiled != NULL) return TRUE; + +if ((popts & PO_FIXED_STRINGS) != 0) + { + int ellength; + char *eop = ps + patlen; + char *pe = end_of_line(ps, eop, &ellength); + + if (ellength != 0) + { + if (add_pattern(pe, p) == NULL) return FALSE; + patlen = (int)(pe - ps - ellength); + } + } + +sprintf((char *)buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]); +p->compiled = pcre2_compile(buffer, -1, options, &errcode, &erroffset, + compile_context); +if (p->compiled != NULL) return TRUE; + +/* Handle compile errors */ + +erroffset -= (int)strlen(prefix[popts]); +if (erroffset > patlen) erroffset = patlen; +pcre2_get_error_message(errcode, buffer, PATBUFSIZE); + +if (fromfile) + { + fprintf(stderr, "pcre2grep: Error in regex in line %d of %s " + "at offset %d: %s\n", count, fromtext, (int)erroffset, buffer); + } +else + { + if (count == 0) + fprintf(stderr, "pcre2grep: Error in %s regex at offset %d: %s\n", + fromtext, (int)erroffset, buffer); + else + fprintf(stderr, "pcre2grep: Error in %s %s regex at offset %d: %s\n", + ordin(count), fromtext, (int)erroffset, buffer); + } + +return FALSE; +} + + + +/************************************************* +* Read and compile a file of patterns * +*************************************************/ + +/* This is used for --filelist, --include-from, and --exclude-from. + +Arguments: + name the name of the file; "-" is stdin + patptr pointer to the pattern chain anchor + patlastptr pointer to the last pattern pointer + popts the process options to pass to pattern_compile() + +Returns: TRUE if all went well +*/ + +static BOOL +read_pattern_file(char *name, patstr **patptr, patstr **patlastptr, int popts) +{ +int linenumber = 0; +FILE *f; +char *filename; +char buffer[PATBUFSIZE]; + +if (strcmp(name, "-") == 0) + { + f = stdin; + filename = stdin_name; + } +else + { + f = fopen(name, "r"); + if (f == NULL) + { + fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", name, strerror(errno)); + return FALSE; + } + filename = name; + } + +while (fgets(buffer, PATBUFSIZE, f) != NULL) + { + char *s = buffer + (int)strlen(buffer); + while (s > buffer && isspace((unsigned char)(s[-1]))) s--; + *s = 0; + linenumber++; + if (buffer[0] == 0) continue; /* Skip blank lines */ + + /* Note: this call to add_pattern() puts a pointer to the local variable + "buffer" into the pattern chain. However, that pointer is used only when + compiling the pattern, which happens immediately below, so we flatten it + afterwards, as a precaution against any later code trying to use it. */ + + *patlastptr = add_pattern(buffer, *patlastptr); + if (*patlastptr == NULL) + { + if (f != stdin) fclose(f); + return FALSE; + } + if (*patptr == NULL) *patptr = *patlastptr; + + /* This loop is needed because compiling a "pattern" when -F is set may add + on additional literal patterns if the original contains a newline. In the + common case, it never will, because fgets() stops at a newline. However, + the -N option can be used to give pcre2grep a different newline setting. */ + + for(;;) + { + if (!compile_pattern(*patlastptr, pcre2_options, popts, TRUE, filename, + linenumber)) + { + if (f != stdin) fclose(f); + return FALSE; + } + (*patlastptr)->string = NULL; /* Insurance */ + if ((*patlastptr)->next == NULL) break; + *patlastptr = (*patlastptr)->next; + } + } + +if (f != stdin) fclose(f); +return TRUE; +} + + + +/************************************************* +* Main program * +*************************************************/ + +/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */ + +int +main(int argc, char **argv) +{ +int i, j; +int rc = 1; +BOOL only_one_at_top; +patstr *cp; +fnstr *fn; +const char *locale_from = "--locale"; + +#ifdef SUPPORT_PCRE2GREP_JIT +pcre2_jit_stack *jit_stack = NULL; +#endif + +/* Set up a default compile and match contexts and a match data block. */ + +compile_context = pcre2_compile_context_create(NULL); +match_context = pcre2_match_context_create(NULL); +match_data = pcre2_match_data_create(OFFSET_SIZE, NULL); +offsets = pcre2_get_ovector_pointer(match_data); + +/* Process the options */ + +for (i = 1; i < argc; i++) + { + option_item *op = NULL; + char *option_data = (char *)""; /* default to keep compiler happy */ + BOOL longop; + BOOL longopwasequals = FALSE; + + if (argv[i][0] != '-') break; + + /* If we hit an argument that is just "-", it may be a reference to STDIN, + but only if we have previously had -e or -f to define the patterns. */ + + if (argv[i][1] == 0) + { + if (pattern_files != NULL || patterns != NULL) break; + else pcre2grep_exit(usage(2)); + } + + /* Handle a long name option, or -- to terminate the options */ + + if (argv[i][1] == '-') + { + char *arg = argv[i] + 2; + char *argequals = strchr(arg, '='); + + if (*arg == 0) /* -- terminates options */ + { + i++; + break; /* out of the options-handling loop */ + } + + longop = TRUE; + + /* Some long options have data that follows after =, for example file=name. + Some options have variations in the long name spelling: specifically, we + allow "regexp" because GNU grep allows it, though I personally go along + with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p". + These options are entered in the table as "regex(p)". Options can be in + both these categories. */ + + for (op = optionlist; op->one_char != 0; op++) + { + char *opbra = strchr(op->long_name, '('); + char *equals = strchr(op->long_name, '='); + + /* Handle options with only one spelling of the name */ + + if (opbra == NULL) /* Does not contain '(' */ + { + if (equals == NULL) /* Not thing=data case */ + { + if (strcmp(arg, op->long_name) == 0) break; + } + else /* Special case xxx=data */ + { + int oplen = (int)(equals - op->long_name); + int arglen = (argequals == NULL)? + (int)strlen(arg) : (int)(argequals - arg); + if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0) + { + option_data = arg + arglen; + if (*option_data == '=') + { + option_data++; + longopwasequals = TRUE; + } + break; + } + } + } + + /* Handle options with an alternate spelling of the name */ + + else + { + char buff1[24]; + char buff2[24]; + + int baselen = (int)(opbra - op->long_name); + int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1); + int arglen = (argequals == NULL || equals == NULL)? + (int)strlen(arg) : (int)(argequals - arg); + + sprintf(buff1, "%.*s", baselen, op->long_name); + sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1); + + if (strncmp(arg, buff1, arglen) == 0 || + strncmp(arg, buff2, arglen) == 0) + { + if (equals != NULL && argequals != NULL) + { + option_data = argequals; + if (*option_data == '=') + { + option_data++; + longopwasequals = TRUE; + } + } + break; + } + } + } + + if (op->one_char == 0) + { + fprintf(stderr, "pcre2grep: Unknown option %s\n", argv[i]); + pcre2grep_exit(usage(2)); + } + } + + /* Jeffrey Friedl's debugging harness uses these additional options which + are not in the right form for putting in the option table because they use + only one hyphen, yet are more than one character long. By putting them + separately here, they will not get displayed as part of the help() output, + but I don't think Jeffrey will care about that. */ + +#ifdef JFRIEDL_DEBUG + else if (strcmp(argv[i], "-pre") == 0) { + jfriedl_prefix = argv[++i]; + continue; + } else if (strcmp(argv[i], "-post") == 0) { + jfriedl_postfix = argv[++i]; + continue; + } else if (strcmp(argv[i], "-XT") == 0) { + sscanf(argv[++i], "%d", &jfriedl_XT); + continue; + } else if (strcmp(argv[i], "-XR") == 0) { + sscanf(argv[++i], "%d", &jfriedl_XR); + continue; + } +#endif + + + /* One-char options; many that have no data may be in a single argument; we + continue till we hit the last one or one that needs data. */ + + else + { + char *s = argv[i] + 1; + longop = FALSE; + + while (*s != 0) + { + for (op = optionlist; op->one_char != 0; op++) + { + if (*s == op->one_char) break; + } + if (op->one_char == 0) + { + fprintf(stderr, "pcre2grep: Unknown option letter '%c' in \"%s\"\n", + *s, argv[i]); + pcre2grep_exit(usage(2)); + } + + option_data = s+1; + + /* Break out if this is the last character in the string; it's handled + below like a single multi-char option. */ + + if (*option_data == 0) break; + + /* Check for a single-character option that has data: OP_OP_NUMBER(S) + are used for ones that either have a numerical number or defaults, i.e. + the data is optional. If a digit follows, there is data; if not, carry on + with other single-character options in the same string. */ + + if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS) + { + if (isdigit((unsigned char)s[1])) break; + } + else /* Check for an option with data */ + { + if (op->type != OP_NODATA) break; + } + + /* Handle a single-character option with no data, then loop for the + next character in the string. */ + + pcre2_options = handle_option(*s++, pcre2_options); + } + } + + /* At this point we should have op pointing to a matched option. If the type + is NO_DATA, it means that there is no data, and the option might set + something in the PCRE options. */ + + if (op->type == OP_NODATA) + { + pcre2_options = handle_option(op->one_char, pcre2_options); + continue; + } + + /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that + either has a value or defaults to something. It cannot have data in a + separate item. At the moment, the only such options are "colo(u)r", + "only-matching", and Jeffrey Friedl's special -S debugging option. */ + + if (*option_data == 0 && + (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER || + op->type == OP_OP_NUMBERS)) + { + switch (op->one_char) + { + case N_COLOUR: + colour_option = (char *)"auto"; + break; + + case 'o': + only_matching_last = add_number(0, only_matching_last); + if (only_matching == NULL) only_matching = only_matching_last; + break; + +#ifdef JFRIEDL_DEBUG + case 'S': + S_arg = 0; + break; +#endif + } + continue; + } + + /* Otherwise, find the data string for the option. */ + + if (*option_data == 0) + { + if (i >= argc - 1 || longopwasequals) + { + fprintf(stderr, "pcre2grep: Data missing after %s\n", argv[i]); + pcre2grep_exit(usage(2)); + } + option_data = argv[++i]; + } + + /* If the option type is OP_OP_NUMBERS, the value is a number that is to be + added to a chain of numbers. */ + + if (op->type == OP_OP_NUMBERS) + { + unsigned long int n = decode_number(option_data, op, longop); + omdatastr *omd = (omdatastr *)op->dataptr; + *(omd->lastptr) = add_number((int)n, *(omd->lastptr)); + if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr); + } + + /* If the option type is OP_PATLIST, it's the -e option, or one of the + include/exclude options, which can be called multiple times to create lists + of patterns. */ + + else if (op->type == OP_PATLIST) + { + patdatastr *pd = (patdatastr *)op->dataptr; + *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr)); + if (*(pd->lastptr) == NULL) goto EXIT2; + if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr); + } + + /* If the option type is OP_FILELIST, it's one of the options that names a + file. */ + + else if (op->type == OP_FILELIST) + { + fndatastr *fd = (fndatastr *)op->dataptr; + fn = (fnstr *)malloc(sizeof(fnstr)); + if (fn == NULL) + { + fprintf(stderr, "pcre2grep: malloc failed\n"); + goto EXIT2; + } + fn->next = NULL; + fn->name = option_data; + if (*(fd->anchor) == NULL) + *(fd->anchor) = fn; + else + (*(fd->lastptr))->next = fn; + *(fd->lastptr) = fn; + } + + /* Handle OP_BINARY_FILES */ + + else if (op->type == OP_BINFILES) + { + if (strcmp(option_data, "binary") == 0) + binary_files = BIN_BINARY; + else if (strcmp(option_data, "without-match") == 0) + binary_files = BIN_NOMATCH; + else if (strcmp(option_data, "text") == 0) + binary_files = BIN_TEXT; + else + { + fprintf(stderr, "pcre2grep: unknown value \"%s\" for binary-files\n", + option_data); + pcre2grep_exit(usage(2)); + } + } + + /* Otherwise, deal with a single string or numeric data value. */ + + else if (op->type != OP_NUMBER && op->type != OP_U32NUMBER && + op->type != OP_OP_NUMBER) + { + *((char **)op->dataptr) = option_data; + } + else + { + unsigned long int n = decode_number(option_data, op, longop); + if (op->type == OP_U32NUMBER) *((uint32_t *)op->dataptr) = n; + else *((int *)op->dataptr) = n; + } + } + +/* Options have been decoded. If -C was used, its value is used as a default +for -A and -B. */ + +if (both_context > 0) + { + if (after_context == 0) after_context = both_context; + if (before_context == 0) before_context = both_context; + } + +/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. +However, all three set show_only_matching because they display, each in their +own way, only the data that has matched. */ + +if ((only_matching != NULL && (file_offsets || line_offsets)) || + (file_offsets && line_offsets)) + { + fprintf(stderr, "pcre2grep: Cannot mix --only-matching, --file-offsets " + "and/or --line-offsets\n"); + pcre2grep_exit(usage(2)); + } + +/* Put limits into the match data block. */ + +if (match_limit > 0) pcre2_set_match_limit(match_context, match_limit); +if (recursion_limit > 0) pcre2_set_recursion_limit(match_context, recursion_limit); + +if (only_matching != NULL || file_offsets || line_offsets) + show_only_matching = TRUE; + +/* If a locale has not been provided as an option, see if the LC_CTYPE or +LC_ALL environment variable is set, and if so, use it. */ + +if (locale == NULL) + { + locale = getenv("LC_ALL"); + locale_from = "LCC_ALL"; + } + +if (locale == NULL) + { + locale = getenv("LC_CTYPE"); + locale_from = "LC_CTYPE"; + } + +/* If a locale is set, use it to generate the tables the PCRE needs. Passing +NULL to pcre2_maketables() means that malloc() is used to get the memory. */ + +if (locale != NULL) + { + if (setlocale(LC_CTYPE, locale) == NULL) + { + fprintf(stderr, "pcre2grep: Failed to set locale %s (obtained from %s)\n", + locale, locale_from); + goto EXIT2; + } + character_tables = pcre2_maketables(NULL); + pcre2_set_character_tables(compile_context, character_tables); + } + +/* Sort out colouring */ + +if (colour_option != NULL && strcmp(colour_option, "never") != 0) + { + if (strcmp(colour_option, "always") == 0) do_colour = TRUE; + else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty(); + else + { + fprintf(stderr, "pcre2grep: Unknown colour setting \"%s\"\n", + colour_option); + goto EXIT2; + } + if (do_colour) + { + char *cs = getenv("PCRE2GREP_COLOUR"); + if (cs == NULL) cs = getenv("PCRE2GREP_COLOR"); + if (cs != NULL) colour_string = cs; + } + } + +/* Sort out a newline setting. */ + +if (newline_arg != NULL) + { + for (endlinetype = 1; endlinetype < (int)(sizeof(newlines)/sizeof(char *)); + endlinetype++) + { + if (strcmpic(newline_arg, newlines[endlinetype]) == 0) break; + } + if (endlinetype < (int)(sizeof(newlines)/sizeof(char *))) + pcre2_set_newline(compile_context, endlinetype); + else + { + fprintf(stderr, "pcre2grep: Invalid newline specifier \"%s\"\n", + newline_arg); + goto EXIT2; + } + } + +/* Find default newline convention */ + +else + { + (void)pcre2_config(PCRE2_CONFIG_NEWLINE, &endlinetype); + } + +/* Interpret the text values for -d and -D */ + +if (dee_option != NULL) + { + if (strcmp(dee_option, "read") == 0) dee_action = dee_READ; + else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE; + else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP; + else + { + fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -d\n", dee_option); + goto EXIT2; + } + } + +if (DEE_option != NULL) + { + if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ; + else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP; + else + { + fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -D\n", DEE_option); + goto EXIT2; + } + } + +/* Check the values for Jeffrey Friedl's debugging options. */ + +#ifdef JFRIEDL_DEBUG +if (S_arg > 9) + { + fprintf(stderr, "pcre2grep: bad value for -S option\n"); + return 2; + } +if (jfriedl_XT != 0 || jfriedl_XR != 0) + { + if (jfriedl_XT == 0) jfriedl_XT = 1; + if (jfriedl_XR == 0) jfriedl_XR = 1; + } +#endif + +/* Get memory for the main buffer. */ + +bufsize = 3*bufthird; +main_buffer = (char *)malloc(bufsize); + +if (main_buffer == NULL) + { + fprintf(stderr, "pcre2grep: malloc failed\n"); + goto EXIT2; + } + +/* If no patterns were provided by -e, and there are no files provided by -f, +the first argument is the one and only pattern, and it must exist. */ + +if (patterns == NULL && pattern_files == NULL) + { + if (i >= argc) return usage(2); + patterns = patterns_last = add_pattern(argv[i++], NULL); + if (patterns == NULL) goto EXIT2; + } + +/* Compile the patterns that were provided on the command line, either by +multiple uses of -e or as a single unkeyed pattern. We cannot do this until +after all the command-line options are read so that we know which PCRE options +to use. When -F is used, compile_pattern() may add another block into the +chain, so we must not access the next pointer till after the compile. */ + +for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next) + { + if (!compile_pattern(cp, pcre2_options, process_options, FALSE, "command-line", + (j == 1 && patterns->next == NULL)? 0 : j)) + goto EXIT2; + } + +/* Read and compile the regular expressions that are provided in files. */ + +for (fn = pattern_files; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &patterns, &patterns_last, process_options)) + goto EXIT2; + } + +/* Unless JIT has been explicitly disabled, arrange a stack for it to use. */ + +#ifdef SUPPORT_PCRE2GREP_JIT +if (use_jit) + jit_stack = pcre2_jit_stack_create(32*1024, 1024*1024, NULL); +#endif + +for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next) + { +#ifdef SUPPORT_PCRE2GREP_JIT + if (jit_stack != NULL && cp->compiled != NULL) + pcre2_jit_stack_assign(match_context, NULL, jit_stack); +#endif + } + +/* If there are include or exclude patterns read from the command line, compile +them. -F, -w, and -x do not apply, so the third argument of compile_pattern is +0. */ + +for (j = 0; j < 4; j++) + { + int k; + for (k = 1, cp = *(incexlist[j]); cp != NULL; k++, cp = cp->next) + { + if (!compile_pattern(cp, pcre2_options, 0, FALSE, incexname[j], + (k == 1 && cp->next == NULL)? 0 : k)) + goto EXIT2; + } + } + +/* Read and compile include/exclude patterns from files. */ + +for (fn = include_from; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last, 0)) + goto EXIT2; + } + +for (fn = exclude_from; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last, 0)) + goto EXIT2; + } + +/* If there are no files that contain lists of files to search, and there are +no file arguments, search stdin, and then exit. */ + +if (file_lists == NULL && i >= argc) + { + rc = pcre2grep(stdin, FR_PLAIN, stdin_name, + (filenames > FN_DEFAULT)? stdin_name : NULL); + goto EXIT; + } + +/* If any files that contains a list of files to search have been specified, +read them line by line and search the given files. */ + +for (fn = file_lists; fn != NULL; fn = fn->next) + { + char buffer[PATBUFSIZE]; + FILE *fl; + if (strcmp(fn->name, "-") == 0) fl = stdin; else + { + fl = fopen(fn->name, "rb"); + if (fl == NULL) + { + fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", fn->name, + strerror(errno)); + goto EXIT2; + } + } + while (fgets(buffer, PATBUFSIZE, fl) != NULL) + { + int frc; + char *end = buffer + (int)strlen(buffer); + while (end > buffer && isspace(end[-1])) end--; + *end = 0; + if (*buffer != 0) + { + frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + } + if (fl != stdin) fclose(fl); + } + +/* After handling file-list, work through remaining arguments. Pass in the fact +that there is only one argument at top level - this suppresses the file name if +the argument is not a directory and filenames are not otherwise forced. */ + +only_one_at_top = i == argc - 1 && file_lists == NULL; + +for (; i < argc; i++) + { + int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE, + only_one_at_top); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + +EXIT: +#ifdef SUPPORT_PCRE2GREP_JIT +if (jit_stack != NULL) pcre2_jit_stack_free(jit_stack); +#endif + +free(main_buffer); +free((void *)character_tables); + +pcre2_compile_context_free(compile_context); +pcre2_match_context_free(match_context); +pcre2_match_data_free(match_data); + +free_pattern_chain(patterns); +free_pattern_chain(include_patterns); +free_pattern_chain(include_dir_patterns); +free_pattern_chain(exclude_patterns); +free_pattern_chain(exclude_dir_patterns); + +free_file_chain(exclude_from); +free_file_chain(include_from); +free_file_chain(pattern_files); +free_file_chain(file_lists); + +while (only_matching != NULL) + { + omstr *this = only_matching; + only_matching = this->next; + free(this); + } + +pcre2grep_exit(rc); + +EXIT2: +rc = 2; +goto EXIT; +} + +/* End of pcre2grep */ diff --git a/pcre2/src/pcre2posix.c b/pcre2/src/pcre2posix.c new file mode 100644 index 000000000..1d6e5b797 --- /dev/null +++ b/pcre2/src/pcre2posix.c @@ -0,0 +1,335 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module is a wrapper that provides a POSIX API to the underlying PCRE2 +functions. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +/* Ensure that the PCRE2POSIX_EXP_xxx macros are set appropriately for +compiling these functions. This must come before including pcre2posix.h, where +they are set for an application (using these functions) if they have not +previously been set. */ + +#if defined(_WIN32) && !defined(PCRE2_STATIC) +# define PCRE2POSIX_EXP_DECL extern __declspec(dllexport) +# define PCRE2POSIX_EXP_DEFN __declspec(dllexport) +#endif + +/* We include pcre2.h before pcre2_internal.h so that the PCRE2 library +functions are declared as "import" for Windows by defining PCRE2_EXP_DECL as +"import". This is needed even though pcre2_internal.h itself includes pcre2.h, +because it does so after it has set PCRE2_EXP_DECL to "export" if it is not +already set. */ + +#include "pcre2.h" +#include "pcre2_internal.h" +#include "pcre2posix.h" + +/* Table to translate PCRE2 compile time error codes into POSIX error codes. +Only a few PCRE2 errors with a value greater than 23 turn into special POSIX +codes: most go to REG_BADPAT. The second table lists, in pairs, those that +don't. */ + +static const int eint1[] = { + 0, /* No error */ + REG_EESCAPE, /* \ at end of pattern */ + REG_EESCAPE, /* \c at end of pattern */ + REG_EESCAPE, /* unrecognized character follows \ */ + REG_BADBR, /* numbers out of order in {} quantifier */ + /* 5 */ + REG_BADBR, /* number too big in {} quantifier */ + REG_EBRACK, /* missing terminating ] for character class */ + REG_ECTYPE, /* invalid escape sequence in character class */ + REG_ERANGE, /* range out of order in character class */ + REG_BADRPT, /* nothing to repeat */ + /* 10 */ + REG_ASSERT, /* internal error: unexpected repeat */ + REG_BADPAT, /* unrecognized character after (? or (?- */ + REG_BADPAT, /* POSIX named classes are supported only within a class */ + REG_BADPAT, /* POSIX collating elements are not supported */ + REG_EPAREN, /* missing ) */ + /* 15 */ + REG_ESUBREG, /* reference to non-existent subpattern */ + REG_INVARG, /* pattern passed as NULL */ + REG_INVARG, /* unknown compile-time option bit(s) */ + REG_EPAREN, /* missing ) after (?# comment */ + REG_ESIZE, /* parentheses nested too deeply */ + /* 20 */ + REG_ESIZE, /* regular expression too large */ + REG_ESPACE, /* failed to get memory */ + REG_EPAREN, /* unmatched closing parenthesis */ + REG_ASSERT /* internal error: code overflow */ + }; + +static const int eint2[] = { + 30, REG_ECTYPE, /* unknown POSIX class name */ + 32, REG_INVARG, /* this version of PCRE2 does not have Unicode support */ + 37, REG_EESCAPE, /* PCRE2 does not support \L, \l, \N{name}, \U, or \u */ + 56, REG_INVARG, /* internal error: unknown newline setting */ +}; + +/* Table of texts corresponding to POSIX error codes */ + +static const char *const pstring[] = { + "", /* Dummy for value 0 */ + "internal error", /* REG_ASSERT */ + "invalid repeat counts in {}", /* BADBR */ + "pattern error", /* BADPAT */ + "? * + invalid", /* BADRPT */ + "unbalanced {}", /* EBRACE */ + "unbalanced []", /* EBRACK */ + "collation error - not relevant", /* ECOLLATE */ + "bad class", /* ECTYPE */ + "bad escape sequence", /* EESCAPE */ + "empty expression", /* EMPTY */ + "unbalanced ()", /* EPAREN */ + "bad range inside []", /* ERANGE */ + "expression too big", /* ESIZE */ + "failed to get memory", /* ESPACE */ + "bad back reference", /* ESUBREG */ + "bad argument", /* INVARG */ + "match failed" /* NOMATCH */ +}; + + + + +/************************************************* +* Translate error code to string * +*************************************************/ + +PCRE2POSIX_EXP_DEFN size_t PCRE2_CALL_CONVENTION +regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ +int used; +const char *message; + +message = (errcode <= 0 || errcode >= (int)(sizeof(pstring)/sizeof(char *)))? + "unknown error code" : pstring[errcode]; + +if (preg != NULL && (int)preg->re_erroffset != -1) + { + used = snprintf(errbuf, errbuf_size, "%s at offset %-6d", message, + (int)preg->re_erroffset); + } +else + { + used = snprintf(errbuf, errbuf_size, "%s", message); + } + +return used + 1; +} + + + + +/************************************************* +* Free store held by a regex * +*************************************************/ + +PCRE2POSIX_EXP_DEFN void PCRE2_CALL_CONVENTION +regfree(regex_t *preg) +{ +pcre2_match_data_free(preg->re_match_data); +pcre2_code_free(preg->re_pcre2_code); +} + + + + +/************************************************* +* Compile a regular expression * +*************************************************/ + +/* +Arguments: + preg points to a structure for recording the compiled expression + pattern the pattern to compile + cflags compilation flags + +Returns: 0 on success + various non-zero codes on failure +*/ + +PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION +regcomp(regex_t *preg, const char *pattern, int cflags) +{ +PCRE2_SIZE erroffset; +int errorcode; +int options = 0; +int re_nsub = 0; + +if ((cflags & REG_ICASE) != 0) options |= PCRE2_CASELESS; +if ((cflags & REG_NEWLINE) != 0) options |= PCRE2_MULTILINE; +if ((cflags & REG_DOTALL) != 0) options |= PCRE2_DOTALL; +if ((cflags & REG_NOSUB) != 0) options |= PCRE2_NO_AUTO_CAPTURE; +if ((cflags & REG_UTF) != 0) options |= PCRE2_UTF; +if ((cflags & REG_UCP) != 0) options |= PCRE2_UCP; +if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY; + +preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, + options, &errorcode, &erroffset, NULL); +preg->re_erroffset = erroffset; + +if (preg->re_pcre2_code == NULL) + { + unsigned int i; + + /* A negative value is a UTF error; otherwise all error codes are greater + than COMPILE_ERROR_BASE, but check, just in case. */ + + if (errorcode < COMPILE_ERROR_BASE) return REG_BADPAT; + errorcode -= COMPILE_ERROR_BASE; + + if (errorcode < (int)(sizeof(eint1)/sizeof(const int))) + return eint1[errorcode]; + for (i = 0; i < sizeof(eint2)/(2*sizeof(const int)); i += 2) + if (errorcode == eint2[i]) return eint2[i+1]; + return REG_BADPAT; + } + +(void)pcre2_pattern_info((const pcre2_code *)preg->re_pcre2_code, + PCRE2_INFO_CAPTURECOUNT, &re_nsub); +preg->re_nsub = (size_t)re_nsub; +if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) re_nsub = -1; +preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL); + +if (preg->re_match_data == NULL) + { + pcre2_code_free(preg->re_pcre2_code); + return REG_ESPACE; + } + +return 0; +} + + + +/************************************************* +* Match a regular expression * +*************************************************/ + +/* A suitable match_data block, large enough to hold all possible captures, was +obtained when the pattern was compiled, to save having to allocate and free it +for each match. If REG_NOSUB was specified at compile time, the +PCRE_NO_AUTO_CAPTURE flag will be set. When this is the case, the nmatch and +pmatch arguments are ignored, and the only result is yes/no/error. */ + +PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION +regexec(const regex_t *preg, const char *string, size_t nmatch, + regmatch_t pmatch[], int eflags) +{ +int rc, so, eo; +int options = 0; +pcre2_match_data *md = (pcre2_match_data *)preg->re_match_data; + +if ((eflags & REG_NOTBOL) != 0) options |= PCRE2_NOTBOL; +if ((eflags & REG_NOTEOL) != 0) options |= PCRE2_NOTEOL; +if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE2_NOTEMPTY; + +((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ + +/* When no string data is being returned, or no vector has been passed in which +to put it, ensure that nmatch is zero. */ + +if ((((pcre2_real_code *)(preg->re_pcre2_code))->compile_options & + PCRE2_NO_AUTO_CAPTURE) != 0 || pmatch == NULL) nmatch = 0; + +/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings. +The man page from OS X says "REG_STARTEND affects only the location of the +string, not how it is matched". That is why the "so" value is used to bump the +start location rather than being passed as a PCRE2 "starting offset". */ + +if ((eflags & REG_STARTEND) != 0) + { + if (pmatch == NULL) return REG_INVARG; + so = pmatch[0].rm_so; + eo = pmatch[0].rm_eo; + } +else + { + so = 0; + eo = (int)strlen(string); + } + +rc = pcre2_match((const pcre2_code *)preg->re_pcre2_code, + (PCRE2_SPTR)string + so, (eo - so), 0, options, md, NULL); + +/* Successful match */ + +if (rc >= 0) + { + size_t i; + if ((size_t)rc > nmatch) rc = (int)nmatch; + for (i = 0; i < (size_t)rc; i++) + { + pmatch[i].rm_so = md->ovector[i*2]; + pmatch[i].rm_eo = md->ovector[i*2+1]; + } + for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + return 0; + } + +/* Unsuccessful match */ + +if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21) + return REG_INVARG; + +switch(rc) + { + default: return REG_ASSERT; + case PCRE2_ERROR_BADMODE: return REG_INVARG; + case PCRE2_ERROR_BADMAGIC: return REG_INVARG; + case PCRE2_ERROR_BADOPTION: return REG_INVARG; + case PCRE2_ERROR_BADUTFOFFSET: return REG_INVARG; + case PCRE2_ERROR_MATCHLIMIT: return REG_ESPACE; + case PCRE2_ERROR_NOMATCH: return REG_NOMATCH; + case PCRE2_ERROR_NOMEMORY: return REG_ESPACE; + case PCRE2_ERROR_NULL: return REG_INVARG; + } +} + +/* End of pcre2posix.c */ diff --git a/pcre2/src/pcre2posix.h b/pcre2/src/pcre2posix.h new file mode 100644 index 000000000..44a2fd8ad --- /dev/null +++ b/pcre2/src/pcre2posix.h @@ -0,0 +1,146 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE2 is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* Have to include stdlib.h in order to ensure that size_t is defined. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options, mostly defined by POSIX, but with some extras. */ + +#define REG_ICASE 0x0001 /* Maps to PCRE2_CASELESS */ +#define REG_NEWLINE 0x0002 /* Maps to PCRE2_MULTILINE */ +#define REG_NOTBOL 0x0004 /* Maps to PCRE2_NOTBOL */ +#define REG_NOTEOL 0x0008 /* Maps to PCRE2_NOTEOL */ +#define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE2_DOTALL */ +#define REG_NOSUB 0x0020 /* Maps to PCRE2_NO_AUTO_CAPTURE */ +#define REG_UTF 0x0040 /* NOT defined by POSIX; maps to PCRE2_UTF */ +#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ +#define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE2_NOTEMPTY */ +#define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE2_UNGREEDY */ +#define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE2_UCP */ + +/* This is not used by PCRE2, but by defining it we make it easier +to slot PCRE2 into existing programs that make POSIX calls. */ + +#define REG_EXTENDED 0 + +/* Error values. Not all these are relevant or used by the wrapper. */ + +enum { + REG_ASSERT = 1, /* internal error ? */ + REG_BADBR, /* invalid repeat counts in {} */ + REG_BADPAT, /* pattern error */ + REG_BADRPT, /* ? * + invalid */ + REG_EBRACE, /* unbalanced {} */ + REG_EBRACK, /* unbalanced [] */ + REG_ECOLLATE, /* collation error - not relevant */ + REG_ECTYPE, /* bad class */ + REG_EESCAPE, /* bad escape sequence */ + REG_EMPTY, /* empty expression */ + REG_EPAREN, /* unbalanced () */ + REG_ERANGE, /* bad range inside [] */ + REG_ESIZE, /* expression too big */ + REG_ESPACE, /* failed to get memory */ + REG_ESUBREG, /* bad back reference */ + REG_INVARG, /* bad argument */ + REG_NOMATCH /* match failed */ +}; + + +/* The structure representing a compiled regular expression. */ + +typedef struct { + void *re_pcre2_code; + void *re_match_data; + size_t re_nsub; + size_t re_erroffset; +} regex_t; + +/* The structure in which a captured offset is returned. */ + +typedef int regoff_t; + +typedef struct { + regoff_t rm_so; + regoff_t rm_eo; +} regmatch_t; + +/* When an application links to a PCRE2 DLL in Windows, the symbols that are +imported have to be identified as such. When building PCRE2, the appropriate +export settings are needed, and are set in pcre2posix.c before including this +file. */ + +#if defined(_WIN32) && !defined(PCRE2_STATIC) && !defined(PCRE2POSIX_EXP_DECL) +# define PCRE2POSIX_EXP_DECL extern __declspec(dllimport) +# define PCRE2POSIX_EXP_DEFN __declspec(dllimport) +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE2POSIX_EXP_DECL +# ifdef __cplusplus +# define PCRE2POSIX_EXP_DECL extern "C" +# define PCRE2POSIX_EXP_DEFN extern "C" +# else +# define PCRE2POSIX_EXP_DECL extern +# define PCRE2POSIX_EXP_DEFN extern +# endif +#endif + +/* The functions */ + +PCRE2POSIX_EXP_DECL int regcomp(regex_t *, const char *, int); +PCRE2POSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, + regmatch_t *, int); +PCRE2POSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); +PCRE2POSIX_EXP_DECL void regfree(regex_t *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* End of pcre2posix.h */ diff --git a/pcre2/src/pcre2test.c b/pcre2/src/pcre2test.c new file mode 100644 index 000000000..0a5879e47 --- /dev/null +++ b/pcre2/src/pcre2test.c @@ -0,0 +1,7426 @@ +/************************************************* +* PCRE2 testing program * +*************************************************/ + +/* PCRE2 is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. In 2014 +the API was completely revised and '2' was added to the name, because the old +API, which had lasted for 16 years, could not accommodate new requirements. At +the same time, this testing program was re-designed because its original +hacked-up (non-) design had also run out of steam. + + Written by Philip Hazel + Original code Copyright (c) 1997-2012 University of Cambridge + Rewritten code Copyright (c) 2016 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This program supports testing of the 8-bit, 16-bit, and 32-bit PCRE2 +libraries in a single program, though its input and output are always 8-bit. +It is different from modules such as pcre2_compile.c in the library itself, +which are compiled separately for each code unit width. If two widths are +enabled, for example, pcre2_compile.c is compiled twice. In contrast, +pcre2test.c is compiled only once, and linked with all the enabled libraries. +Therefore, it must not make use of any of the macros from pcre2.h or +pcre2_internal.h that depend on PCRE2_CODE_UNIT_WIDTH. It does, however, make +use of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16, and SUPPORT_PCRE2_32, to ensure that +it references only the enabled library functions. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined NATIVE_ZOS +#include "pcrzoscs.h" +/* That header is not included in the main PCRE2 distribution because other +apparatus is needed to compile pcre2test for z/OS. The header can be found in +the special z/OS distribution, which is available from www.zaconsultants.net or +from www.cbttape.org. */ +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +/* Both libreadline and libedit are optionally supported. The user-supplied +original patch uses readline/readline.h for libedit, but in at least one system +it is installed as editline/readline.h, so the configuration code now looks for +that first, falling back to readline/readline.h. */ + +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) +#if defined(SUPPORT_LIBREADLINE) +#include +#include +#else +#if defined(HAVE_EDITLINE_READLINE_H) +#include +#else +#include +#endif +#endif +#endif + +/* Put the test for interactive input into a macro so that it can be changed if +required for different environments. */ + +#define INTERACTIVE(f) isatty(fileno(f)) + + +/* ---------------------- System-specific definitions ---------------------- */ + +/* A number of things vary for Windows builds. Originally, pcretest opened its +input and output without "b"; then I was told that "b" was needed in some +environments, so it was added for release 5.0 to both the input and output. (It +makes no difference on Unix-like systems.) Later I was told that it is wrong +for the input on Windows. I've now abstracted the modes into macros that are +set here, to make it easier to fiddle with them, and removed "b" from the input +mode under Windows. The BINARY versions are used when saving/restoring compiled +patterns. */ + +#if defined(_WIN32) || defined(WIN32) +#include /* For _setmode() */ +#include /* For _O_BINARY */ +#define INPUT_MODE "r" +#define OUTPUT_MODE "wb" +#define BINARY_INPUT_MODE "rb" +#define BINARY_OUTPUT_MODE "wb" + +#ifndef isatty +#define isatty _isatty /* This is what Windows calls them, I'm told, */ +#endif /* though in some environments they seem to */ + /* be already defined, hence the #ifndefs. */ +#ifndef fileno +#define fileno _fileno +#endif + +/* A user sent this fix for Borland Builder 5 under Windows. */ + +#ifdef __BORLANDC__ +#define _setmode(handle, mode) setmode(handle, mode) +#endif + +/* Not Windows */ + +#else +#include /* These two includes are needed */ +#include /* for setrlimit(). */ +#if defined NATIVE_ZOS /* z/OS uses non-binary I/O */ +#define INPUT_MODE "r" +#define OUTPUT_MODE "w" +#define BINARY_INPUT_MODE "rb" +#define BINARY_OUTPUT_MODE "wb" +#else +#define INPUT_MODE "rb" +#define OUTPUT_MODE "wb" +#define BINARY_INPUT_MODE "rb" +#define BINARY_OUTPUT_MODE "wb" +#endif +#endif + +#ifdef __VMS +#include +void vms_setsymbol( char *, char *, int ); +#endif + +/* ------------------End of system-specific definitions -------------------- */ + +/* Glueing macros that are used in several places below. */ + +#define glue(a,b) a##b +#define G(a,b) glue(a,b) + +/* Miscellaneous parameters and manifests */ + +#ifndef CLOCKS_PER_SEC +#ifdef CLK_TCK +#define CLOCKS_PER_SEC CLK_TCK +#else +#define CLOCKS_PER_SEC 100 +#endif +#endif + +#define CFAIL_UNSET UINT32_MAX /* Unset value for cfail fields */ +#define DFA_WS_DIMENSION 1000 /* Size of DFA workspace */ +#define DEFAULT_OVECCOUNT 15 /* Default ovector count */ +#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */ +#define LOCALESIZE 32 /* Size of locale name */ +#define LOOPREPEAT 500000 /* Default loop count for timing */ +#define PATSTACKSIZE 20 /* Pattern stack for save/restore testing */ +#define REPLACE_MODSIZE 100 /* Field for reading 8-bit replacement */ +#define VERSION_SIZE 64 /* Size of buffer for the version strings */ + +/* Make sure the buffer into which replacement strings are copied is big enough +to hold them as 32-bit code units. */ + +#define REPLACE_BUFFSIZE 1024 /* This is a byte value */ + +/* Execution modes */ + +#define PCRE8_MODE 8 +#define PCRE16_MODE 16 +#define PCRE32_MODE 32 + +/* Processing returns */ + +enum { PR_OK, PR_SKIP, PR_ABEND }; + +/* The macro PRINTABLE determines whether to print an output character as-is or +as a hex value when showing compiled patterns. is We use it in cases when the +locale has not been explicitly changed, so as to get consistent output from +systems that differ in their output from isprint() even in the "C" locale. */ + +#ifdef EBCDIC +#define PRINTABLE(c) ((c) >= 64 && (c) < 255) +#else +#define PRINTABLE(c) ((c) >= 32 && (c) < 127) +#endif + +#define PRINTOK(c) ((locale_tables != NULL)? isprint(c) : PRINTABLE(c)) + +/* We have to include some of the library source files because we need +to use some of the macros, internal structure definitions, and other internal +values - pcre2test has "inside information" compared to an application program +that strictly follows the PCRE2 API. + +Before including pcre2_internal.h we define PRIV so that it does not get +defined therein. This ensures that PRIV names in the included files do not +clash with those in the libraries. Also, although pcre2_internal.h does itself +include pcre2.h, we explicitly include it beforehand, along with pcre2posix.h, +so that the PCRE2_EXP_xxx macros get set appropriately for an application, not +for building the library. */ + +#define PRIV(name) name +#define PCRE2_CODE_UNIT_WIDTH 0 +#include "pcre2.h" +#include "pcre2posix.h" +#include "pcre2_internal.h" + +/* We need access to some of the data tables that PCRE2 uses. Defining +PCRE2_PCRETEST makes some minor changes in the files. The previous definition +of PRIV avoids name clashes. */ + +#define PCRE2_PCRE2TEST +#include "pcre2_tables.c" +#include "pcre2_ucd.c" + +/* 32-bit integer values in the input are read by strtoul() or strtol(). The +check needed for overflow depends on whether long ints are in fact longer than +ints. They are defined not to be shorter. */ + +#if ULONG_MAX > UINT32_MAX +#define U32OVERFLOW(x) (x > UINT32_MAX) +#else +#define U32OVERFLOW(x) (x == UINT32_MAX) +#endif + +#if LONG_MAX > INT32_MAX +#define S32OVERFLOW(x) (x > INT32_MAX || x < INT32_MIN) +#else +#define S32OVERFLOW(x) (x == INT32_MAX || x == INT32_MIN) +#endif + +/* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include +pcre2_intmodedep.h, which is where mode-dependent macros and structures are +defined. We can now include it for each supported code unit width. Because +PCRE2_CODE_UNIT_WIDTH was defined as zero before including pcre2.h, it will +have left PCRE2_SUFFIX defined as a no-op. We must re-define it appropriately +while including these files, and then restore it to a no-op. Because LINK_SIZE +may be changed in 16-bit mode and forced to 1 in 32-bit mode, the order of +these inclusions should not be changed. */ + +#undef PCRE2_SUFFIX +#undef PCRE2_CODE_UNIT_WIDTH + +#ifdef SUPPORT_PCRE2_8 +#define PCRE2_CODE_UNIT_WIDTH 8 +#define PCRE2_SUFFIX(a) G(a,8) +#include "pcre2_intmodedep.h" +#include "pcre2_printint.c" +#undef PCRE2_CODE_UNIT_WIDTH +#undef PCRE2_SUFFIX +#endif /* SUPPORT_PCRE2_8 */ + +#ifdef SUPPORT_PCRE2_16 +#define PCRE2_CODE_UNIT_WIDTH 16 +#define PCRE2_SUFFIX(a) G(a,16) +#include "pcre2_intmodedep.h" +#include "pcre2_printint.c" +#undef PCRE2_CODE_UNIT_WIDTH +#undef PCRE2_SUFFIX +#endif /* SUPPORT_PCRE2_16 */ + +#ifdef SUPPORT_PCRE2_32 +#define PCRE2_CODE_UNIT_WIDTH 32 +#define PCRE2_SUFFIX(a) G(a,32) +#include "pcre2_intmodedep.h" +#include "pcre2_printint.c" +#undef PCRE2_CODE_UNIT_WIDTH +#undef PCRE2_SUFFIX +#endif /* SUPPORT_PCRE2_32 */ + +#define PCRE2_SUFFIX(a) a + +/* We need to be able to check input text for UTF-8 validity, whatever code +widths are actually available, because the input to pcre2test is always in +8-bit code units. So we include the UTF validity checking function for 8-bit +code units. */ + +extern int valid_utf(PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE *); + +#define PCRE2_CODE_UNIT_WIDTH 8 +#undef PCRE2_SPTR +#define PCRE2_SPTR PCRE2_SPTR8 +#include "pcre2_valid_utf.c" +#undef PCRE2_CODE_UNIT_WIDTH +#undef PCRE2_SPTR + +/* If we have 8-bit support, default to it; if there is also 16-or 32-bit +support, it can be selected by a command-line option. If there is no 8-bit +support, there must be 16- or 32-bit support, so default to one of them. The +config function, JIT stack, contexts, and version string are the same in all +modes, so use the form of the first that is available. */ + +#if defined SUPPORT_PCRE2_8 +#define DEFAULT_TEST_MODE PCRE8_MODE +#define VERSION_TYPE PCRE2_UCHAR8 +#define PCRE2_CONFIG pcre2_config_8 +#define PCRE2_JIT_STACK pcre2_jit_stack_8 +#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8 +#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8 +#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8 +#define VERSION_TYPE PCRE2_UCHAR8 + +#elif defined SUPPORT_PCRE2_16 +#define DEFAULT_TEST_MODE PCRE16_MODE +#define VERSION_TYPE PCRE2_UCHAR16 +#define PCRE2_CONFIG pcre2_config_16 +#define PCRE2_JIT_STACK pcre2_jit_stack_16 +#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_16 +#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_16 +#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_16 + +#elif defined SUPPORT_PCRE2_32 +#define DEFAULT_TEST_MODE PCRE32_MODE +#define VERSION_TYPE PCRE2_UCHAR32 +#define PCRE2_CONFIG pcre2_config_32 +#define PCRE2_JIT_STACK pcre2_jit_stack_32 +#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_32 +#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_32 +#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_32 +#endif + +/* ------------- Structure and table for handling #-commands ------------- */ + +typedef struct cmdstruct { + const char *name; + int value; +} cmdstruct; + +enum { CMD_FORBID_UTF, CMD_LOAD, CMD_NEWLINE_DEFAULT, CMD_PATTERN, + CMD_PERLTEST, CMD_POP, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN }; + +static cmdstruct cmdlist[] = { + { "forbid_utf", CMD_FORBID_UTF }, + { "load", CMD_LOAD }, + { "newline_default", CMD_NEWLINE_DEFAULT }, + { "pattern", CMD_PATTERN }, + { "perltest", CMD_PERLTEST }, + { "pop", CMD_POP }, + { "save", CMD_SAVE }, + { "subject", CMD_SUBJECT }}; + +#define cmdlistcount sizeof(cmdlist)/sizeof(cmdstruct) + +/* ------------- Structures and tables for handling modifiers -------------- */ + +/* Table of names for newline types. Must be kept in step with the definitions +of PCRE2_NEWLINE_xx in pcre2.h. */ + +static const char *newlines[] = { + "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" }; + +/* Modifier types and applicability */ + +enum { MOD_CTC, /* Applies to a compile context */ + MOD_CTM, /* Applies to a match context */ + MOD_PAT, /* Applies to a pattern */ + MOD_PATP, /* Ditto, OK for Perl test */ + MOD_DAT, /* Applies to a data line */ + MOD_PD, /* Applies to a pattern or a data line */ + MOD_PDP, /* As MOD_PD, OK for Perl test */ + MOD_PND, /* As MOD_PD, but not for a default pattern */ + MOD_PNDP, /* As MOD_PND, OK for Perl test */ + MOD_CTL, /* Is a control bit */ + MOD_BSR, /* Is a BSR value */ + MOD_IN2, /* Is one or two unsigned integers */ + MOD_INS, /* Is a signed integer */ + MOD_INT, /* Is an unsigned integer */ + MOD_IND, /* Is an unsigned integer, but no value => default */ + MOD_NL, /* Is a newline value */ + MOD_NN, /* Is a number or a name; more than one may occur */ + MOD_OPT, /* Is an option bit */ + MOD_SIZ, /* Is a PCRE2_SIZE value */ + MOD_STR }; /* Is a string */ + +/* Control bits. Some apply to compiling, some to matching, but some can be set +either on a pattern or a data line, so they must all be distinct. There are now +so many of them that they are split into two fields. */ + +#define CTL_AFTERTEXT 0x00000001u +#define CTL_ALLAFTERTEXT 0x00000002u +#define CTL_ALLCAPTURES 0x00000004u +#define CTL_ALLUSEDTEXT 0x00000008u +#define CTL_ALTGLOBAL 0x00000010u +#define CTL_BINCODE 0x00000020u +#define CTL_CALLOUT_CAPTURE 0x00000040u +#define CTL_CALLOUT_INFO 0x00000080u +#define CTL_CALLOUT_NONE 0x00000100u +#define CTL_DFA 0x00000200u +#define CTL_EXPAND 0x00000400u +#define CTL_FINDLIMITS 0x00000800u +#define CTL_FULLBINCODE 0x00001000u +#define CTL_GETALL 0x00002000u +#define CTL_GLOBAL 0x00004000u +#define CTL_HEXPAT 0x00008000u +#define CTL_INFO 0x00010000u +#define CTL_JITFAST 0x00020000u +#define CTL_JITVERIFY 0x00040000u +#define CTL_MARK 0x00080000u +#define CTL_MEMORY 0x00100000u +#define CTL_NULLCONTEXT 0x00200000u +#define CTL_POSIX 0x00400000u +#define CTL_PUSH 0x00800000u +#define CTL_STARTCHAR 0x01000000u +#define CTL_ZERO_TERMINATE 0x02000000u +/* Spare 0x04000000u */ +/* Spare 0x08000000u */ +/* Spare 0x10000000u */ +/* Spare 0x20000000u */ +#define CTL_NL_SET 0x40000000u /* Informational */ +#define CTL_BSR_SET 0x80000000u /* Informational */ + +/* Second control word */ + +#define CTL2_SUBSTITUTE_EXTENDED 0x00000001u +#define CTL2_SUBSTITUTE_OVERFLOW_LENGTH 0x00000002u +#define CTL2_SUBSTITUTE_UNKNOWN_UNSET 0x00000004u +#define CTL2_SUBSTITUTE_UNSET_EMPTY 0x00000008u + +/* Combinations */ + +#define CTL_DEBUG (CTL_FULLBINCODE|CTL_INFO) /* For setting */ +#define CTL_ANYINFO (CTL_DEBUG|CTL_BINCODE|CTL_CALLOUT_INFO) +#define CTL_ANYGLOB (CTL_ALTGLOBAL|CTL_GLOBAL) + +/* These are all the controls that may be set either on a pattern or on a +data line. */ + +#define CTL_ALLPD (CTL_AFTERTEXT|\ + CTL_ALLAFTERTEXT|\ + CTL_ALLCAPTURES|\ + CTL_ALLUSEDTEXT|\ + CTL_ALTGLOBAL|\ + CTL_GLOBAL|\ + CTL_MARK|\ + CTL_MEMORY|\ + CTL_STARTCHAR) + +#define CTL2_ALLPD (CTL2_SUBSTITUTE_EXTENDED|\ + CTL2_SUBSTITUTE_OVERFLOW_LENGTH|\ + CTL2_SUBSTITUTE_UNKNOWN_UNSET|\ + CTL2_SUBSTITUTE_UNSET_EMPTY) + +/* Structures for holding modifier information for patterns and subject strings +(data). Fields containing modifiers that can be set either for a pattern or a +subject must be at the start and in the same order in both cases so that the +same offset in the big table below works for both. */ + +typedef struct patctl { /* Structure for pattern modifiers. */ + uint32_t options; /* Must be in same position as datctl */ + uint32_t control; /* Must be in same position as datctl */ + uint32_t control2; /* Must be in same position as datctl */ + uint8_t replacement[REPLACE_MODSIZE]; /* So must this */ + uint32_t jit; + uint32_t stackguard_test; + uint32_t tables_id; + uint32_t regerror_buffsize; + uint8_t locale[LOCALESIZE]; +} patctl; + +#define MAXCPYGET 10 +#define LENCPYGET 64 + +typedef struct datctl { /* Structure for data line modifiers. */ + uint32_t options; /* Must be in same position as patctl */ + uint32_t control; /* Must be in same position as patctl */ + uint32_t control2; /* Must be in same position as patctl */ + uint8_t replacement[REPLACE_MODSIZE]; /* So must this */ + uint32_t cfail[2]; + int32_t callout_data; + int32_t copy_numbers[MAXCPYGET]; + int32_t get_numbers[MAXCPYGET]; + uint32_t jitstack; + uint32_t oveccount; + uint32_t offset; + uint8_t copy_names[LENCPYGET]; + uint8_t get_names[LENCPYGET]; +} datctl; + +/* Ids for which context to modify. */ + +enum { CTX_PAT, /* Active pattern context */ + CTX_POPPAT, /* Ditto, for a popped pattern */ + CTX_DEFPAT, /* Default pattern context */ + CTX_DAT, /* Active data (match) context */ + CTX_DEFDAT }; /* Default data (match) context */ + +/* Macros to simplify the big table below. */ + +#define CO(name) offsetof(PCRE2_REAL_COMPILE_CONTEXT, name) +#define MO(name) offsetof(PCRE2_REAL_MATCH_CONTEXT, name) +#define PO(name) offsetof(patctl, name) +#define PD(name) PO(name) +#define DO(name) offsetof(datctl, name) + +/* Table of all long-form modifiers. Must be in collating sequence of modifier +name because it is searched by binary chop. */ + +typedef struct modstruct { + const char *name; + uint16_t which; + uint16_t type; + uint32_t value; + PCRE2_SIZE offset; +} modstruct; + +static modstruct modlist[] = { + { "aftertext", MOD_PNDP, MOD_CTL, CTL_AFTERTEXT, PO(control) }, + { "allaftertext", MOD_PNDP, MOD_CTL, CTL_ALLAFTERTEXT, PO(control) }, + { "allcaptures", MOD_PND, MOD_CTL, CTL_ALLCAPTURES, PO(control) }, + { "allow_empty_class", MOD_PAT, MOD_OPT, PCRE2_ALLOW_EMPTY_CLASS, PO(options) }, + { "allusedtext", MOD_PNDP, MOD_CTL, CTL_ALLUSEDTEXT, PO(control) }, + { "alt_bsux", MOD_PAT, MOD_OPT, PCRE2_ALT_BSUX, PO(options) }, + { "alt_circumflex", MOD_PAT, MOD_OPT, PCRE2_ALT_CIRCUMFLEX, PO(options) }, + { "alt_verbnames", MOD_PAT, MOD_OPT, PCRE2_ALT_VERBNAMES, PO(options) }, + { "altglobal", MOD_PND, MOD_CTL, CTL_ALTGLOBAL, PO(control) }, + { "anchored", MOD_PD, MOD_OPT, PCRE2_ANCHORED, PD(options) }, + { "auto_callout", MOD_PAT, MOD_OPT, PCRE2_AUTO_CALLOUT, PO(options) }, + { "bincode", MOD_PAT, MOD_CTL, CTL_BINCODE, PO(control) }, + { "bsr", MOD_CTC, MOD_BSR, 0, CO(bsr_convention) }, + { "callout_capture", MOD_DAT, MOD_CTL, CTL_CALLOUT_CAPTURE, DO(control) }, + { "callout_data", MOD_DAT, MOD_INS, 0, DO(callout_data) }, + { "callout_fail", MOD_DAT, MOD_IN2, 0, DO(cfail) }, + { "callout_info", MOD_PAT, MOD_CTL, CTL_CALLOUT_INFO, PO(control) }, + { "callout_none", MOD_DAT, MOD_CTL, CTL_CALLOUT_NONE, DO(control) }, + { "caseless", MOD_PATP, MOD_OPT, PCRE2_CASELESS, PO(options) }, + { "copy", MOD_DAT, MOD_NN, DO(copy_numbers), DO(copy_names) }, + { "debug", MOD_PAT, MOD_CTL, CTL_DEBUG, PO(control) }, + { "dfa", MOD_DAT, MOD_CTL, CTL_DFA, DO(control) }, + { "dfa_restart", MOD_DAT, MOD_OPT, PCRE2_DFA_RESTART, DO(options) }, + { "dfa_shortest", MOD_DAT, MOD_OPT, PCRE2_DFA_SHORTEST, DO(options) }, + { "dollar_endonly", MOD_PAT, MOD_OPT, PCRE2_DOLLAR_ENDONLY, PO(options) }, + { "dotall", MOD_PATP, MOD_OPT, PCRE2_DOTALL, PO(options) }, + { "dupnames", MOD_PATP, MOD_OPT, PCRE2_DUPNAMES, PO(options) }, + { "expand", MOD_PAT, MOD_CTL, CTL_EXPAND, PO(control) }, + { "extended", MOD_PATP, MOD_OPT, PCRE2_EXTENDED, PO(options) }, + { "find_limits", MOD_DAT, MOD_CTL, CTL_FINDLIMITS, DO(control) }, + { "firstline", MOD_PAT, MOD_OPT, PCRE2_FIRSTLINE, PO(options) }, + { "fullbincode", MOD_PAT, MOD_CTL, CTL_FULLBINCODE, PO(control) }, + { "get", MOD_DAT, MOD_NN, DO(get_numbers), DO(get_names) }, + { "getall", MOD_DAT, MOD_CTL, CTL_GETALL, DO(control) }, + { "global", MOD_PNDP, MOD_CTL, CTL_GLOBAL, PO(control) }, + { "hex", MOD_PAT, MOD_CTL, CTL_HEXPAT, PO(control) }, + { "info", MOD_PAT, MOD_CTL, CTL_INFO, PO(control) }, + { "jit", MOD_PAT, MOD_IND, 7, PO(jit) }, + { "jitfast", MOD_PAT, MOD_CTL, CTL_JITFAST, PO(control) }, + { "jitstack", MOD_DAT, MOD_INT, 0, DO(jitstack) }, + { "jitverify", MOD_PAT, MOD_CTL, CTL_JITVERIFY, PO(control) }, + { "locale", MOD_PAT, MOD_STR, LOCALESIZE, PO(locale) }, + { "mark", MOD_PNDP, MOD_CTL, CTL_MARK, PO(control) }, + { "match_limit", MOD_CTM, MOD_INT, 0, MO(match_limit) }, + { "match_unset_backref", MOD_PAT, MOD_OPT, PCRE2_MATCH_UNSET_BACKREF, PO(options) }, + { "max_pattern_length", MOD_CTC, MOD_SIZ, 0, CO(max_pattern_length) }, + { "memory", MOD_PD, MOD_CTL, CTL_MEMORY, PD(control) }, + { "multiline", MOD_PATP, MOD_OPT, PCRE2_MULTILINE, PO(options) }, + { "never_backslash_c", MOD_PAT, MOD_OPT, PCRE2_NEVER_BACKSLASH_C, PO(options) }, + { "never_ucp", MOD_PAT, MOD_OPT, PCRE2_NEVER_UCP, PO(options) }, + { "never_utf", MOD_PAT, MOD_OPT, PCRE2_NEVER_UTF, PO(options) }, + { "newline", MOD_CTC, MOD_NL, 0, CO(newline_convention) }, + { "no_auto_capture", MOD_PAT, MOD_OPT, PCRE2_NO_AUTO_CAPTURE, PO(options) }, + { "no_auto_possess", MOD_PATP, MOD_OPT, PCRE2_NO_AUTO_POSSESS, PO(options) }, + { "no_dotstar_anchor", MOD_PAT, MOD_OPT, PCRE2_NO_DOTSTAR_ANCHOR, PO(options) }, + { "no_start_optimize", MOD_PATP, MOD_OPT, PCRE2_NO_START_OPTIMIZE, PO(options) }, + { "no_utf_check", MOD_PD, MOD_OPT, PCRE2_NO_UTF_CHECK, PD(options) }, + { "notbol", MOD_DAT, MOD_OPT, PCRE2_NOTBOL, DO(options) }, + { "notempty", MOD_DAT, MOD_OPT, PCRE2_NOTEMPTY, DO(options) }, + { "notempty_atstart", MOD_DAT, MOD_OPT, PCRE2_NOTEMPTY_ATSTART, DO(options) }, + { "noteol", MOD_DAT, MOD_OPT, PCRE2_NOTEOL, DO(options) }, + { "null_context", MOD_PD, MOD_CTL, CTL_NULLCONTEXT, PO(control) }, + { "offset", MOD_DAT, MOD_INT, 0, DO(offset) }, + { "offset_limit", MOD_CTM, MOD_SIZ, 0, MO(offset_limit)}, + { "ovector", MOD_DAT, MOD_INT, 0, DO(oveccount) }, + { "parens_nest_limit", MOD_CTC, MOD_INT, 0, CO(parens_nest_limit) }, + { "partial_hard", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_HARD, DO(options) }, + { "partial_soft", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, + { "ph", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_HARD, DO(options) }, + { "posix", MOD_PAT, MOD_CTL, CTL_POSIX, PO(control) }, + { "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, + { "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) }, + { "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) }, + { "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) }, + { "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) }, + { "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) }, + { "startchar", MOD_PND, MOD_CTL, CTL_STARTCHAR, PO(control) }, + { "startoffset", MOD_DAT, MOD_INT, 0, DO(offset) }, + { "substitute_extended", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_EXTENDED, PO(control2) }, + { "substitute_overflow_length", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_OVERFLOW_LENGTH, PO(control2) }, + { "substitute_unknown_unset", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_UNKNOWN_UNSET, PO(control2) }, + { "substitute_unset_empty", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_UNSET_EMPTY, PO(control2) }, + { "tables", MOD_PAT, MOD_INT, 0, PO(tables_id) }, + { "ucp", MOD_PATP, MOD_OPT, PCRE2_UCP, PO(options) }, + { "ungreedy", MOD_PAT, MOD_OPT, PCRE2_UNGREEDY, PO(options) }, + { "use_offset_limit", MOD_PAT, MOD_OPT, PCRE2_USE_OFFSET_LIMIT, PO(options) }, + { "utf", MOD_PATP, MOD_OPT, PCRE2_UTF, PO(options) }, + { "zero_terminate", MOD_DAT, MOD_CTL, CTL_ZERO_TERMINATE, DO(control) } +}; + +#define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct) + +/* Controls and options that are supported for use with the POSIX interface. */ + +#define POSIX_SUPPORTED_COMPILE_OPTIONS ( \ + PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ + PCRE2_UCP|PCRE2_UTF|PCRE2_UNGREEDY) + +#define POSIX_SUPPORTED_COMPILE_CONTROLS ( \ + CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_POSIX) + +#define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0) + +#define POSIX_SUPPORTED_MATCH_OPTIONS ( \ + PCRE2_NOTBOL|PCRE2_NOTEMPTY|PCRE2_NOTEOL) + +#define POSIX_SUPPORTED_MATCH_CONTROLS (CTL_AFTERTEXT|CTL_ALLAFTERTEXT) +#define POSIX_SUPPORTED_MATCH_CONTROLS2 (0) + +/* Control bits that are not ignored with 'push'. */ + +#define PUSH_SUPPORTED_COMPILE_CONTROLS ( \ + CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \ + CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_BSR_SET|CTL_NL_SET) + +#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (0) + +/* Controls that apply only at compile time with 'push'. */ + +#define PUSH_COMPILE_ONLY_CONTROLS CTL_JITVERIFY +#define PUSH_COMPILE_ONLY_CONTROLS2 (0) + +/* Controls that are forbidden with #pop. */ + +#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_PUSH) + +/* Pattern controls that are mutually exclusive. At present these are all in +the first control word. */ + +static uint32_t exclusive_pat_controls[] = { + CTL_POSIX | CTL_HEXPAT, + CTL_POSIX | CTL_PUSH, + CTL_EXPAND | CTL_HEXPAT }; + +/* Data controls that are mutually exclusive. At present these are all in the +first control word. */ +static uint32_t exclusive_dat_controls[] = { + CTL_ALLUSEDTEXT | CTL_STARTCHAR, + CTL_FINDLIMITS | CTL_NULLCONTEXT }; + +/* Table of single-character abbreviated modifiers. The index field is +initialized to -1, but the first time the modifier is encountered, it is filled +in with the index of the full entry in modlist, to save repeated searching when +processing multiple test items. This short list is searched serially, so its +order does not matter. */ + +typedef struct c1modstruct { + const char *fullname; + uint32_t onechar; + int index; +} c1modstruct; + +static c1modstruct c1modlist[] = { + { "bincode", 'B', -1 }, + { "info", 'I', -1 }, + { "global", 'g', -1 }, + { "caseless", 'i', -1 }, + { "multiline", 'm', -1 }, + { "dotall", 's', -1 }, + { "extended", 'x', -1 } +}; + +#define C1MODLISTCOUNT sizeof(c1modlist)/sizeof(c1modstruct) + +/* Table of arguments for the -C command line option. Use macros to make the +table itself easier to read. */ + +#if defined SUPPORT_PCRE2_8 +#define SUPPORT_8 1 +#endif +#if defined SUPPORT_PCRE2_16 +#define SUPPORT_16 1 +#endif +#if defined SUPPORT_PCRE2_32 +#define SUPPORT_32 1 +#endif + +#ifndef SUPPORT_8 +#define SUPPORT_8 0 +#endif +#ifndef SUPPORT_16 +#define SUPPORT_16 0 +#endif +#ifndef SUPPORT_32 +#define SUPPORT_32 0 +#endif + +#ifdef EBCDIC +#define SUPPORT_EBCDIC 1 +#define EBCDIC_NL CHAR_LF +#else +#define SUPPORT_EBCDIC 0 +#define EBCDIC_NL 0 +#endif + +#ifdef NEVER_BACKSLASH_C +#define BACKSLASH_C 0 +#else +#define BACKSLASH_C 1 +#endif + +typedef struct coptstruct { + const char *name; + uint32_t type; + uint32_t value; +} coptstruct; + +enum { CONF_BSR, + CONF_FIX, + CONF_FIZ, + CONF_INT, + CONF_NL +}; + +static coptstruct coptlist[] = { + { "backslash-C", CONF_FIX, BACKSLASH_C }, + { "bsr", CONF_BSR, PCRE2_CONFIG_BSR }, + { "ebcdic", CONF_FIX, SUPPORT_EBCDIC }, + { "ebcdic-nl", CONF_FIZ, EBCDIC_NL }, + { "jit", CONF_INT, PCRE2_CONFIG_JIT }, + { "linksize", CONF_INT, PCRE2_CONFIG_LINKSIZE }, + { "newline", CONF_NL, PCRE2_CONFIG_NEWLINE }, + { "pcre2-16", CONF_FIX, SUPPORT_16 }, + { "pcre2-32", CONF_FIX, SUPPORT_32 }, + { "pcre2-8", CONF_FIX, SUPPORT_8 }, + { "unicode", CONF_INT, PCRE2_CONFIG_UNICODE } +}; + +#define COPTLISTCOUNT sizeof(coptlist)/sizeof(coptstruct) + +#undef SUPPORT_8 +#undef SUPPORT_16 +#undef SUPPORT_32 +#undef SUPPORT_EBCDIC + + +/* ----------------------- Static variables ------------------------ */ + +static FILE *infile; +static FILE *outfile; + +static const void *last_callout_mark; +static PCRE2_JIT_STACK *jit_stack = NULL; +static size_t jit_stack_size = 0; + +static BOOL first_callout; +static BOOL jit_was_used; +static BOOL restrict_for_perl_test = FALSE; +static BOOL show_memory = FALSE; + +static int code_unit_size; /* Bytes */ +static int jitrc; /* Return from JIT compile */ +static int test_mode = DEFAULT_TEST_MODE; +static int timeit = 0; +static int timeitm = 0; + +clock_t total_compile_time = 0; +clock_t total_jit_compile_time = 0; +clock_t total_match_time = 0; + +static uint32_t dfa_matched; +static uint32_t forbid_utf = 0; +static uint32_t maxlookbehind; +static uint32_t max_oveccount; +static uint32_t callout_count; + +static uint16_t local_newline_default = 0; + +static VERSION_TYPE jittarget[VERSION_SIZE]; +static VERSION_TYPE version[VERSION_SIZE]; +static VERSION_TYPE uversion[VERSION_SIZE]; + +static patctl def_patctl; +static patctl pat_patctl; +static datctl def_datctl; +static datctl dat_datctl; + +static void *patstack[PATSTACKSIZE]; +static int patstacknext = 0; + +#ifdef SUPPORT_PCRE2_8 +static regex_t preg = { NULL, NULL, 0, 0 }; +#endif + +static int *dfa_workspace = NULL; +static const uint8_t *locale_tables = NULL; +static uint8_t locale_name[32]; + +/* We need buffers for building 16/32-bit strings; 8-bit strings don't need +rebuilding, but set up the same naming scheme for use in macros. The "buffer" +buffer is where all input lines are read. Its size is the same as pbuffer8. +Pattern lines are always copied to pbuffer8 for use in callouts, even if they +are actually compiled from pbuffer16 or pbuffer32. */ + +static size_t pbuffer8_size = 50000; /* Initial size, bytes */ +static uint8_t *pbuffer8 = NULL; +static uint8_t *buffer = NULL; + +/* The dbuffer is where all processed data lines are put. In non-8-bit modes it +is cast as needed. For long data lines it grows as necessary. */ + +static size_t dbuffer_size = 1u << 14; /* Initial size, bytes */ +static uint8_t *dbuffer = NULL; + + +/* ---------------- Mode-dependent variables -------------------*/ + +#ifdef SUPPORT_PCRE2_8 +static pcre2_code_8 *compiled_code8; +static pcre2_general_context_8 *general_context8, *general_context_copy8; +static pcre2_compile_context_8 *pat_context8, *default_pat_context8; +static pcre2_match_context_8 *dat_context8, *default_dat_context8; +static pcre2_match_data_8 *match_data8; +#endif + +#ifdef SUPPORT_PCRE2_16 +static pcre2_code_16 *compiled_code16; +static pcre2_general_context_16 *general_context16, *general_context_copy16; +static pcre2_compile_context_16 *pat_context16, *default_pat_context16; +static pcre2_match_context_16 *dat_context16, *default_dat_context16; +static pcre2_match_data_16 *match_data16; +static PCRE2_SIZE pbuffer16_size = 0; /* Set only when needed */ +static uint16_t *pbuffer16 = NULL; +#endif + +#ifdef SUPPORT_PCRE2_32 +static pcre2_code_32 *compiled_code32; +static pcre2_general_context_32 *general_context32, *general_context_copy32; +static pcre2_compile_context_32 *pat_context32, *default_pat_context32; +static pcre2_match_context_32 *dat_context32, *default_dat_context32; +static pcre2_match_data_32 *match_data32; +static PCRE2_SIZE pbuffer32_size = 0; /* Set only when needed */ +static uint32_t *pbuffer32 = NULL; +#endif + + +/* ---------------- Macros that work in all modes ----------------- */ + +#define CAST8VAR(x) CASTVAR(uint8_t *, x) +#define SET(x,y) SETOP(x,y,=) +#define SETPLUS(x,y) SETOP(x,y,+=) +#define strlen8(x) strlen((char *)x) + + +/* ---------------- Mode-dependent, runtime-testing macros ------------------*/ + +/* Define macros for variables and functions that must be selected dynamically +depending on the mode setting (8, 16, 32). These are dependent on which modes +are supported. */ + +#if (defined (SUPPORT_PCRE2_8) + defined (SUPPORT_PCRE2_16) + \ + defined (SUPPORT_PCRE2_32)) >= 2 + +/* ----- All three modes supported ----- */ + +#if defined(SUPPORT_PCRE2_8) && defined(SUPPORT_PCRE2_16) && defined(SUPPORT_PCRE2_32) + +#define CASTFLD(t,a,b) ((test_mode == PCRE8_MODE)? (t)(G(a,8)->b) : \ + (test_mode == PCRE16_MODE)? (t)(G(a,16)->b) : (t)(G(a,32)->b)) + +#define CASTVAR(t,x) ( \ + (test_mode == PCRE8_MODE)? (t)G(x,8) : \ + (test_mode == PCRE16_MODE)? (t)G(x,16) : (t)G(x,32)) + +#define CODE_UNIT(a,b) ( \ + (test_mode == PCRE8_MODE)? (uint32_t)(((PCRE2_SPTR8)(a))[b]) : \ + (test_mode == PCRE16_MODE)? (uint32_t)(((PCRE2_SPTR16)(a))[b]) : \ + (uint32_t)(((PCRE2_SPTR32)(a))[b])) + +#define DATCTXCPY(a,b) \ + if (test_mode == PCRE8_MODE) \ + memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)); \ + else if (test_mode == PCRE16_MODE) \ + memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)); \ + else memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32)) + +#define FLD(a,b) ((test_mode == PCRE8_MODE)? G(a,8)->b : \ + (test_mode == PCRE16_MODE)? G(a,16)->b : G(a,32)->b) + +#define PATCTXCPY(a,b) \ + if (test_mode == PCRE8_MODE) \ + memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)); \ + else if (test_mode == PCRE16_MODE) \ + memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)); \ + else memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32)) + +#define PCHARS(lv, p, offset, len, utf, f) \ + if (test_mode == PCRE32_MODE) \ + lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \ + else if (test_mode == PCRE16_MODE) \ + lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \ + else \ + lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) + +#define PCHARSV(p, offset, len, utf, f) \ + if (test_mode == PCRE32_MODE) \ + (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \ + else if (test_mode == PCRE16_MODE) \ + (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \ + else \ + (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) + +#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_callout_enumerate_8(compiled_code8, \ + (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_callout_enumerate_16(compiled_code16, \ + (int(*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c); \ + else \ + a = pcre2_callout_enumerate_32(compiled_code32, \ + (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) + +#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ + if (test_mode == PCRE8_MODE) \ + G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g); \ + else if (test_mode == PCRE16_MODE) \ + G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g); \ + else \ + G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g) + +#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j); \ + else \ + a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j) + +#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ + if (test_mode == PCRE8_MODE) \ + r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)); \ + else if (test_mode == PCRE16_MODE) \ + r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)); \ + else \ + r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) + +#define PCRE2_GET_OVECTOR_COUNT(a,b) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_get_ovector_count_8(G(b,8)); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_get_ovector_count_16(G(b,16)); \ + else \ + a = pcre2_get_ovector_count_32(G(b,32)) + +#define PCRE2_GET_STARTCHAR(a,b) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_get_startchar_8(G(b,8)); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_get_startchar_16(G(b,16)); \ + else \ + a = pcre2_get_startchar_32(G(b,32)) + +#define PCRE2_JIT_COMPILE(r,a,b) \ + if (test_mode == PCRE8_MODE) r = pcre2_jit_compile_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) r = pcre2_jit_compile_16(G(a,16),b); \ + else r = pcre2_jit_compile_32(G(a,32),b) + +#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ + if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \ + else if (test_mode == PCRE16_MODE) pcre2_jit_free_unused_memory_16(G(a,16)); \ + else pcre2_jit_free_unused_memory_32(G(a,32)) + +#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \ + else \ + a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) + +#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); \ + else if (test_mode == PCRE16_MODE) \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); \ + else \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d); + +#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); \ + else \ + pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c); + +#define PCRE2_JIT_STACK_FREE(a) \ + if (test_mode == PCRE8_MODE) \ + pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); \ + else \ + pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a); + +#define PCRE2_MAKETABLES(a) \ + if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(NULL); \ + else if (test_mode == PCRE16_MODE) a = pcre2_maketables_16(NULL); \ + else a = pcre2_maketables_32(NULL) + +#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \ + else \ + a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) + +#define PCRE2_MATCH_DATA_CREATE(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + G(a,8) = pcre2_match_data_create_8(b,c); \ + else if (test_mode == PCRE16_MODE) \ + G(a,16) = pcre2_match_data_create_16(b,c); \ + else \ + G(a,32) = pcre2_match_data_create_32(b,c) + +#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c); \ + else if (test_mode == PCRE16_MODE) \ + G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c); \ + else \ + G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c) + +#define PCRE2_MATCH_DATA_FREE(a) \ + if (test_mode == PCRE8_MODE) \ + pcre2_match_data_free_8(G(a,8)); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_match_data_free_16(G(a,16)); \ + else \ + pcre2_match_data_free_32(G(a,32)) + +#define PCRE2_PATTERN_INFO(a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_pattern_info_8(G(b,8),c,d); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_pattern_info_16(G(b,16),c,d); \ + else \ + a = pcre2_pattern_info_32(G(b,32),c,d) + +#define PCRE2_PRINTINT(a) \ + if (test_mode == PCRE8_MODE) \ + pcre2_printint_8(compiled_code8,outfile,a); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_printint_16(compiled_code16,outfile,a); \ + else \ + pcre2_printint_32(compiled_code32,outfile,a) + +#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)); \ + else if (test_mode == PCRE16_MODE) \ + r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)); \ + else \ + r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32)) + +#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ + if (test_mode == PCRE8_MODE) \ + r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)); \ + else if (test_mode == PCRE16_MODE) \ + r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)); \ + else \ + r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32)) + +#define PCRE2_SERIALIZE_FREE(a) \ + if (test_mode == PCRE8_MODE) \ + pcre2_serialize_free_8(a); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_serialize_free_16(a); \ + else \ + pcre2_serialize_free_32(a) + +#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ + if (test_mode == PCRE8_MODE) \ + r = pcre2_serialize_get_number_of_codes_8(a); \ + else if (test_mode == PCRE16_MODE) \ + r = pcre2_serialize_get_number_of_codes_16(a); \ + else \ + r = pcre2_serialize_get_number_of_codes_32(a); \ + +#define PCRE2_SET_CALLOUT(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); \ + else \ + pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c); + +#define PCRE2_SET_CHARACTER_TABLES(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_character_tables_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_character_tables_16(G(a,16),b); \ + else \ + pcre2_set_character_tables_32(G(a,32),b) + +#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_compile_recursion_guard_8(G(a,8),b,c); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_compile_recursion_guard_16(G(a,16),b,c); \ + else \ + pcre2_set_compile_recursion_guard_32(G(a,32),b,c) + +#define PCRE2_SET_MATCH_LIMIT(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_match_limit_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_match_limit_16(G(a,16),b); \ + else \ + pcre2_set_match_limit_32(G(a,32),b) + +#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_max_pattern_length_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_max_pattern_length_16(G(a,16),b); \ + else \ + pcre2_set_max_pattern_length_32(G(a,32),b) + +#define PCRE2_SET_OFFSET_LIMIT(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_offset_limit_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_offset_limit_16(G(a,16),b); \ + else \ + pcre2_set_offset_limit_32(G(a,32),b) + +#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_parens_nest_limit_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_parens_nest_limit_16(G(a,16),b); \ + else \ + pcre2_set_parens_nest_limit_32(G(a,32),b) + +#define PCRE2_SET_RECURSION_LIMIT(a,b) \ + if (test_mode == PCRE8_MODE) \ + pcre2_set_recursion_limit_8(G(a,8),b); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_set_recursion_limit_16(G(a,16),b); \ + else \ + pcre2_set_recursion_limit_32(G(a,32),b) + +#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ + (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \ + (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \ + else \ + a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \ + (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l) + +#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e); \ + else \ + a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e) + +#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e); \ + else \ + a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e) + +#define PCRE2_SUBSTRING_FREE(a) \ + if (test_mode == PCRE8_MODE) pcre2_substring_free_8((PCRE2_UCHAR8 *)a); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_substring_free_16((PCRE2_UCHAR16 *)a); \ + else pcre2_substring_free_32((PCRE2_UCHAR32 *)a) + +#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e); \ + else \ + a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e) + +#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e); \ + else \ + a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e) + +#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d); \ + else \ + a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d) + +#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_length_bynumber_8(G(b,8),c,d); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_length_bynumber_16(G(b,16),c,d); \ + else \ + a = pcre2_substring_length_bynumber_32(G(b,32),c,d) + +#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d); \ + else \ + a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d) + +#define PCRE2_SUBSTRING_LIST_FREE(a) \ + if (test_mode == PCRE8_MODE) \ + pcre2_substring_list_free_8((PCRE2_SPTR8 *)a); \ + else if (test_mode == PCRE16_MODE) \ + pcre2_substring_list_free_16((PCRE2_SPTR16 *)a); \ + else \ + pcre2_substring_list_free_32((PCRE2_SPTR32 *)a) + +#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ + if (test_mode == PCRE8_MODE) \ + a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); \ + else if (test_mode == PCRE16_MODE) \ + a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); \ + else \ + a = pcre2_substring_number_from_name_32(G(b,32),G(c,32)) + +#define PTR(x) ( \ + (test_mode == PCRE8_MODE)? (void *)G(x,8) : \ + (test_mode == PCRE16_MODE)? (void *)G(x,16) : \ + (void *)G(x,32)) + +#define SETFLD(x,y,z) \ + if (test_mode == PCRE8_MODE) G(x,8)->y = z; \ + else if (test_mode == PCRE16_MODE) G(x,16)->y = z; \ + else G(x,32)->y = z + +#define SETFLDVEC(x,y,v,z) \ + if (test_mode == PCRE8_MODE) G(x,8)->y[v] = z; \ + else if (test_mode == PCRE16_MODE) G(x,16)->y[v] = z; \ + else G(x,32)->y[v] = z + +#define SETOP(x,y,z) \ + if (test_mode == PCRE8_MODE) G(x,8) z y; \ + else if (test_mode == PCRE16_MODE) G(x,16) z y; \ + else G(x,32) z y + +#define SETCASTPTR(x,y) \ + if (test_mode == PCRE8_MODE) \ + G(x,8) = (uint8_t *)(y); \ + else if (test_mode == PCRE16_MODE) \ + G(x,16) = (uint16_t *)(y); \ + else \ + G(x,32) = (uint32_t *)(y) + +#define STRLEN(p) ((test_mode == PCRE8_MODE)? ((int)strlen((char *)p)) : \ + (test_mode == PCRE16_MODE)? ((int)strlen16((PCRE2_SPTR16)p)) : \ + ((int)strlen32((PCRE2_SPTR32)p))) + +#define SUB1(a,b) \ + if (test_mode == PCRE8_MODE) G(a,8)(G(b,8)); \ + else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16)); \ + else G(a,32)(G(b,32)) + +#define SUB2(a,b,c) \ + if (test_mode == PCRE8_MODE) G(a,8)(G(b,8),G(c,8)); \ + else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16),G(c,16)); \ + else G(a,32)(G(b,32),G(c,32)) + +#define TEST(x,r,y) ( \ + (test_mode == PCRE8_MODE && G(x,8) r (y)) || \ + (test_mode == PCRE16_MODE && G(x,16) r (y)) || \ + (test_mode == PCRE32_MODE && G(x,32) r (y))) + +#define TESTFLD(x,f,r,y) ( \ + (test_mode == PCRE8_MODE && G(x,8)->f r (y)) || \ + (test_mode == PCRE16_MODE && G(x,16)->f r (y)) || \ + (test_mode == PCRE32_MODE && G(x,32)->f r (y))) + + + +/* ----- Two out of three modes are supported ----- */ + +#else + +/* We can use some macro trickery to make a single set of definitions work in +the three different cases. */ + +/* ----- 32-bit and 16-bit but not 8-bit supported ----- */ + +#if defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_16) +#define BITONE 32 +#define BITTWO 16 + +/* ----- 32-bit and 8-bit but not 16-bit supported ----- */ + +#elif defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_8) +#define BITONE 32 +#define BITTWO 8 + +/* ----- 16-bit and 8-bit but not 32-bit supported ----- */ + +#else +#define BITONE 16 +#define BITTWO 8 +#endif + + +/* ----- Common macros for two-mode cases ----- */ + +#define CASTFLD(t,a,b) \ + ((test_mode == G(G(PCRE,BITONE),_MODE))? (t)(G(a,BITONE)->b) : \ + (t)(G(a,BITTWO)->b)) + +#define CASTVAR(t,x) ( \ + (test_mode == G(G(PCRE,BITONE),_MODE))? \ + (t)G(x,BITONE) : (t)G(x,BITTWO)) + +#define CODE_UNIT(a,b) ( \ + (test_mode == G(G(PCRE,BITONE),_MODE))? \ + (uint32_t)(((G(PCRE2_SPTR,BITONE))(a))[b]) : \ + (uint32_t)(((G(PCRE2_SPTR,BITTWO))(a))[b])) + +#define DATCTXCPY(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_match_context_,BITONE))); \ + else \ + memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_match_context_,BITTWO))) + +#define FLD(a,b) \ + ((test_mode == G(G(PCRE,BITONE),_MODE))? G(a,BITONE)->b : G(a,BITTWO)->b) + +#define PATCTXCPY(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_compile_context_,BITONE))); \ + else \ + memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_compile_context_,BITTWO))) + +#define PCHARS(lv, p, offset, len, utf, f) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + lv = G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \ + else \ + lv = G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f) + +#define PCHARSV(p, offset, len, utf, f) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + (void)G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \ + else \ + (void)G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f) + +#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_callout_enumerate,BITONE)(G(compiled_code,BITONE), \ + (int (*)(struct G(pcre2_callout_enumerate_block_,BITONE) *, void *))b,c); \ + else \ + a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \ + (int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c) + +#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE) = G(pcre2_compile_,BITONE)(G(b,BITONE),c,d,e,f,g); \ + else \ + G(a,BITTWO) = G(pcre2_compile_,BITTWO)(G(b,BITTWO),c,d,e,f,g) + +#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_dfa_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ + G(g,BITONE),h,i,j); \ + else \ + a = G(pcre2_dfa_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ + G(g,BITTWO),h,i,j) + +#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + r = G(pcre2_get_error_message_,BITONE)(a,G(b,BITONE),G(G(b,BITONE),_size)); \ + else \ + r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size)) + +#define PCRE2_GET_OVECTOR_COUNT(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_get_ovector_count_,BITONE)(G(b,BITONE)); \ + else \ + a = G(pcre2_get_ovector_count_,BITTWO)(G(b,BITTWO)) + +#define PCRE2_GET_STARTCHAR(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_get_startchar_,BITONE)(G(b,BITONE)); \ + else \ + a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO)) + +#define PCRE2_JIT_COMPILE(r,a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + r = G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \ + else \ + r = G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_jit_free_unused_memory_,BITONE)(G(a,BITONE)); \ + else \ + G(pcre2_jit_free_unused_memory_,BITTWO)(G(a,BITTWO)) + +#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_jit_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ + G(g,BITONE),h); \ + else \ + a = G(pcre2_jit_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ + G(g,BITTWO),h) + +#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITONE)(b,c,d); \ + else \ + a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITTWO)(b,c,d); \ + +#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_jit_stack_assign_,BITONE)(G(a,BITONE),(G(pcre2_jit_callback_,BITONE))b,c); \ + else \ + G(pcre2_jit_stack_assign_,BITTWO)(G(a,BITTWO),(G(pcre2_jit_callback_,BITTWO))b,c); + +#define PCRE2_JIT_STACK_FREE(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_jit_stack_free_,BITONE)((G(pcre2_jit_stack_,BITONE) *)a); \ + else \ + G(pcre2_jit_stack_free_,BITTWO)((G(pcre2_jit_stack_,BITTWO) *)a); + +#define PCRE2_MAKETABLES(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_maketables_,BITONE)(NULL); \ + else \ + a = G(pcre2_maketables_,BITTWO)(NULL) + +#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ + G(g,BITONE),h); \ + else \ + a = G(pcre2_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ + G(g,BITTWO),h) + +#define PCRE2_MATCH_DATA_CREATE(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE) = G(pcre2_match_data_create_,BITONE)(b,c); \ + else \ + G(a,BITTWO) = G(pcre2_match_data_create_,BITTWO)(b,c) + +#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE) = G(pcre2_match_data_create_from_pattern_,BITONE)(G(b,BITONE),c); \ + else \ + G(a,BITTWO) = G(pcre2_match_data_create_from_pattern_,BITTWO)(G(b,BITTWO),c) + +#define PCRE2_MATCH_DATA_FREE(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_match_data_free_,BITONE)(G(a,BITONE)); \ + else \ + G(pcre2_match_data_free_,BITTWO)(G(a,BITTWO)) + +#define PCRE2_PATTERN_INFO(a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_pattern_info_,BITONE)(G(b,BITONE),c,d); \ + else \ + a = G(pcre2_pattern_info_,BITTWO)(G(b,BITTWO),c,d) + +#define PCRE2_PRINTINT(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_printint_,BITONE)(G(compiled_code,BITONE),outfile,a); \ + else \ + G(pcre2_printint_,BITTWO)(G(compiled_code,BITTWO),outfile,a) + +#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + r = G(pcre2_serialize_decode_,BITONE)((G(pcre2_code_,BITONE) **)a,b,c,G(d,BITONE)); \ + else \ + r = G(pcre2_serialize_decode_,BITTWO)((G(pcre2_code_,BITTWO) **)a,b,c,G(d,BITTWO)) + +#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + r = G(pcre2_serialize_encode_,BITONE)((G(const pcre2_code_,BITONE) **)a,b,c,d,G(e,BITONE)); \ + else \ + r = G(pcre2_serialize_encode_,BITTWO)((G(const pcre2_code_,BITTWO) **)a,b,c,d,G(e,BITTWO)) + +#define PCRE2_SERIALIZE_FREE(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_serialize_free_,BITONE)(a); \ + else \ + G(pcre2_serialize_free_,BITTWO)(a) + +#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + r = G(pcre2_serialize_get_number_of_codes_,BITONE)(a); \ + else \ + r = G(pcre2_serialize_get_number_of_codes_,BITTWO)(a) + +#define PCRE2_SET_CALLOUT(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_callout_,BITONE)(G(a,BITONE), \ + (int (*)(G(pcre2_callout_block_,BITONE) *, void *))b,c); \ + else \ + G(pcre2_set_callout_,BITTWO)(G(a,BITTWO), \ + (int (*)(G(pcre2_callout_block_,BITTWO) *, void *))b,c); + +#define PCRE2_SET_CHARACTER_TABLES(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_character_tables_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_character_tables_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_compile_recursion_guard_,BITONE)(G(a,BITONE),b,c); \ + else \ + G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c) + +#define PCRE2_SET_MATCH_LIMIT(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_match_limit_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_max_pattern_length_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_max_pattern_length_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SET_OFFSET_LIMIT(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_offset_limit_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_offset_limit_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_parens_nest_limit_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SET_RECURSION_LIMIT(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_set_recursion_limit_,BITONE)(G(a,BITONE),b); \ + else \ + G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b) + +#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ + G(g,BITONE),G(h,BITONE),(G(PCRE2_SPTR,BITONE))i,j, \ + (G(PCRE2_UCHAR,BITONE) *)k,l); \ + else \ + a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ + G(g,BITTWO),G(h,BITTWO),(G(PCRE2_SPTR,BITTWO))i,j, \ + (G(PCRE2_UCHAR,BITTWO) *)k,l) + +#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\ + (G(PCRE2_UCHAR,BITONE) *)d,e); \ + else \ + a = G(pcre2_substring_copy_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\ + (G(PCRE2_UCHAR,BITTWO) *)d,e) + +#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_copy_bynumber_,BITONE)(G(b,BITONE),c,\ + (G(PCRE2_UCHAR,BITONE) *)d,e); \ + else \ + a = G(pcre2_substring_copy_bynumber_,BITTWO)(G(b,BITTWO),c,\ + (G(PCRE2_UCHAR,BITTWO) *)d,e) + +#define PCRE2_SUBSTRING_FREE(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_substring_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \ + else G(pcre2_substring_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a) + +#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_get_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\ + (G(PCRE2_UCHAR,BITONE) **)d,e); \ + else \ + a = G(pcre2_substring_get_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\ + (G(PCRE2_UCHAR,BITTWO) **)d,e) + +#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_get_bynumber_,BITONE)(G(b,BITONE),c,\ + (G(PCRE2_UCHAR,BITONE) **)d,e); \ + else \ + a = G(pcre2_substring_get_bynumber_,BITTWO)(G(b,BITTWO),c,\ + (G(PCRE2_UCHAR,BITTWO) **)d,e) + +#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_length_byname_,BITONE)(G(b,BITONE),G(c,BITONE),d); \ + else \ + a = G(pcre2_substring_length_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),d) + +#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_length_bynumber_,BITONE)(G(b,BITONE),c,d); \ + else \ + a = G(pcre2_substring_length_bynumber_,BITTWO)(G(b,BITTWO),c,d) + +#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_list_get_,BITONE)(G(b,BITONE), \ + (G(PCRE2_UCHAR,BITONE) ***)c,d); \ + else \ + a = G(pcre2_substring_list_get_,BITTWO)(G(b,BITTWO), \ + (G(PCRE2_UCHAR,BITTWO) ***)c,d) + +#define PCRE2_SUBSTRING_LIST_FREE(a) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(pcre2_substring_list_free_,BITONE)((G(PCRE2_SPTR,BITONE) *)a); \ + else \ + G(pcre2_substring_list_free_,BITTWO)((G(PCRE2_SPTR,BITTWO) *)a) + +#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = G(pcre2_substring_number_from_name_,BITONE)(G(b,BITONE),G(c,BITONE)); \ + else \ + a = G(pcre2_substring_number_from_name_,BITTWO)(G(b,BITTWO),G(c,BITTWO)) + +#define PTR(x) ( \ + (test_mode == G(G(PCRE,BITONE),_MODE))? (void *)G(x,BITONE) : \ + (void *)G(x,BITTWO)) + +#define SETFLD(x,y,z) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y = z; \ + else G(x,BITTWO)->y = z + +#define SETFLDVEC(x,y,v,z) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y[v] = z; \ + else G(x,BITTWO)->y[v] = z + +#define SETOP(x,y,z) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE) z y; \ + else G(x,BITTWO) z y + +#define SETCASTPTR(x,y) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(x,BITONE) = (G(G(uint,BITONE),_t) *)(y); \ + else \ + G(x,BITTWO) = (G(G(uint,BITTWO),_t) *)(y) + +#define STRLEN(p) ((test_mode == G(G(PCRE,BITONE),_MODE))? \ + G(strlen,BITONE)((G(PCRE2_SPTR,BITONE))p) : \ + G(strlen,BITTWO)((G(PCRE2_SPTR,BITTWO))p)) + +#define SUB1(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE)(G(b,BITONE)); \ + else \ + G(a,BITTWO)(G(b,BITTWO)) + +#define SUB2(a,b,c) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE))(G(b,BITONE),G(c,BITONE)); \ + else \ + G(a,BITTWO))(G(b,BITTWO),G(c,BITTWO)) + +#define TEST(x,r,y) ( \ + (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE) r (y)) || \ + (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO) r (y))) + +#define TESTFLD(x,f,r,y) ( \ + (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE)->f r (y)) || \ + (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO)->f r (y))) + + +#endif /* Two out of three modes */ + +/* ----- End of cases where more than one mode is supported ----- */ + + +/* ----- Only 8-bit mode is supported ----- */ + +#elif defined SUPPORT_PCRE2_8 +#define CASTFLD(t,a,b) (t)(G(a,8)->b) +#define CASTVAR(t,x) (t)G(x,8) +#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR8)(a))[b]) +#define DATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)) +#define FLD(a,b) G(a,8)->b +#define PATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)) +#define PCHARS(lv, p, offset, len, utf, f) \ + lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) +#define PCHARSV(p, offset, len, utf, f) \ + (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) +#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ + a = pcre2_callout_enumerate_8(compiled_code8, \ + (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c) +#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ + G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g) +#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ + a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j) +#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ + r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)) +#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8)) +#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8)) +#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_8(G(a,8),b) +#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8)) +#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h) +#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); +#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ + pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); +#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); +#define PCRE2_MAKETABLES(a) a = pcre2_maketables_8(NULL) +#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h) +#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,8) = pcre2_match_data_create_8(b,c) +#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ + G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c) +#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_8(G(a,8)) +#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_8(G(b,8),c,d) +#define PCRE2_PRINTINT(a) pcre2_printint_8(compiled_code8,outfile,a) +#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ + r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)) +#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ + r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)) +#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_8(a) +#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ + r = pcre2_serialize_get_number_of_codes_8(a) +#define PCRE2_SET_CALLOUT(a,b,c) \ + pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c) +#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b) +#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ + pcre2_set_compile_recursion_guard_8(G(a,8),b,c) +#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b) +#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b) +#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b) +#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b) +#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b) +#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ + a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ + (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l) +#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e) +#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e) +#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_8((PCRE2_UCHAR8 *)a) +#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e) +#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e) +#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ + a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d) +#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ + a = pcre2_substring_length_bynumber_8(G(b,8),c,d) +#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ + a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d) +#define PCRE2_SUBSTRING_LIST_FREE(a) \ + pcre2_substring_list_free_8((PCRE2_SPTR8 *)a) +#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ + a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); +#define PTR(x) (void *)G(x,8) +#define SETFLD(x,y,z) G(x,8)->y = z +#define SETFLDVEC(x,y,v,z) G(x,8)->y[v] = z +#define SETOP(x,y,z) G(x,8) z y +#define SETCASTPTR(x,y) G(x,8) = (uint8_t *)(y) +#define STRLEN(p) (int)strlen((char *)p) +#define SUB1(a,b) G(a,8)(G(b,8)) +#define SUB2(a,b,c) G(a,8)(G(b,8),G(c,8)) +#define TEST(x,r,y) (G(x,8) r (y)) +#define TESTFLD(x,f,r,y) (G(x,8)->f r (y)) + + +/* ----- Only 16-bit mode is supported ----- */ + +#elif defined SUPPORT_PCRE2_16 +#define CASTFLD(t,a,b) (t)(G(a,16)->b) +#define CASTVAR(t,x) (t)G(x,16) +#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR16)(a))[b]) +#define DATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)) +#define FLD(a,b) G(a,16)->b +#define PATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)) +#define PCHARS(lv, p, offset, len, utf, f) \ + lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f) +#define PCHARSV(p, offset, len, utf, f) \ + (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f) +#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ + a = pcre2_callout_enumerate_16(compiled_code16, \ + (int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c) +#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ + G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g) +#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ + a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j) +#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ + r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)) +#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16)) +#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16)) +#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_16(G(a,16),b) +#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16)) +#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h) +#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); +#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ + pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); +#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); +#define PCRE2_MAKETABLES(a) a = pcre2_maketables_16(NULL) +#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h) +#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,16) = pcre2_match_data_create_16(b,c) +#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ + G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c) +#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_16(G(a,16)) +#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_16(G(b,16),c,d) +#define PCRE2_PRINTINT(a) pcre2_printint_16(compiled_code16,outfile,a) +#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ + r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)) +#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ + r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)) +#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_16(a) +#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ + r = pcre2_serialize_get_number_of_codes_16(a) +#define PCRE2_SET_CALLOUT(a,b,c) \ + pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); +#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b) +#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ + pcre2_set_compile_recursion_guard_16(G(a,16),b,c) +#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b) +#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_16(G(a,16),b) +#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b) +#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b) +#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b) +#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ + a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \ + (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l) +#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e) +#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e) +#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_16((PCRE2_UCHAR16 *)a) +#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e) +#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e) +#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ + a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d) +#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ + a = pcre2_substring_length_bynumber_16(G(b,16),c,d) +#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ + a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d) +#define PCRE2_SUBSTRING_LIST_FREE(a) \ + pcre2_substring_list_free_16((PCRE2_SPTR16 *)a) +#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ + a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); +#define PTR(x) (void *)G(x,16) +#define SETFLD(x,y,z) G(x,16)->y = z +#define SETFLDVEC(x,y,v,z) G(x,16)->y[v] = z +#define SETOP(x,y,z) G(x,16) z y +#define SETCASTPTR(x,y) G(x,16) = (uint16_t *)(y) +#define STRLEN(p) (int)strlen16((PCRE2_SPTR16)p) +#define SUB1(a,b) G(a,16)(G(b,16)) +#define SUB2(a,b,c) G(a,16)(G(b,16),G(c,16)) +#define TEST(x,r,y) (G(x,16) r (y)) +#define TESTFLD(x,f,r,y) (G(x,16)->f r (y)) + + +/* ----- Only 32-bit mode is supported ----- */ + +#elif defined SUPPORT_PCRE2_32 +#define CASTFLD(t,a,b) (t)(G(a,32)->b) +#define CASTVAR(t,x) (t)G(x,32) +#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR32)(a))[b]) +#define DATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32)) +#define FLD(a,b) G(a,32)->b +#define PATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32)) +#define PCHARS(lv, p, offset, len, utf, f) \ + lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f) +#define PCHARSV(p, offset, len, utf, f) \ + (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f) +#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ + a = pcre2_callout_enumerate_32(compiled_code32, \ + (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) +#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ + G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g) +#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ + a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j) +#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ + r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) +#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32)) +#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32)) +#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_32(G(a,32),b) +#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32)) +#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) +#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ + a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d); +#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ + pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c); +#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a); +#define PCRE2_MAKETABLES(a) a = pcre2_maketables_32(NULL) +#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ + a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) +#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,32) = pcre2_match_data_create_32(b,c) +#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ + G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c) +#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_32(G(a,32)) +#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_32(G(b,32),c,d) +#define PCRE2_PRINTINT(a) pcre2_printint_32(compiled_code32,outfile,a) +#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ + r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32)) +#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ + r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32)) +#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_32(a) +#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ + r = pcre2_serialize_get_number_of_codes_32(a) +#define PCRE2_SET_CALLOUT(a,b,c) \ + pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c); +#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b) +#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ + pcre2_set_compile_recursion_guard_32(G(a,32),b,c) +#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b) +#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_32(G(a,32),b) +#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b) +#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b) +#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b) +#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ + a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \ + (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l) +#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e) +#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e); +#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_32((PCRE2_UCHAR32 *)a) +#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ + a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e) +#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ + a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e) +#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ + a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d) +#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ + a = pcre2_substring_length_bynumber_32(G(b,32),c,d) +#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ + a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d) +#define PCRE2_SUBSTRING_LIST_FREE(a) \ + pcre2_substring_list_free_32((PCRE2_SPTR32 *)a) +#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ + a = pcre2_substring_number_from_name_32(G(b,32),G(c,32)); +#define PTR(x) (void *)G(x,32) +#define SETFLD(x,y,z) G(x,32)->y = z +#define SETFLDVEC(x,y,v,z) G(x,32)->y[v] = z +#define SETOP(x,y,z) G(x,32) z y +#define SETCASTPTR(x,y) G(x,32) = (uint32_t *)(y) +#define STRLEN(p) (int)strlen32((PCRE2_SPTR32)p) +#define SUB1(a,b) G(a,32)(G(b,32)) +#define SUB2(a,b,c) G(a,32)(G(b,32),G(c,32)) +#define TEST(x,r,y) (G(x,32) r (y)) +#define TESTFLD(x,f,r,y) (G(x,32)->f r (y)) + +#endif + +/* ----- End of mode-specific function call macros ----- */ + + + + +/************************************************* +* Alternate character tables * +*************************************************/ + +/* By default, the "tables" pointer in the compile context when calling +pcre2_compile() is not set (= NULL), thereby using the default tables of the +library. However, the tables modifier can be used to select alternate sets of +tables, for different kinds of testing. Note that the locale modifier also +adjusts the tables. */ + +/* This is the set of tables distributed as default with PCRE2. It recognizes +only ASCII characters. */ + +static const uint8_t tables1[] = { + +/* This table is a lower casing table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table is a case flipping table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table contains bit maps for various character classes. Each map is 32 +bytes long and the bits run from the least significant end of each byte. The +classes that have their own maps are: space, xdigit, digit, upper, lower, word, +graph, print, punct, and cntrl. Other classes are built from combinations. */ + + 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, + 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +/* This table identifies various classes of character by individual bits: + 0x01 white space character + 0x02 letter + 0x04 decimal digit + 0x08 hexadecimal digit + 0x10 alphanumeric or '_' + 0x80 regular expression metacharacter or binary zero +*/ + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ + 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +/* This is a set of tables that came originally from a Windows user. It seems +to be at least an approximation of ISO 8859. In particular, there are +characters greater than 128 that are marked as spaces, letters, etc. */ + +static const uint8_t tables2[] = { +0,1,2,3,4,5,6,7, +8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23, +24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39, +40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55, +56,57,58,59,60,61,62,63, +64,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,91,92,93,94,95, +96,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,123,124,125,126,127, +128,129,130,131,132,133,134,135, +136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151, +152,153,154,155,156,157,158,159, +160,161,162,163,164,165,166,167, +168,169,170,171,172,173,174,175, +176,177,178,179,180,181,182,183, +184,185,186,187,188,189,190,191, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,215, +248,249,250,251,252,253,254,223, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,247, +248,249,250,251,252,253,254,255, +0,1,2,3,4,5,6,7, +8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23, +24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39, +40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55, +56,57,58,59,60,61,62,63, +64,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,91,92,93,94,95, +96,65,66,67,68,69,70,71, +72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87, +88,89,90,123,124,125,126,127, +128,129,130,131,132,133,134,135, +136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151, +152,153,154,155,156,157,158,159, +160,161,162,163,164,165,166,167, +168,169,170,171,172,173,174,175, +176,177,178,179,180,181,182,183, +184,185,186,187,188,189,190,191, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,215, +248,249,250,251,252,253,254,223, +192,193,194,195,196,197,198,199, +200,201,202,203,204,205,206,207, +208,209,210,211,212,213,214,247, +216,217,218,219,220,221,222,255, +0,62,0,0,1,0,0,0, +0,0,0,0,0,0,0,0, +32,0,0,0,1,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,255,3, +126,0,0,0,126,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,255,3, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,2, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +254,255,255,7,0,0,0,0, +0,0,0,0,0,0,0,0, +255,255,127,127,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,254,255,255,7, +0,0,0,0,0,4,32,4, +0,0,0,128,255,255,127,255, +0,0,0,0,0,0,255,3, +254,255,255,135,254,255,255,7, +0,0,0,0,0,4,44,6, +255,255,127,255,255,255,127,255, +0,0,0,0,254,255,255,255, +255,255,255,255,255,255,255,127, +0,0,0,0,254,255,255,255, +255,255,255,255,255,255,255,255, +0,2,0,0,255,255,255,255, +255,255,255,255,255,255,255,127, +0,0,0,0,255,255,255,255, +255,255,255,255,255,255,255,255, +0,0,0,0,254,255,0,252, +1,0,0,248,1,0,0,120, +0,0,0,0,254,255,255,255, +0,0,128,0,0,0,128,0, +255,255,255,255,0,0,0,0, +0,0,0,0,0,0,0,128, +255,255,255,255,0,0,0,0, +0,0,0,0,0,0,0,0, +128,0,0,0,0,0,0,0, +0,1,1,0,1,1,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +1,0,0,0,128,0,0,0, +128,128,128,128,0,0,128,0, +28,28,28,28,28,28,28,28, +28,28,0,0,0,0,0,128, +0,26,26,26,26,26,26,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,128,128,0,128,16, +0,26,26,26,26,26,26,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,128,128,0,0,0, +0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0, +0,0,18,0,0,0,0,0, +0,0,20,20,0,18,0,0, +0,20,18,0,0,0,0,0, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,0, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,0, +18,18,18,18,18,18,18,18 +}; + + + +/************************************************* +* Local memory functions * +*************************************************/ + +/* Alternative memory functions, to test functionality. */ + +static void *my_malloc(size_t size, void *data) +{ +void *block = malloc(size); +(void)data; +if (show_memory) + fprintf(outfile, "malloc %3d %p\n", (int)size, block); +return block; +} + +static void my_free(void *block, void *data) +{ +(void)data; +if (show_memory) + fprintf(outfile, "free %p\n", block); +free(block); +} + +/* For recursion malloc/free, to test stacking calls */ + +#ifdef HEAP_MATCH_RECURSE +static void *my_stack_malloc(size_t size, void *data) +{ +void *block = malloc(size); +(void)data; +if (show_memory) + fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block); +return block; +} + +static void my_stack_free(void *block, void *data) +{ +(void)data; +if (show_memory) + fprintf(outfile, "stack_free %p\n", block); +free(block); +} +#endif /* HEAP_MATCH_RECURSE */ + + +/************************************************* +* Callback function for stack guard * +*************************************************/ + +/* This is set up to be called from pcre2_compile() when the stackguard=n +modifier sets a value greater than zero. The test we do is whether the +parenthesis nesting depth is greater than the value set by the modifier. + +Argument: the current parenthesis nesting depth +Returns: non-zero to kill the compilation +*/ + +static int +stack_guard(uint32_t depth, void *user_data) +{ +(void)user_data; +return depth > pat_patctl.stackguard_test; +} + + +/************************************************* +* JIT memory callback * +*************************************************/ + +static PCRE2_JIT_STACK* +jit_callback(void *arg) +{ +jit_was_used = TRUE; +return (PCRE2_JIT_STACK *)arg; +} + + +/************************************************* +* Convert UTF-8 character to code point * +*************************************************/ + +/* This function reads one or more bytes that represent a UTF-8 character, +and returns the codepoint of that character. Note that the function supports +the original UTF-8 definition of RFC 2279, allowing for values in the range 0 +to 0x7fffffff, up to 6 bytes long. This makes it possible to generate +codepoints greater than 0x10ffff which are useful for testing PCRE2's error +checking, and also for generating 32-bit non-UTF data values above the UTF +limit. + +Argument: + utf8bytes a pointer to the byte vector + vptr a pointer to an int to receive the value + +Returns: > 0 => the number of bytes consumed + -6 to 0 => malformed UTF-8 character at offset = (-return) +*/ + +static int +utf82ord(PCRE2_SPTR8 utf8bytes, uint32_t *vptr) +{ +uint32_t c = *utf8bytes++; +uint32_t d = c; +int i, j, s; + +for (i = -1; i < 6; i++) /* i is number of additional bytes */ + { + if ((d & 0x80) == 0) break; + d <<= 1; + } + +if (i == -1) { *vptr = c; return 1; } /* ascii character */ +if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ + +/* i now has a value in the range 1-5 */ + +s = 6*i; +d = (c & utf8_table3[i]) << s; + +for (j = 0; j < i; j++) + { + c = *utf8bytes++; + if ((c & 0xc0) != 0x80) return -(j+1); + s -= 6; + d |= (c & 0x3f) << s; + } + +/* Check that encoding was the correct unique one */ + +for (j = 0; j < utf8_table1_size; j++) + if (d <= (uint32_t)utf8_table1[j]) break; +if (j != i) return -(i+1); + +/* Valid value */ + +*vptr = d; +return i+1; +} + + + +/************************************************* +* Print one character * +*************************************************/ + +/* Print a single character either literally, or as a hex escape, and count how +many printed characters are used. + +Arguments: + c the character + utf TRUE in UTF mode + f the FILE to print to, or NULL just to count characters + +Returns: number of characters written +*/ + +static int +pchar(uint32_t c, BOOL utf, FILE *f) +{ +int n = 0; +if (PRINTOK(c)) + { + if (f != NULL) fprintf(f, "%c", c); + return 1; + } + +if (c < 0x100) + { + if (utf) + { + if (f != NULL) fprintf(f, "\\x{%02x}", c); + return 6; + } + else + { + if (f != NULL) fprintf(f, "\\x%02x", c); + return 4; + } + } + +if (f != NULL) n = fprintf(f, "\\x{%02x}", c); +return n >= 0 ? n : 0; +} + + + +#ifdef SUPPORT_PCRE2_16 +/************************************************* +* Find length of 0-terminated 16-bit string * +*************************************************/ + +static size_t strlen16(PCRE2_SPTR16 p) +{ +PCRE2_SPTR16 pp = p; +while (*pp != 0) pp++; +return (int)(pp - p); +} +#endif /* SUPPORT_PCRE2_16 */ + + + +#ifdef SUPPORT_PCRE2_32 +/************************************************* +* Find length of 0-terminated 32-bit string * +*************************************************/ + +static size_t strlen32(PCRE2_SPTR32 p) +{ +PCRE2_SPTR32 pp = p; +while (*pp != 0) pp++; +return (int)(pp - p); +} +#endif /* SUPPORT_PCRE2_32 */ + + +#ifdef SUPPORT_PCRE2_8 +/************************************************* +* Print 8-bit character string * +*************************************************/ + +/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. +For printing *MARK strings, a negative length is given. If handed a NULL file, +just counts chars without printing. */ + +static int pchars8(PCRE2_SPTR8 p, int length, BOOL utf, FILE *f) +{ +uint32_t c = 0; +int yield = 0; +if (length < 0) length = p[-1]; +while (length-- > 0) + { + if (utf) + { + int rc = utf82ord(p, &c); + if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ + { + length -= rc - 1; + p += rc; + yield += pchar(c, utf, f); + continue; + } + } + c = *p++; + yield += pchar(c, utf, f); + } +return yield; +} +#endif + + +#ifdef SUPPORT_PCRE2_16 +/************************************************* +* Print 16-bit character string * +*************************************************/ + +/* Must handle UTF-16 strings in utf mode. Yields number of characters printed. +For printing *MARK strings, a negative length is given. If handed a NULL file, +just counts chars without printing. */ + +static int pchars16(PCRE2_SPTR16 p, int length, BOOL utf, FILE *f) +{ +int yield = 0; +if (length < 0) length = p[-1]; +while (length-- > 0) + { + uint32_t c = *p++ & 0xffff; + if (utf && c >= 0xD800 && c < 0xDC00 && length > 0) + { + int d = *p & 0xffff; + if (d >= 0xDC00 && d <= 0xDFFF) + { + c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; + length--; + p++; + } + } + yield += pchar(c, utf, f); + } +return yield; +} +#endif /* SUPPORT_PCRE2_16 */ + + + +#ifdef SUPPORT_PCRE2_32 +/************************************************* +* Print 32-bit character string * +*************************************************/ + +/* Must handle UTF-32 strings in utf mode. Yields number of characters printed. +For printing *MARK strings, a negative length is given.If handed a NULL file, +just counts chars without printing. */ + +static int pchars32(PCRE2_SPTR32 p, int length, BOOL utf, FILE *f) +{ +int yield = 0; +(void)(utf); /* Avoid compiler warning */ +if (length < 0) length = p[-1]; +while (length-- > 0) + { + uint32_t c = *p++; + yield += pchar(c, utf, f); + } +return yield; +} +#endif /* SUPPORT_PCRE2_32 */ + + + + +#ifdef SUPPORT_PCRE2_8 +/************************************************* +* Convert character value to UTF-8 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x7fffffff +and encodes it as a UTF-8 character in 0 to 6 bytes. + +Arguments: + cvalue the character value + utf8bytes pointer to buffer for result - at least 6 bytes long + +Returns: number of characters placed in the buffer +*/ + +static int +ord2utf8(uint32_t cvalue, uint8_t *utf8bytes) +{ +register int i, j; +if (cvalue > 0x7fffffffu) + return -1; +for (i = 0; i < utf8_table1_size; i++) + if (cvalue <= (uint32_t)utf8_table1[i]) break; +utf8bytes += i; +for (j = i; j > 0; j--) + { + *utf8bytes-- = 0x80 | (cvalue & 0x3f); + cvalue >>= 6; + } +*utf8bytes = utf8_table2[i] | cvalue; +return i + 1; +} +#endif /* SUPPORT_PCRE2_8 */ + + + +#ifdef SUPPORT_PCRE2_16 +/************************************************* +* Convert pattern to 16-bit * +*************************************************/ + +/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If +all the input bytes are ASCII, the space needed for a 16-bit string is exactly +double the 8-bit size. Otherwise, the size needed for a 16-bit string is no +more than double, because up to 0xffff uses no more than 3 bytes in UTF-8 but +possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in +UTF-16. The result is always left in pbuffer16. Impose a minimum size to save +repeated re-sizing. + +Note that this function does not object to surrogate values. This is +deliberate; it makes it possible to construct UTF-16 strings that are invalid, +for the purpose of testing that they are correctly faulted. + +Arguments: + p points to a byte string + utf non-zero if converting to UTF-16 + lenptr points to number of bytes in the string (excluding trailing zero) + +Returns: 0 on success, with the length updated to the number of 16-bit + data items used (excluding the trailing zero) + OR -1 if a UTF-8 string is malformed + OR -2 if a value > 0x10ffff is encountered in UTF mode + OR -3 if a value > 0xffff is encountered when not in UTF mode +*/ + +static PCRE2_SIZE +to16(uint8_t *p, int utf, PCRE2_SIZE *lenptr) +{ +uint16_t *pp; +PCRE2_SIZE len = *lenptr; + +if (pbuffer16_size < 2*len + 2) + { + if (pbuffer16 != NULL) free(pbuffer16); + pbuffer16_size = 2*len + 2; + if (pbuffer16_size < 256) pbuffer16_size = 256; + pbuffer16 = (uint16_t *)malloc(pbuffer16_size); + if (pbuffer16 == NULL) + { + fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer16\n", + (unsigned long int)pbuffer16_size); + exit(1); + } + } + +pp = pbuffer16; +if (!utf) + { + for (; len > 0; len--) *pp++ = *p++; + } +else while (len > 0) + { + uint32_t c; + int chlen = utf82ord(p, &c); + if (chlen <= 0) return -1; + if (c > 0x10ffff) return -2; + p += chlen; + len -= chlen; + if (c < 0x10000) *pp++ = c; else + { + if (!utf) return -3; + c -= 0x10000; + *pp++ = 0xD800 | (c >> 10); + *pp++ = 0xDC00 | (c & 0x3ff); + } + } + +*pp = 0; +*lenptr = pp - pbuffer16; +return 0; +} +#endif + + + +#ifdef SUPPORT_PCRE2_32 +/************************************************* +* Convert pattern to 32-bit * +*************************************************/ + +/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If +all the input bytes are ASCII, the space needed for a 32-bit string is exactly +four times the 8-bit size. Otherwise, the size needed for a 32-bit string is no +more than four times, because the number of characters must be less than the +number of bytes. The result is always left in pbuffer32. Impose a minimum size +to save repeated re-sizing. + +Note that this function does not object to surrogate values. This is +deliberate; it makes it possible to construct UTF-32 strings that are invalid, +for the purpose of testing that they are correctly faulted. + +Arguments: + p points to a byte string + utf true if UTF-8 (to be converted to UTF-32) + lenptr points to number of bytes in the string (excluding trailing zero) + +Returns: 0 on success, with the length updated to the number of 32-bit + data items used (excluding the trailing zero) + OR -1 if a UTF-8 string is malformed + OR -2 if a value > 0x10ffff is encountered in UTF mode +*/ + +static PCRE2_SIZE +to32(uint8_t *p, int utf, PCRE2_SIZE *lenptr) +{ +uint32_t *pp; +PCRE2_SIZE len = *lenptr; + +if (pbuffer32_size < 4*len + 4) + { + if (pbuffer32 != NULL) free(pbuffer32); + pbuffer32_size = 4*len + 4; + if (pbuffer32_size < 256) pbuffer32_size = 256; + pbuffer32 = (uint32_t *)malloc(pbuffer32_size); + if (pbuffer32 == NULL) + { + fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer32\n", + (unsigned long int)pbuffer32_size); + exit(1); + } + } + +pp = pbuffer32; +if (!utf) + { + for (; len > 0; len--) *pp++ = *p++; + } +else while (len > 0) + { + uint32_t c; + int chlen = utf82ord(p, &c); + if (chlen <= 0) return -1; + if (utf && c > 0x10ffff) return -2; + p += chlen; + len -= chlen; + *pp++ = c; + } + +*pp = 0; +*lenptr = pp - pbuffer32; +return 0; +} +#endif /* SUPPORT_PCRE2_32 */ + + + +/************************************************* +* Move back by so many characters * +*************************************************/ + +/* Given a code unit offset in a subject string, move backwards by a number of +characters, and return the resulting offset. + +Arguments: + subject pointer to the string + offset start offset + count count to move back by + utf TRUE if in UTF mode + +Returns: a possibly changed offset +*/ + +static PCRE2_SIZE +backchars(uint8_t *subject, PCRE2_SIZE offset, uint32_t count, BOOL utf) +{ +if (!utf || test_mode == PCRE32_MODE) + return (count >= offset)? 0 : (offset - count); + +else if (test_mode == PCRE8_MODE) + { + PCRE2_SPTR8 pp = (PCRE2_SPTR8)subject + offset; + for (; count > 0 && pp > (PCRE2_SPTR8)subject; count--) + { + pp--; + while ((*pp & 0xc0) == 0x80) pp--; + } + return pp - (PCRE2_SPTR8)subject; + } + +else /* 16-bit mode */ + { + PCRE2_SPTR16 pp = (PCRE2_SPTR16)subject + offset; + for (; count > 0 && pp > (PCRE2_SPTR16)subject; count--) + { + pp--; + if ((*pp & 0xfc00) == 0xdc00) pp--; + } + return pp - (PCRE2_SPTR16)subject; + } +} + + + +/************************************************* +* Expand input buffers * +*************************************************/ + +/* This function doubles the size of the input buffer and the buffer for +keeping an 8-bit copy of patterns (pbuffer8), and copies the current buffers to +the new ones. + +Arguments: none +Returns: nothing (aborts if malloc() fails) +*/ + +static void +expand_input_buffers(void) +{ +int new_pbuffer8_size = 2*pbuffer8_size; +uint8_t *new_buffer = (uint8_t *)malloc(new_pbuffer8_size); +uint8_t *new_pbuffer8 = (uint8_t *)malloc(new_pbuffer8_size); + +if (new_buffer == NULL || new_pbuffer8 == NULL) + { + fprintf(stderr, "pcre2test: malloc(%d) failed\n", new_pbuffer8_size); + exit(1); + } + +memcpy(new_buffer, buffer, pbuffer8_size); +memcpy(new_pbuffer8, pbuffer8, pbuffer8_size); + +pbuffer8_size = new_pbuffer8_size; + +free(buffer); +free(pbuffer8); + +buffer = new_buffer; +pbuffer8 = new_pbuffer8; +} + + + +/************************************************* +* Read or extend an input line * +*************************************************/ + +/* Input lines are read into buffer, but both patterns and data lines can be +continued over multiple input lines. In addition, if the buffer fills up, we +want to automatically expand it so as to be able to handle extremely large +lines that are needed for certain stress tests. When the input buffer is +expanded, the other two buffers must also be expanded likewise, and the +contents of pbuffer, which are a copy of the input for callouts, must be +preserved (for when expansion happens for a data line). This is not the most +optimal way of handling this, but hey, this is just a test program! + +Arguments: + f the file to read + start where in buffer to start (this *must* be within buffer) + prompt for stdin or readline() + +Returns: pointer to the start of new data + could be a copy of start, or could be moved + NULL if no data read and EOF reached +*/ + +static uint8_t * +extend_inputline(FILE *f, uint8_t *start, const char *prompt) +{ +uint8_t *here = start; + +for (;;) + { + size_t rlen = (size_t)(pbuffer8_size - (here - buffer)); + + if (rlen > 1000) + { + int dlen; + + /* If libreadline or libedit support is required, use readline() to read a + line if the input is a terminal. Note that readline() removes the trailing + newline, so we must put it back again, to be compatible with fgets(). */ + +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) + if (INTERACTIVE(f)) + { + size_t len; + char *s = readline(prompt); + if (s == NULL) return (here == start)? NULL : start; + len = strlen(s); + if (len > 0) add_history(s); + if (len > rlen - 1) len = rlen - 1; + memcpy(here, s, len); + here[len] = '\n'; + here[len+1] = 0; + free(s); + } + else +#endif + + /* Read the next line by normal means, prompting if the file is a tty. */ + + { + if (INTERACTIVE(f)) printf("%s", prompt); + if (fgets((char *)here, rlen, f) == NULL) + return (here == start)? NULL : start; + } + + dlen = (int)strlen((char *)here); + if (dlen > 0 && here[dlen - 1] == '\n') return start; + here += dlen; + } + + else + { + size_t start_offset = start - buffer; + size_t here_offset = here - buffer; + expand_input_buffers(); + start = buffer + start_offset; + here = buffer + here_offset; + } + } + +/* Control never gets here */ +} + + + +/************************************************* +* Case-independent strncmp() function * +*************************************************/ + +/* +Arguments: + s first string + t second string + n number of characters to compare + +Returns: < 0, = 0, or > 0, according to the comparison +*/ + +static int +strncmpic(const uint8_t *s, const uint8_t *t, int n) +{ +while (n--) + { + int c = tolower(*s++) - tolower(*t++); + if (c) return c; + } +return 0; +} + + + +/************************************************* +* Scan the main modifier list * +*************************************************/ + +/* This function searches the modifier list for a long modifier name. + +Argument: + p start of the name + lenp length of the name + +Returns: an index in the modifier list, or -1 on failure +*/ + +static int +scan_modifiers(const uint8_t *p, unsigned int len) +{ +int bot = 0; +int top = MODLISTCOUNT; + +while (top > bot) + { + int mid = (bot + top)/2; + unsigned int mlen = strlen(modlist[mid].name); + int c = strncmp((char *)p, modlist[mid].name, (len < mlen)? len : mlen); + if (c == 0) + { + if (len == mlen) return mid; + c = (int)len - (int)mlen; + } + if (c > 0) bot = mid + 1; else top = mid; + } + +return -1; + +} + + + +/************************************************* +* Check a modifer and find its field * +*************************************************/ + +/* This function is called when a modifier has been identified. We check that +it is allowed here and find the field that is to be changed. + +Arguments: + m the modifier list entry + ctx CTX_PAT => pattern context + CTX_POPPAT => pattern context for popped pattern + CTX_DEFPAT => default pattern context + CTX_DAT => data context + CTX_DEFDAT => default data context + pctl point to pattern control block + dctl point to data control block + c a single character or 0 + +Returns: a field pointer or NULL +*/ + +static void * +check_modifier(modstruct *m, int ctx, patctl *pctl, datctl *dctl, uint32_t c) +{ +void *field = NULL; +PCRE2_SIZE offset = m->offset; + +if (restrict_for_perl_test) switch(m->which) + { + case MOD_PNDP: + case MOD_PATP: + case MOD_PDP: + break; + + default: + fprintf(outfile, "** '%s' is not allowed in a Perl-compatible test\n", + m->name); + return NULL; + } + +switch (m->which) + { + case MOD_CTC: /* Compile context modifier */ + if (ctx == CTX_DEFPAT) field = PTR(default_pat_context); + else if (ctx == CTX_PAT) field = PTR(pat_context); + break; + + case MOD_CTM: /* Match context modifier */ + if (ctx == CTX_DEFDAT) field = PTR(default_dat_context); + else if (ctx == CTX_DAT) field = PTR(dat_context); + break; + + case MOD_DAT: /* Data line modifier */ + if (dctl != NULL) field = dctl; + break; + + case MOD_PAT: /* Pattern modifier */ + case MOD_PATP: /* Allowed for Perl test */ + if (pctl != NULL) field = pctl; + break; + + case MOD_PD: /* Pattern or data line modifier */ + case MOD_PDP: /* Ditto, allowed for Perl test */ + case MOD_PND: /* Ditto, but not default pattern */ + case MOD_PNDP: /* Ditto, allowed for Perl test */ + if (dctl != NULL) field = dctl; + else if (pctl != NULL && (m->which == MOD_PD || ctx != CTX_DEFPAT)) + field = pctl; + break; + } + +if (field == NULL) + { + if (c == 0) + fprintf(outfile, "** '%s' is not valid here\n", m->name); + else + fprintf(outfile, "** /%c is not valid here\n", c); + return NULL; + } + +return (char *)field + offset; +} + + + +/************************************************* +* Decode a modifier list * +*************************************************/ + +/* A pointer to a control block is NULL when called in cases when that block is +not relevant. They are never all relevant in one call. At least one of patctl +and datctl is NULL. The second argument specifies which context to use for +modifiers that apply to contexts. + +Arguments: + p point to modifier string + ctx CTX_PAT => pattern context + CTX_POPPAT => pattern context for popped pattern + CTX_DEFPAT => default pattern context + CTX_DAT => data context + CTX_DEFDAT => default data context + pctl point to pattern control block + dctl point to data control block + +Returns: TRUE if successful decode, FALSE otherwise +*/ + +static BOOL +decode_modifiers(uint8_t *p, int ctx, patctl *pctl, datctl *dctl) +{ +uint8_t *ep, *pp; +long li; +unsigned long uli; +BOOL first = TRUE; + +for (;;) + { + void *field; + modstruct *m; + BOOL off = FALSE; + unsigned int i, len; + int index; + char *endptr; + + /* Skip white space and commas. */ + + while (isspace(*p) || *p == ',') p++; + if (*p == 0) break; + + /* Find the end of the item; lose trailing whitespace at end of line. */ + + for (ep = p; *ep != 0 && *ep != ','; ep++); + if (*ep == 0) + { + while (ep > p && isspace(ep[-1])) ep--; + *ep = 0; + } + + /* Remember if the first character is '-'. */ + + if (*p == '-') + { + off = TRUE; + p++; + } + + /* Find the length of a full-length modifier name, and scan for it. */ + + pp = p; + while (pp < ep && *pp != '=') pp++; + index = scan_modifiers(p, pp - p); + + /* If the first modifier is unrecognized, try to interpret it as a sequence + of single-character abbreviated modifiers. None of these modifiers have any + associated data. They just set options or control bits. */ + + if (index < 0) + { + uint32_t cc; + uint8_t *mp = p; + + if (!first) + { + fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p); + if (ep - p == 1) + fprintf(outfile, "** Single-character modifiers must come first\n"); + return FALSE; + } + + for (cc = *p; cc != ',' && cc != '\n' && cc != 0; cc = *(++p)) + { + for (i = 0; i < C1MODLISTCOUNT; i++) + if (cc == c1modlist[i].onechar) break; + + if (i >= C1MODLISTCOUNT) + { + fprintf(outfile, "** Unrecognized modifier '%c' in '%.*s'\n", + *p, (int)(ep-mp), mp); + return FALSE; + } + + if (c1modlist[i].index >= 0) + { + index = c1modlist[i].index; + } + + else + { + index = scan_modifiers((uint8_t *)(c1modlist[i].fullname), + strlen(c1modlist[i].fullname)); + if (index < 0) + { + fprintf(outfile, "** Internal error: single-character equivalent " + "modifier '%s' not found\n", c1modlist[i].fullname); + return FALSE; + } + c1modlist[i].index = index; /* Cache for next time */ + } + + field = check_modifier(modlist + index, ctx, pctl, dctl, *p); + if (field == NULL) return FALSE; + *((uint32_t *)field) |= modlist[index].value; + } + + continue; /* With tne next (fullname) modifier */ + } + + /* We have a match on a full-name modifier. Check for the existence of data + when needed. */ + + m = modlist + index; /* Save typing */ + if (m->type != MOD_CTL && m->type != MOD_OPT && + (m->type != MOD_IND || *pp == '=')) + { + if (*pp++ != '=') + { + fprintf(outfile, "** '=' expected after '%s'\n", m->name); + return FALSE; + } + if (off) + { + fprintf(outfile, "** '-' is not valid for '%s'\n", m->name); + return FALSE; + } + } + + /* These on/off types have no data. */ + + else if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) + { + fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p); + return FALSE; + } + + /* Set the data length for those types that have data. Then find the field + that is to be set. If check_modifier() returns NULL, it has already output an + error message. */ + + len = ep - pp; + field = check_modifier(m, ctx, pctl, dctl, 0); + if (field == NULL) return FALSE; + + /* Process according to data type. */ + + switch (m->type) + { + case MOD_CTL: + case MOD_OPT: + if (off) *((uint32_t *)field) &= ~m->value; + else *((uint32_t *)field) |= m->value; + break; + + case MOD_BSR: + if (len == 7 && strncmpic(pp, (const uint8_t *)"default", 7) == 0) + { +#ifdef BSR_ANYCRLF + *((uint16_t *)field) = PCRE2_BSR_ANYCRLF; +#else + *((uint16_t *)field) = PCRE2_BSR_UNICODE; +#endif + if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_BSR_SET; + else dctl->control &= ~CTL_BSR_SET; + } + else + { + if (len == 7 && strncmpic(pp, (const uint8_t *)"anycrlf", 7) == 0) + *((uint16_t *)field) = PCRE2_BSR_ANYCRLF; + else if (len == 7 && strncmpic(pp, (const uint8_t *)"unicode", 7) == 0) + *((uint16_t *)field) = PCRE2_BSR_UNICODE; + else goto INVALID_VALUE; + if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_BSR_SET; + else dctl->control |= CTL_BSR_SET; + } + pp = ep; + break; + + case MOD_IN2: /* One or two unsigned integers */ + if (!isdigit(*pp)) goto INVALID_VALUE; + uli = strtoul((const char *)pp, &endptr, 10); + if (U32OVERFLOW(uli)) goto INVALID_VALUE; + ((uint32_t *)field)[0] = (uint32_t)uli; + if (*endptr == ':') + { + uli = strtoul((const char *)endptr+1, &endptr, 10); + if (U32OVERFLOW(uli)) goto INVALID_VALUE; + ((uint32_t *)field)[1] = (uint32_t)uli; + } + else ((uint32_t *)field)[1] = 0; + pp = (uint8_t *)endptr; + break; + + /* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or + less than ULONG_MAX. So first test for overflowing the long int, and then + test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */ + + case MOD_SIZ: /* PCRE2_SIZE value */ + if (!isdigit(*pp)) goto INVALID_VALUE; + uli = strtoul((const char *)pp, &endptr, 10); + if (uli == ULONG_MAX) goto INVALID_VALUE; +#if ULONG_MAX > PCRE2_SIZE_MAX + if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE; +#endif + *((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli; + pp = (uint8_t *)endptr; + break; + + case MOD_IND: /* Unsigned integer with default */ + if (len == 0) + { + *((uint32_t *)field) = (uint32_t)(m->value); + break; + } + /* Fall through */ + + case MOD_INT: /* Unsigned integer */ + if (!isdigit(*pp)) goto INVALID_VALUE; + uli = strtoul((const char *)pp, &endptr, 10); + if (U32OVERFLOW(uli)) goto INVALID_VALUE; + *((uint32_t *)field) = (uint32_t)uli; + pp = (uint8_t *)endptr; + break; + + case MOD_INS: /* Signed integer */ + if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE; + li = strtol((const char *)pp, &endptr, 10); + if (S32OVERFLOW(li)) goto INVALID_VALUE; + *((int32_t *)field) = (int32_t)li; + pp = (uint8_t *)endptr; + break; + + case MOD_NL: + for (i = 0; i < sizeof(newlines)/sizeof(char *); i++) + if (len == strlen(newlines[i]) && + strncmpic(pp, (const uint8_t *)newlines[i], len) == 0) break; + if (i >= sizeof(newlines)/sizeof(char *)) goto INVALID_VALUE; + if (i == 0) + { + *((uint16_t *)field) = NEWLINE_DEFAULT; + if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_NL_SET; + else dctl->control &= ~CTL_NL_SET; + } + else + { + *((uint16_t *)field) = i; + if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_NL_SET; + else dctl->control |= CTL_NL_SET; + } + pp = ep; + break; + + case MOD_NN: /* Name or (signed) number; may be several */ + if (isdigit(*pp) || *pp == '-') + { + int ct = MAXCPYGET - 1; + int32_t value; + li = strtol((const char *)pp, &endptr, 10); + if (S32OVERFLOW(li)) goto INVALID_VALUE; + value = (int32_t)li; + field = (char *)field - m->offset + m->value; /* Adjust field ptr */ + if (value >= 0) /* Add new number */ + { + while (*((int32_t *)field) >= 0 && ct-- > 0) /* Skip previous */ + field = (char *)field + sizeof(int32_t); + if (ct <= 0) + { + fprintf(outfile, "** Too many numeric '%s' modifiers\n", m->name); + return FALSE; + } + } + *((int32_t *)field) = value; + if (ct > 0) ((int32_t *)field)[1] = -1; + pp = (uint8_t *)endptr; + } + + /* Multiple strings are put end to end. */ + + else + { + char *nn = (char *)field; + if (len > 0) /* Add new name */ + { + while (*nn != 0) nn += strlen(nn) + 1; + if (nn + len + 1 - (char *)field > LENCPYGET) + { + fprintf(outfile, "** Too many named '%s' modifiers\n", m->name); + return FALSE; + } + memcpy(nn, pp, len); + } + nn[len] = 0 ; + nn[len+1] = 0; + pp = ep; + } + break; + + case MOD_STR: + if (len + 1 > m->value) + { + fprintf(outfile, "** Overlong value for '%s' (max %d code units)\n", + m->name, m->value - 1); + return FALSE; + } + memcpy(field, pp, len); + ((uint8_t *)field)[len] = 0; + pp = ep; + break; + } + + if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) + { + fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name); + return FALSE; + } + + p = pp; + first = FALSE; + + if (ctx == CTX_POPPAT && + (pctl->options != 0 || + pctl->tables_id != 0 || + pctl->locale[0] != 0 || + (pctl->control & NOTPOP_CONTROLS) != 0)) + { + fprintf(outfile, "** '%s' is not valid here\n", m->name); + return FALSE; + } + } + +return TRUE; + +INVALID_VALUE: +fprintf(outfile, "** Invalid value in '%.*s'\n", (int)(ep-p), p); +return FALSE; +} + + +/************************************************* +* Get info from a pattern * +*************************************************/ + +/* A wrapped call to pcre2_pattern_info(), applied to the current compiled +pattern. + +Arguments: + what code for the required information + where where to put the answer + unsetok PCRE2_ERROR_UNSET is an "expected" result + +Returns: the return from pcre2_pattern_info() +*/ + +static int +pattern_info(int what, void *where, BOOL unsetok) +{ +int rc; +PCRE2_PATTERN_INFO(rc, compiled_code, what, where); +if (rc >= 0) return 0; +if (rc != PCRE2_ERROR_UNSET || !unsetok) + { + fprintf(outfile, "Error %d from pcre2_pattern_info_%d(%d)\n", rc, test_mode, + what); + if (rc == PCRE2_ERROR_BADMODE) + fprintf(outfile, "Running in %d-bit mode but pattern was compiled in " + "%d-bit mode\n", test_mode, + 8 * (FLD(compiled_code, flags) & PCRE2_MODE_MASK)); + } +return rc; +} + + + +#ifdef SUPPORT_PCRE2_8 +/************************************************* +* Show something in a list * +*************************************************/ + +/* This function just helps to keep the code that uses it tidier. It's used for +various lists of things where there needs to be introductory text before the +first item. As these calls are all in the POSIX-support code, they happen only +when 8-bit mode is supported. */ + +static void +prmsg(const char **msg, const char *s) +{ +fprintf(outfile, "%s %s", *msg, s); +*msg = ""; +} +#endif /* SUPPORT_PCRE2_8 */ + + + +/************************************************* +* Show control bits * +*************************************************/ + +/* Called for mutually exclusive controls and for unsupported POSIX controls. +Because the bits are unique, this can be used for both pattern and data control +words. + +Arguments: + controls control bits + controls2 more control bits + before text to print before + +Returns: nothing +*/ + +static void +show_controls(uint32_t controls, uint32_t controls2, const char *before) +{ +fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + before, + ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "", + ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "", + ((controls & CTL_ALLCAPTURES) != 0)? " allcaptures" : "", + ((controls & CTL_ALLUSEDTEXT) != 0)? " allusedtext" : "", + ((controls & CTL_ALTGLOBAL) != 0)? " altglobal" : "", + ((controls & CTL_BINCODE) != 0)? " bincode" : "", + ((controls & CTL_BSR_SET) != 0)? " bsr" : "", + ((controls & CTL_CALLOUT_CAPTURE) != 0)? " callout_capture" : "", + ((controls & CTL_CALLOUT_INFO) != 0)? " callout_info" : "", + ((controls & CTL_CALLOUT_NONE) != 0)? " callout_none" : "", + ((controls & CTL_DFA) != 0)? " dfa" : "", + ((controls & CTL_EXPAND) != 0)? " expand" : "", + ((controls & CTL_FINDLIMITS) != 0)? " find_limits" : "", + ((controls & CTL_FULLBINCODE) != 0)? " fullbincode" : "", + ((controls & CTL_GETALL) != 0)? " getall" : "", + ((controls & CTL_GLOBAL) != 0)? " global" : "", + ((controls & CTL_HEXPAT) != 0)? " hex" : "", + ((controls & CTL_INFO) != 0)? " info" : "", + ((controls & CTL_JITFAST) != 0)? " jitfast" : "", + ((controls & CTL_JITVERIFY) != 0)? " jitverify" : "", + ((controls & CTL_MARK) != 0)? " mark" : "", + ((controls & CTL_MEMORY) != 0)? " memory" : "", + ((controls & CTL_NL_SET) != 0)? " newline" : "", + ((controls & CTL_NULLCONTEXT) != 0)? " null_context" : "", + ((controls & CTL_POSIX) != 0)? " posix" : "", + ((controls & CTL_PUSH) != 0)? " push" : "", + ((controls & CTL_STARTCHAR) != 0)? " startchar" : "", + ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "", + ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "", + ((controls2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) != 0)? " substitute_unknown_unset" : "", + ((controls2 & CTL2_SUBSTITUTE_UNSET_EMPTY) != 0)? " substitute_unset_empty" : "", + ((controls & CTL_ZERO_TERMINATE) != 0)? " zero_terminate" : ""); +} + + + +/************************************************* +* Show compile options * +*************************************************/ + +/* Called from show_pattern_info() and for unsupported POSIX options. + +Arguments: + options an options word + before text to print before + after text to print after + +Returns: nothing +*/ + +static void +show_compile_options(uint32_t options, const char *before, const char *after) +{ +if (options == 0) fprintf(outfile, "%s %s", before, after); +else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + before, + ((options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "", + ((options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "", + ((options & PCRE2_ALT_VERBNAMES) != 0)? " alt_verbnames" : "", + ((options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? " allow_empty_class" : "", + ((options & PCRE2_ANCHORED) != 0)? " anchored" : "", + ((options & PCRE2_AUTO_CALLOUT) != 0)? " auto_callout" : "", + ((options & PCRE2_CASELESS) != 0)? " caseless" : "", + ((options & PCRE2_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", + ((options & PCRE2_DOTALL) != 0)? " dotall" : "", + ((options & PCRE2_DUPNAMES) != 0)? " dupnames" : "", + ((options & PCRE2_EXTENDED) != 0)? " extended" : "", + ((options & PCRE2_FIRSTLINE) != 0)? " firstline" : "", + ((options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "", + ((options & PCRE2_MULTILINE) != 0)? " multiline" : "", + ((options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "", + ((options & PCRE2_NEVER_UCP) != 0)? " never_ucp" : "", + ((options & PCRE2_NEVER_UTF) != 0)? " never_utf" : "", + ((options & PCRE2_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "", + ((options & PCRE2_NO_AUTO_POSSESS) != 0)? " no_auto_possess" : "", + ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? " no_dotstar_anchor" : "", + ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "", + ((options & PCRE2_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "", + ((options & PCRE2_UCP) != 0)? " ucp" : "", + ((options & PCRE2_UNGREEDY) != 0)? " ungreedy" : "", + ((options & PCRE2_USE_OFFSET_LIMIT) != 0)? " use_offset_limit" : "", + ((options & PCRE2_UTF) != 0)? " utf" : "", + after); +} + + + +#ifdef SUPPORT_PCRE2_8 +/************************************************* +* Show match options * +*************************************************/ + +/* Called for unsupported POSIX options. */ + +static void +show_match_options(uint32_t options) +{ +fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s", + ((options & PCRE2_ANCHORED) != 0)? " anchored" : "", + ((options & PCRE2_DFA_RESTART) != 0)? " dfa_restart" : "", + ((options & PCRE2_DFA_SHORTEST) != 0)? " dfa_shortest" : "", + ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "", + ((options & PCRE2_NOTBOL) != 0)? " notbol" : "", + ((options & PCRE2_NOTEMPTY) != 0)? " notempty" : "", + ((options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "", + ((options & PCRE2_NOTEOL) != 0)? " noteol" : "", + ((options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "", + ((options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : ""); +} +#endif /* SUPPORT_PCRE2_8 */ + + + +/************************************************* +* Show memory usage info for a pattern * +*************************************************/ + +static void +show_memory_info(void) +{ +uint32_t name_count, name_entry_size; +size_t size, cblock_size; + +#ifdef SUPPORT_PCRE2_8 +if (test_mode == 8) cblock_size = sizeof(pcre2_real_code_8); +#endif +#ifdef SUPPORT_PCRE2_16 +if (test_mode == 16) cblock_size = sizeof(pcre2_real_code_16); +#endif +#ifdef SUPPORT_PCRE2_32 +if (test_mode == 32) cblock_size = sizeof(pcre2_real_code_32); +#endif + +(void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE); +(void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE); +(void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE); +fprintf(outfile, "Memory allocation (code space): %d\n", + (int)(size - name_count*name_entry_size*code_unit_size - cblock_size)); +if (pat_patctl.jit != 0) + { + (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE); + fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)size); + } +} + + + +/************************************************* +* Callback function for callout enumeration * +*************************************************/ + +/* The only differences in the callout emumeration block for different code +unit widths are that the pointers to the subject, the most recent MARK, and a +callout argument string point to strings of the appropriate width. Casts can be +used to deal with this. + +Argument: + cb pointer to enumerate block + callout_data user data + +Returns: 0 +*/ + +static int callout_callback(pcre2_callout_enumerate_block_8 *cb, + void *callout_data) +{ +uint32_t i; +BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; + +(void)callout_data; /* Not currently displayed */ + +fprintf(outfile, "Callout "); +if (cb->callout_string != NULL) + { + uint32_t delimiter = CODE_UNIT(cb->callout_string, -1); + fprintf(outfile, "%c", delimiter); + PCHARSV(cb->callout_string, 0, + cb->callout_string_length, utf, outfile); + for (i = 0; callout_start_delims[i] != 0; i++) + if (delimiter == callout_start_delims[i]) + { + delimiter = callout_end_delims[i]; + break; + } + fprintf(outfile, "%c ", delimiter); + } +else fprintf(outfile, "%d ", cb->callout_number); + +fprintf(outfile, "%.*s\n", + (int)((cb->next_item_length == 0)? 1 : cb->next_item_length), + pbuffer8 + cb->pattern_position); + +return 0; +} + + + +/************************************************* +* Show information about a pattern * +*************************************************/ + +/* This function is called after a pattern has been compiled if any of the +information-requesting controls have been set. + +Arguments: none + +Returns: PR_OK continue processing next line + PR_SKIP skip to a blank line + PR_ABEND abort the pcre2test run +*/ + +static int +show_pattern_info(void) +{ +uint32_t compile_options, overall_options; + +if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0) + { + fprintf(outfile, "------------------------------------------------------------------\n"); + PCRE2_PRINTINT((pat_patctl.control & CTL_FULLBINCODE) != 0); + } + +if ((pat_patctl.control & CTL_INFO) != 0) + { + const void *nametable; + const uint8_t *start_bits; + BOOL match_limit_set, recursion_limit_set; + uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit, + hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty, + match_limit, minlength, nameentrysize, namecount, newline_convention, + recursion_limit; + + /* These info requests may return PCRE2_ERROR_UNSET. */ + + switch(pattern_info(PCRE2_INFO_MATCHLIMIT, &match_limit, TRUE)) + { + case 0: + match_limit_set = TRUE; + break; + + case PCRE2_ERROR_UNSET: + match_limit_set = FALSE; + break; + + default: + return PR_ABEND; + } + + switch(pattern_info(PCRE2_INFO_RECURSIONLIMIT, &recursion_limit, TRUE)) + { + case 0: + recursion_limit_set = TRUE; + break; + + case PCRE2_ERROR_UNSET: + recursion_limit_set = FALSE; + break; + + default: + return PR_ABEND; + } + + /* These info requests should always succeed. */ + + if (pattern_info(PCRE2_INFO_BACKREFMAX, &backrefmax, FALSE) + + pattern_info(PCRE2_INFO_BSR, &bsr_convention, FALSE) + + pattern_info(PCRE2_INFO_CAPTURECOUNT, &capture_count, FALSE) + + pattern_info(PCRE2_INFO_FIRSTBITMAP, &start_bits, FALSE) + + pattern_info(PCRE2_INFO_FIRSTCODEUNIT, &first_cunit, FALSE) + + pattern_info(PCRE2_INFO_FIRSTCODETYPE, &first_ctype, FALSE) + + pattern_info(PCRE2_INFO_HASBACKSLASHC, &hasbackslashc, FALSE) + + pattern_info(PCRE2_INFO_HASCRORLF, &hascrorlf, FALSE) + + pattern_info(PCRE2_INFO_JCHANGED, &jchanged, FALSE) + + pattern_info(PCRE2_INFO_LASTCODEUNIT, &last_cunit, FALSE) + + pattern_info(PCRE2_INFO_LASTCODETYPE, &last_ctype, FALSE) + + pattern_info(PCRE2_INFO_MATCHEMPTY, &match_empty, FALSE) + + pattern_info(PCRE2_INFO_MINLENGTH, &minlength, FALSE) + + pattern_info(PCRE2_INFO_NAMECOUNT, &namecount, FALSE) + + pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize, FALSE) + + pattern_info(PCRE2_INFO_NAMETABLE, &nametable, FALSE) + + pattern_info(PCRE2_INFO_NEWLINE, &newline_convention, FALSE) + != 0) + return PR_ABEND; + + fprintf(outfile, "Capturing subpattern count = %d\n", capture_count); + + if (backrefmax > 0) + fprintf(outfile, "Max back reference = %d\n", backrefmax); + + if (maxlookbehind > 0) + fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind); + + if (match_limit_set) + fprintf(outfile, "Match limit = %u\n", match_limit); + + if (recursion_limit_set) + fprintf(outfile, "Recursion limit = %u\n", recursion_limit); + + if (namecount > 0) + { + fprintf(outfile, "Named capturing subpatterns:\n"); + for (; namecount > 0; namecount--) + { + int imm2_size = test_mode == PCRE8_MODE ? 2 : 1; + uint32_t length = (uint32_t)STRLEN(nametable + imm2_size); + fprintf(outfile, " "); + PCHARSV(nametable, imm2_size, length, FALSE, outfile); + while (length++ < nameentrysize - imm2_size) putc(' ', outfile); +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE) + fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR32)nametable)[0])); +#endif +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE) + fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR16)nametable)[0])); +#endif +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) + fprintf(outfile, "%3d\n", (int)( + ((((PCRE2_SPTR8)nametable)[0]) << 8) | ((PCRE2_SPTR8)nametable)[1])); +#endif + nametable = (void*)((PCRE2_SPTR8)nametable + nameentrysize * code_unit_size); + } + } + + if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); + if (hasbackslashc) fprintf(outfile, "Contains \\C\n"); + if (match_empty) fprintf(outfile, "May match empty string\n"); + + pattern_info(PCRE2_INFO_ARGOPTIONS, &compile_options, FALSE); + pattern_info(PCRE2_INFO_ALLOPTIONS, &overall_options, FALSE); + + /* Remove UTF/UCP if they were there only because of forbid_utf. This saves + cluttering up the verification output of non-UTF test files. */ + + if ((pat_patctl.options & PCRE2_NEVER_UTF) == 0) + { + compile_options &= ~PCRE2_NEVER_UTF; + overall_options &= ~PCRE2_NEVER_UTF; + } + + if ((pat_patctl.options & PCRE2_NEVER_UCP) == 0) + { + compile_options &= ~PCRE2_NEVER_UCP; + overall_options &= ~PCRE2_NEVER_UCP; + } + + if ((compile_options|overall_options) != 0) + { + if (compile_options == overall_options) + show_compile_options(compile_options, "Options:", "\n"); + else + { + show_compile_options(compile_options, "Compile options:", "\n"); + show_compile_options(overall_options, "Overall options:", "\n"); + } + } + + if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); + + if ((pat_patctl.control & CTL_BSR_SET) != 0 || + (FLD(compiled_code, flags) & PCRE2_BSR_SET) != 0) + fprintf(outfile, "\\R matches %s\n", (bsr_convention == PCRE2_BSR_UNICODE)? + "any Unicode newline" : "CR, LF, or CRLF"); + + if ((FLD(compiled_code, flags) & PCRE2_NL_SET) != 0) + { + switch (newline_convention) + { + case PCRE2_NEWLINE_CR: + fprintf(outfile, "Forced newline is CR\n"); + break; + + case PCRE2_NEWLINE_LF: + fprintf(outfile, "Forced newline is LF\n"); + break; + + case PCRE2_NEWLINE_CRLF: + fprintf(outfile, "Forced newline is CRLF\n"); + break; + + case PCRE2_NEWLINE_ANYCRLF: + fprintf(outfile, "Forced newline is CR, LF, or CRLF\n"); + break; + + case PCRE2_NEWLINE_ANY: + fprintf(outfile, "Forced newline is any Unicode newline\n"); + break; + + default: + break; + } + } + + if (first_ctype == 2) + { + fprintf(outfile, "First code unit at start or follows newline\n"); + } + else if (first_ctype == 1) + { + const char *caseless = + ((FLD(compiled_code, flags) & PCRE2_FIRSTCASELESS) == 0)? + "" : " (caseless)"; + if (PRINTOK(first_cunit)) + fprintf(outfile, "First code unit = \'%c\'%s\n", first_cunit, caseless); + else + { + fprintf(outfile, "First code unit = "); + pchar(first_cunit, FALSE, outfile); + fprintf(outfile, "%s\n", caseless); + } + } + else if (start_bits != NULL) + { + int i; + int c = 24; + fprintf(outfile, "Starting code units: "); + for (i = 0; i < 256; i++) + { + if ((start_bits[i/8] & (1<<(i&7))) != 0) + { + if (c > 75) + { + fprintf(outfile, "\n "); + c = 2; + } + if (PRINTOK(i) && i != ' ') + { + fprintf(outfile, "%c ", i); + c += 2; + } + else + { + fprintf(outfile, "\\x%02x ", i); + c += 5; + } + } + } + fprintf(outfile, "\n"); + } + + if (last_ctype != 0) + { + const char *caseless = + ((FLD(compiled_code, flags) & PCRE2_LASTCASELESS) == 0)? + "" : " (caseless)"; + if (PRINTOK(last_cunit)) + fprintf(outfile, "Last code unit = \'%c\'%s\n", last_cunit, caseless); + else + { + fprintf(outfile, "Last code unit = "); + pchar(last_cunit, FALSE, outfile); + fprintf(outfile, "%s\n", caseless); + } + } + + fprintf(outfile, "Subject length lower bound = %d\n", minlength); + + if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0) + { + if (FLD(compiled_code, executable_jit) != NULL) + fprintf(outfile, "JIT compilation was successful\n"); + else + { +#ifdef SUPPORT_JIT + int len; + fprintf(outfile, "JIT compilation was not successful"); + if (jitrc != 0) + { + fprintf(outfile, " ("); + PCRE2_GET_ERROR_MESSAGE(len, jitrc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); + fprintf(outfile, ")"); + } + fprintf(outfile, "\n"); +#else + fprintf(outfile, "JIT support is not available in this version of PCRE2\n"); +#endif + } + } + } + +if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0) + { + int errorcode; + PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0); + if (errorcode != 0) + { + int len; + fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode); + if (errorcode < 0) + { + PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); + } + fprintf(outfile, "\n"); + return PR_SKIP; + } + } + +return PR_OK; +} + + + +/************************************************* +* Handle serialization error * +*************************************************/ + +/* Print an error message after a serialization failure. + +Arguments: + rc the error code + msg an initial message for what failed + +Returns: nothing +*/ + +static void +serial_error(int rc, const char *msg) +{ +fprintf(outfile, "%s failed: error %d: ", msg, rc); +PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); +PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); +fprintf(outfile, "\n"); +} + + + +/************************************************* +* Open file for save/load commands * +*************************************************/ + +/* This function decodes the file name and opens the file. + +Arguments: + buffptr point after the #command + mode open mode + fptr points to the FILE variable + +Returns: PR_OK or PR_ABEND +*/ + +static int +open_file(uint8_t *buffptr, const char *mode, FILE **fptr) +{ +char *endf; +char *filename = (char *)buffptr; +while (isspace(*filename)) filename++; +endf = filename + strlen8(filename); +while (endf > filename && isspace(endf[-1])) endf--; + +if (endf == filename) + { + fprintf(outfile, "** File name expected after #save\n"); + return PR_ABEND; + } + +*endf = 0; +*fptr = fopen((const char *)filename, mode); +if (*fptr == NULL) + { + fprintf(outfile, "** Failed to open '%s'\n", filename); + return PR_ABEND; + } + +return PR_OK; +} + + + +/************************************************* +* Process command line * +*************************************************/ + +/* This function is called for lines beginning with # and a character that is +not ! or whitespace, when encountered between tests, which means that there is +no compiled pattern (compiled_code is NULL). The line is in buffer. + +Arguments: none + +Returns: PR_OK continue processing next line + PR_SKIP skip to a blank line + PR_ABEND abort the pcre2test run +*/ + +static int +process_command(void) +{ +FILE *f; +PCRE2_SIZE serial_size; +size_t i; +int rc, cmd, cmdlen; +uint16_t first_listed_newline; +const char *cmdname; +uint8_t *argptr, *serial; + +if (restrict_for_perl_test) + { + fprintf(outfile, "** #-commands are not allowed after #perltest\n"); + return PR_ABEND; + } + +cmd = CMD_UNKNOWN; +cmdlen = 0; + +for (i = 0; i < cmdlistcount; i++) + { + cmdname = cmdlist[i].name; + cmdlen = strlen(cmdname); + if (strncmp((char *)(buffer+1), cmdname, cmdlen) == 0 && + isspace(buffer[cmdlen+1])) + { + cmd = cmdlist[i].value; + break; + } + } + +argptr = buffer + cmdlen + 1; + +switch(cmd) + { + case CMD_UNKNOWN: + fprintf(outfile, "** Unknown command: %s", buffer); + break; + + case CMD_FORBID_UTF: + forbid_utf = PCRE2_NEVER_UTF|PCRE2_NEVER_UCP; + break; + + case CMD_PERLTEST: + restrict_for_perl_test = TRUE; + break; + + /* Set default pattern modifiers */ + + case CMD_PATTERN: + (void)decode_modifiers(argptr, CTX_DEFPAT, &def_patctl, NULL); + if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0) + def_patctl.jit = 7; + break; + + /* Set default subject modifiers */ + + case CMD_SUBJECT: + (void)decode_modifiers(argptr, CTX_DEFDAT, NULL, &def_datctl); + break; + + /* Check the default newline, and if not one of those listed, set up the + first one to be forced. An empty list unsets. */ + + case CMD_NEWLINE_DEFAULT: + local_newline_default = 0; /* Unset */ + first_listed_newline = 0; + for (;;) + { + while (isspace(*argptr)) argptr++; + if (*argptr == 0) break; + for (i = 1; i < sizeof(newlines)/sizeof(char *); i++) + { + size_t nlen = strlen(newlines[i]); + if (strncmpic(argptr, (const uint8_t *)newlines[i], nlen) == 0 && + isspace(argptr[nlen])) + { + if (i == NEWLINE_DEFAULT) return PR_OK; /* Default is valid */ + if (first_listed_newline == 0) first_listed_newline = i; + } + } + while (*argptr != 0 && !isspace(*argptr)) argptr++; + } + local_newline_default = first_listed_newline; + break; + + /* Pop a compiled pattern off the stack. Modifiers that do not affect the + compiled pattern (e.g. to give information) are permitted. The default + pattern modifiers are ignored. */ + + case CMD_POP: + if (patstacknext <= 0) + { + fprintf(outfile, "** Can't pop off an empty stack\n"); + return PR_SKIP; + } + memset(&pat_patctl, 0, sizeof(patctl)); /* Completely unset */ + if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL)) + return PR_SKIP; + SET(compiled_code, patstack[--patstacknext]); + if (pat_patctl.jit != 0) + { + PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit); + } + if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info(); + if ((pat_patctl.control & CTL_ANYINFO) != 0) + { + rc = show_pattern_info(); + if (rc != PR_OK) return rc; + } + break; + + /* Save the stack of compiled patterns to a file, then empty the stack. */ + + case CMD_SAVE: + if (patstacknext <= 0) + { + fprintf(outfile, "** No stacked patterns to save\n"); + return PR_OK; + } + + rc = open_file(argptr+1, BINARY_OUTPUT_MODE, &f); + if (rc != PR_OK) return rc; + + PCRE2_SERIALIZE_ENCODE(rc, patstack, patstacknext, &serial, &serial_size, + general_context); + if (rc < 0) + { + serial_error(rc, "Serialization"); + break; + } + + /* Write the length at the start of the file to make it straightforward to + get the right memory when re-loading. This saves having to read the file size + in different operating systems. To allow for different endianness (even + though reloading with the opposite endianness does not work), write the + length byte-by-byte. */ + + for (i = 0; i < 4; i++) fputc((serial_size >> (i*8)) & 255, f); + if (fwrite(serial, 1, serial_size, f) != serial_size) + { + fprintf(outfile, "** Wrong return from fwrite()\n"); + return PR_ABEND; + } + + fclose(f); + PCRE2_SERIALIZE_FREE(serial); + while(patstacknext > 0) + { + SET(compiled_code, patstack[--patstacknext]); + SUB1(pcre2_code_free, compiled_code); + } + SET(compiled_code, NULL); + break; + + /* Load a set of compiled patterns from a file onto the stack */ + + case CMD_LOAD: + rc = open_file(argptr+1, BINARY_INPUT_MODE, &f); + if (rc != PR_OK) return rc; + + serial_size = 0; + for (i = 0; i < 4; i++) serial_size |= fgetc(f) << (i*8); + + serial = malloc(serial_size); + if (serial == NULL) + { + fprintf(outfile, "** Failed to get memory (size %lu) for #load\n", + (unsigned long int)serial_size); + return PR_ABEND; + } + + if (fread(serial, 1, serial_size, f) != serial_size) + { + fprintf(outfile, "** Wrong return from fread()\n"); + return PR_ABEND; + } + fclose(f); + + PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial); + if (rc < 0) serial_error(rc, "Get number of codes"); else + { + if (rc + patstacknext > PATSTACKSIZE) + { + fprintf(outfile, "** Not enough space on pattern stack for %d pattern%s\n", + rc, (rc == 1)? "" : "s"); + rc = PATSTACKSIZE - patstacknext; + fprintf(outfile, "** Decoding %d pattern%s\n", rc, + (rc == 1)? "" : "s"); + } + PCRE2_SERIALIZE_DECODE(rc, patstack + patstacknext, rc, serial, + general_context); + if (rc < 0) serial_error(rc, "Deserialization"); + else patstacknext += rc; + } + + free(serial); + break; + } + +return PR_OK; +} + + + +/************************************************* +* Process pattern line * +*************************************************/ + +/* This function is called when the input buffer contains the start of a +pattern. The first character is known to be a valid delimiter. The pattern is +read, modifiers are interpreted, and a suitable local context is set up for +this test. The pattern is then compiled. + +Arguments: none + +Returns: PR_OK continue processing next line + PR_SKIP skip to a blank line + PR_ABEND abort the pcre2test run +*/ + +static int +process_pattern(void) +{ +BOOL utf; +uint32_t k; +uint8_t *p = buffer; +const uint8_t *use_tables; +unsigned int delimiter = *p++; +int errorcode; +void *use_pat_context; +PCRE2_SIZE patlen; +PCRE2_SIZE erroroffset; + +/* Initialize the context and pattern/data controls for this test from the +defaults. */ + +PATCTXCPY(pat_context, default_pat_context); +memcpy(&pat_patctl, &def_patctl, sizeof(patctl)); + +/* Find the end of the pattern, reading more lines if necessary. */ + +for(;;) + { + while (*p != 0) + { + if (*p == '\\' && p[1] != 0) p++; + else if (*p == delimiter) break; + p++; + } + if (*p != 0) break; + if ((p = extend_inputline(infile, p, " > ")) == NULL) + { + fprintf(outfile, "** Unexpected EOF\n"); + return PR_ABEND; + } + if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)p); + } + +/* If the first character after the delimiter is backslash, make the pattern +end with backslash. This is purely to provide a way of testing for the error +message when a pattern ends with backslash. */ + +if (p[1] == '\\') *p++ = '\\'; + +/* Terminate the pattern at the delimiter, and compute the length. */ + +*p++ = 0; +patlen = p - buffer - 2; + +/* Look for modifiers and options after the final delimiter. */ + +if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP; +utf = (pat_patctl.options & PCRE2_UTF) != 0; + +/* Check for mutually exclusive modifiers. At present, these are all in the +first control word. */ + +for (k = 0; k < sizeof(exclusive_pat_controls)/sizeof(uint32_t); k++) + { + uint32_t c = pat_patctl.control & exclusive_pat_controls[k]; + if (c != 0 && c != (c & (~c+1))) + { + show_controls(c, 0, "** Not allowed together:"); + fprintf(outfile, "\n"); + return PR_SKIP; + } + } + +/* Assume full JIT compile for jitverify and/or jitfast if nothing else was +specified. */ + +if (pat_patctl.jit == 0 && + (pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0) + pat_patctl.jit = 7; + +/* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting +in callouts. Convert from hex if required; this must necessarily be fewer +characters so will always fit in pbuffer8. Alternatively, process for +repetition if requested. */ + +if ((pat_patctl.control & CTL_HEXPAT) != 0) + { + uint8_t *pp, *pt; + uint32_t c, d; + + pt = pbuffer8; + for (pp = buffer + 1; *pp != 0; pp++) + { + if (isspace(*pp)) continue; + c = toupper(*pp++); + if (*pp == 0) + { + fprintf(outfile, "** Odd number of digits in hex pattern.\n"); + return PR_SKIP; + } + d = toupper(*pp); + if (!isxdigit(c) || !isxdigit(d)) + { + fprintf(outfile, "** Non-hex-digit in hex pattern.\n"); + return PR_SKIP; + } + *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) + + (isdigit(d)? (d - '0') : (d - 'A' + 10)); + } + *pt = 0; + patlen = pt - pbuffer8; + } + +else if ((pat_patctl.control & CTL_EXPAND) != 0) + { + uint8_t *pp, *pt; + + pt = pbuffer8; + for (pp = buffer + 1; *pp != 0; pp++) + { + uint8_t *pc = pp; + uint32_t count = 1; + size_t length = 1; + + /* Check for replication syntax; if not found, the defaults just set will + prevail and one character will be copied. */ + + if (pp[0] == '\\' && pp[1] == '[') + { + uint8_t *pe; + for (pe = pp + 2; *pe != 0; pe++) + { + if (pe[0] == ']' && pe[1] == '{') + { + uint32_t clen = pe - pc - 2; + uint32_t i = 0; + pe += 2; + while (isdigit(*pe)) i = i * 10 + *pe++ - '0'; + if (*pe == '}') + { + if (i == 0) + { + fprintf(outfile, "** Zero repeat not allowed\n"); + return PR_SKIP; + } + pc += 2; + count = i; + length = clen; + pp = pe; + break; + } + } + } + } + + /* Add to output. If the buffer is too small expand it. The function for + expanding buffers always keeps buffer and pbuffer8 in step as far as their + size goes. */ + + while (pt + count * length > pbuffer8 + pbuffer8_size) + { + size_t pc_offset = pc - buffer; + size_t pp_offset = pp - buffer; + size_t pt_offset = pt - pbuffer8; + expand_input_buffers(); + pc = buffer + pc_offset; + pp = buffer + pp_offset; + pt = pbuffer8 + pt_offset; + } + + while (count-- > 0) + { + memcpy(pt, pc, length); + pt += length; + } + } + + *pt = 0; + patlen = pt - pbuffer8; + + if ((pat_patctl.control & CTL_INFO) != 0) + fprintf(outfile, "Expanded: %s\n", pbuffer8); + } + +/* Neither hex nor expanded, just copy the input verbatim. */ + +else + { + strncpy((char *)pbuffer8, (char *)(buffer+1), patlen + 1); + } + +/* Sort out character tables */ + +if (pat_patctl.locale[0] != 0) + { + if (pat_patctl.tables_id != 0) + { + fprintf(outfile, "** 'Locale' and 'tables' must not both be set.\n"); + return PR_SKIP; + } + if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale) == NULL) + { + fprintf(outfile, "** Failed to set locale '%s'\n", pat_patctl.locale); + return PR_SKIP; + } + if (strcmp((const char *)pat_patctl.locale, (const char *)locale_name) != 0) + { + strcpy((char *)locale_name, (char *)pat_patctl.locale); + if (locale_tables != NULL) free((void *)locale_tables); + PCRE2_MAKETABLES(locale_tables); + } + use_tables = locale_tables; + } + +else switch (pat_patctl.tables_id) + { + case 0: use_tables = NULL; break; + case 1: use_tables = tables1; break; + case 2: use_tables = tables2; break; + default: + fprintf(outfile, "** 'Tables' must specify 0, 1, or 2.\n"); + return PR_SKIP; + } + +PCRE2_SET_CHARACTER_TABLES(pat_context, use_tables); + +/* Set up for the stackguard test. */ + +if (pat_patctl.stackguard_test != 0) + { + PCRE2_SET_COMPILE_RECURSION_GUARD(pat_context, stack_guard, NULL); + } + +/* Handle compiling via the POSIX interface, which doesn't support the +timing, showing, or debugging options, nor the ability to pass over +local character tables. Neither does it have 16-bit or 32-bit support. */ + +if ((pat_patctl.control & CTL_POSIX) != 0) + { +#ifdef SUPPORT_PCRE2_8 + int rc; + int cflags = 0; + const char *msg = "** Ignored with POSIX interface:"; +#endif + + if (test_mode != 8) + { + fprintf(outfile, "** The POSIX interface is available only in 8-bit mode\n"); + return PR_SKIP; + } + +#ifdef SUPPORT_PCRE2_8 + /* Check for features that the POSIX interface does not support. */ + + if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale"); + if (pat_patctl.replacement[0] != 0) prmsg(&msg, "replace"); + if (pat_patctl.tables_id != 0) prmsg(&msg, "tables"); + if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard"); + if (timeit > 0) prmsg(&msg, "timing"); + if (pat_patctl.jit != 0) prmsg(&msg, "JIT"); + + if ((pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS) != 0) + { + show_compile_options( + pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS, msg, ""); + msg = ""; + } + if ((pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS) != 0 || + (pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2) != 0) + { + show_controls(pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS, + pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2, msg); + msg = ""; + } + + if (local_newline_default != 0) prmsg(&msg, "#newline_default"); + + if (msg[0] == 0) fprintf(outfile, "\n"); + + /* Translate PCRE2 options to POSIX options and then compile. On success, set + up a match_data block to be used for all matches. */ + + if (utf) cflags |= REG_UTF; + if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP; + if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE; + if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE; + if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL; + if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; + if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY; + + rc = regcomp(&preg, (char *)pbuffer8, cflags); + if (rc != 0) /* Failure */ + { + size_t bsize, usize; + + preg.re_pcre2_code = NULL; /* In case something was left in there */ + preg.re_match_data = NULL; + + bsize = (pat_patctl.regerror_buffsize != 0)? + pat_patctl.regerror_buffsize : pbuffer8_size; + if (bsize + 8 < pbuffer8_size) + memcpy(pbuffer8 + bsize, "DEADBEEF", 8); + usize = regerror(rc, &preg, (char *)pbuffer8, bsize); + + fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, pbuffer8); + if (usize > bsize) + { + fprintf(outfile, "** regerror() message truncated\n"); + if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0) + fprintf(outfile, "** regerror() buffer overflow\n"); + } + return PR_SKIP; + } + return PR_OK; +#endif /* SUPPORT_PCRE2_8 */ + } + +/* Handle compiling via the native interface. Controls that act later are +ignored with "push". Replacements are locked out. */ + +if ((pat_patctl.control & CTL_PUSH) != 0) + { + if (pat_patctl.replacement[0] != 0) + { + fprintf(outfile, "** Replacement text is not supported with 'push'.\n"); + return PR_OK; + } + if ((pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS) != 0 || + (pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2) != 0) + { + show_controls(pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS, + pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2, + "** Ignored when compiled pattern is stacked with 'push':"); + fprintf(outfile, "\n"); + } + if ((pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS) != 0 || + (pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2) != 0) + { + show_controls(pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS, + pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2, + "** Applies only to compile when pattern is stacked with 'push':"); + fprintf(outfile, "\n"); + } + } + +/* Convert the input in non-8-bit modes. */ + +#ifdef SUPPORT_PCRE2_8 +if (test_mode == PCRE8_MODE) errorcode = 0; +#endif + +#ifdef SUPPORT_PCRE2_16 +if (test_mode == PCRE16_MODE) errorcode = to16(pbuffer8, utf, &patlen); +#endif + +#ifdef SUPPORT_PCRE2_32 +if (test_mode == PCRE32_MODE) errorcode = to32(pbuffer8, utf, &patlen); +#endif + +switch(errorcode) + { + case -1: + fprintf(outfile, "** Failed: invalid UTF-8 string cannot be " + "converted to %d-bit string\n", (test_mode == PCRE16_MODE)? 16:32); + return PR_SKIP; + + case -2: + fprintf(outfile, "** Failed: character value greater than 0x10ffff " + "cannot be converted to UTF\n"); + return PR_SKIP; + + case -3: + fprintf(outfile, "** Failed: character value greater than 0xffff " + "cannot be converted to 16-bit in non-UTF mode\n"); + return PR_SKIP; + + default: + break; + } + +/* The pattern is now in pbuffer[8|16|32], with the length in patlen. By +default, however, we pass a zero-terminated pattern. The length is passed only +if we had a hex pattern. */ + +if ((pat_patctl.control & CTL_HEXPAT) == 0) patlen = PCRE2_ZERO_TERMINATED; + +/* If #newline_default has been used and the library was not compiled with an +appropriate default newline setting, local_newline_default will be non-zero. We +use this if there is no explicit newline modifier. */ + +if ((pat_patctl.control & CTL_NL_SET) == 0 && local_newline_default != 0) + { + SETFLD(pat_context, newline_convention, local_newline_default); + } + +/* The nullcontext modifier is used to test calling pcre2_compile() with a NULL +context. */ + +use_pat_context = ((pat_patctl.control & CTL_NULLCONTEXT) != 0)? + NULL : PTR(pat_context); + +/* Compile many times when timing. */ + +if (timeit > 0) + { + register int i; + clock_t time_taken = 0; + for (i = 0; i < timeit; i++) + { + clock_t start_time = clock(); + PCRE2_COMPILE(compiled_code, pbuffer, patlen, + pat_patctl.options|forbid_utf, &errorcode, &erroroffset, use_pat_context); + time_taken += clock() - start_time; + if (TEST(compiled_code, !=, NULL)) + { SUB1(pcre2_code_free, compiled_code); } + } + total_compile_time += time_taken; + fprintf(outfile, "Compile time %.4f milliseconds\n", + (((double)time_taken * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + } + +/* A final compile that is used "for real". */ + +PCRE2_COMPILE(compiled_code, pbuffer, patlen, pat_patctl.options|forbid_utf, + &errorcode, &erroroffset, use_pat_context); + +/* Compilation failed; go back for another re, skipping to blank line +if non-interactive. */ + +if (TEST(compiled_code, ==, NULL)) + { + int len; + fprintf(outfile, "Failed: error %d at offset %d: ", errorcode, + (int)erroroffset); + PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); + fprintf(outfile, "\n"); + return PR_SKIP; + } + +/* If forbid_utf is non-zero, we are running a non-UTF test. UTF and UCP are +locked out at compile time, but we must also check for occurrences of \P, \p, +and \X, which are only supported when Unicode is supported. */ + +if (forbid_utf != 0) + { + if ((FLD(compiled_code, flags) & PCRE2_HASBKPORX) != 0) + { + fprintf(outfile, "** \\P, \\p, and \\X are not allowed after the " + "#forbid_utf command\n"); + return PR_SKIP; + } + } + +/* Remember the maximum lookbehind, for partial matching. */ + +if (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0) + return PR_ABEND; + +/* Call the JIT compiler if requested. When timing, we must free and recompile +the pattern each time because that is the only way to free the JIT compiled +code. We know that compilation will always succeed. */ + +if (pat_patctl.jit != 0) + { + if (timeit > 0) + { + register int i; + clock_t time_taken = 0; + for (i = 0; i < timeit; i++) + { + clock_t start_time; + SUB1(pcre2_code_free, compiled_code); + PCRE2_COMPILE(compiled_code, pbuffer, patlen, + pat_patctl.options|forbid_utf, &errorcode, &erroroffset, + use_pat_context); + start_time = clock(); + PCRE2_JIT_COMPILE(jitrc,compiled_code, pat_patctl.jit); + time_taken += clock() - start_time; + } + total_jit_compile_time += time_taken; + fprintf(outfile, "JIT compile %.4f milliseconds\n", + (((double)time_taken * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + } + else + { + PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit); + } + } + +/* If an explicit newline modifier was given, set the information flag in the +pattern so that it is preserved over push/pop. */ + +if ((pat_patctl.control & CTL_NL_SET) != 0) + { + SETFLD(compiled_code, flags, FLD(compiled_code, flags) | PCRE2_NL_SET); + } + +/* Output code size and other information if requested. */ + +if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info(); +if ((pat_patctl.control & CTL_ANYINFO) != 0) + { + int rc = show_pattern_info(); + if (rc != PR_OK) return rc; + } + +/* The "push" control requests that the compiled pattern be remembered on a +stack. This is mainly for testing the serialization functionality. */ + +if ((pat_patctl.control & CTL_PUSH) != 0) + { + if (patstacknext >= PATSTACKSIZE) + { + fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE); + return PR_ABEND; + } + patstack[patstacknext++] = PTR(compiled_code); + SET(compiled_code, NULL); + } + +return PR_OK; +} + + + +/************************************************* +* Check match or recursion limit * +*************************************************/ + +static int +check_match_limit(uint8_t *pp, size_t ulen, int errnumber, const char *msg) +{ +int capcount; +uint32_t min = 0; +uint32_t mid = 64; +uint32_t max = UINT32_MAX; + +PCRE2_SET_MATCH_LIMIT(dat_context, max); +PCRE2_SET_RECURSION_LIMIT(dat_context, max); + +for (;;) + { + if (errnumber == PCRE2_ERROR_MATCHLIMIT) + { + PCRE2_SET_MATCH_LIMIT(dat_context, mid); + } + else + { + PCRE2_SET_RECURSION_LIMIT(dat_context, mid); + } + + if ((pat_patctl.control & CTL_JITFAST) != 0) + PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, + dat_datctl.options, match_data, PTR(dat_context)); + else + PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, + dat_datctl.options, match_data, PTR(dat_context)); + + if (capcount == errnumber) + { + min = mid; + mid = (mid == max - 1)? max : (max != UINT32_MAX)? (min + max)/2 : mid*2; + } + else if (capcount >= 0 || + capcount == PCRE2_ERROR_NOMATCH || + capcount == PCRE2_ERROR_PARTIAL) + { + if (mid == min + 1) + { + fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); + break; + } + max = mid; + mid = (min + mid)/2; + } + else break; /* Some other error */ + } + +return capcount; +} + + + +/************************************************* +* Callout function * +*************************************************/ + +/* Called from a PCRE2 library as a result of the (?C) item. We print out where +we are in the match. Yield zero unless more callouts than the fail count, or +the callout data is not zero. The only differences in the callout block for +different code unit widths are that the pointers to the subject, the most +recent MARK, and a callout argument string point to strings of the appropriate +width. Casts can be used to deal with this. + +Argument: a pointer to a callout block +Return: +*/ + +static int +callout_function(pcre2_callout_block_8 *cb, void *callout_data_ptr) +{ +uint32_t i, pre_start, post_start, subject_length; +BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; +BOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0; + +/* This FILE is used for echoing the subject. This is done only once in simple +cases. */ + +FILE *f = (first_callout || callout_capture || cb->callout_string != NULL)? + outfile : NULL; + +/* For a callout with a string argument, show the string first because there +isn't a tidy way to fit it in the rest of the data. */ + +if (cb->callout_string != NULL) + { + uint32_t delimiter = CODE_UNIT(cb->callout_string, -1); + fprintf(outfile, "Callout (%lu): %c", + (unsigned long int)cb->callout_string_offset, delimiter); + PCHARSV(cb->callout_string, 0, + cb->callout_string_length, utf, outfile); + for (i = 0; callout_start_delims[i] != 0; i++) + if (delimiter == callout_start_delims[i]) + { + delimiter = callout_end_delims[i]; + break; + } + fprintf(outfile, "%c", delimiter); + if (!callout_capture) fprintf(outfile, "\n"); + } + +/* Show captured strings if required */ + +if (callout_capture) + { + if (cb->callout_string == NULL) + fprintf(outfile, "Callout %d:", cb->callout_number); + fprintf(outfile, " last capture = %d\n", cb->capture_last); + for (i = 0; i < cb->capture_top * 2; i += 2) + { + fprintf(outfile, "%2d: ", i/2); + if (cb->offset_vector[i] == PCRE2_UNSET) + fprintf(outfile, ""); + else + { + PCHARSV(cb->subject, cb->offset_vector[i], + cb->offset_vector[i+1] - cb->offset_vector[i], utf, f); + } + fprintf(outfile, "\n"); + } + } + +/* Re-print the subject in canonical form, the first time or if giving full +datails. On subsequent calls in the same match, we use pchars just to find the +printed lengths of the substrings. */ + +if (f != NULL) fprintf(f, "--->"); + +PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f); + +PCHARS(post_start, cb->subject, cb->start_match, + cb->current_position - cb->start_match, utf, f); + +PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL); + +PCHARSV(cb->subject, cb->current_position, + cb->subject_length - cb->current_position, utf, f); + +if (f != NULL) fprintf(f, "\n"); + +/* For automatic callouts, show the pattern offset. Otherwise, for a numerical +callout whose number has not already been shown with captured strings, show the +number here. A callout with a string argument has been displayed above. */ + +if (cb->callout_number == 255) + { + fprintf(outfile, "%+3d ", (int)cb->pattern_position); + if (cb->pattern_position > 99) fprintf(outfile, "\n "); + } +else + { + if (callout_capture || cb->callout_string != NULL) fprintf(outfile, " "); + else fprintf(outfile, "%3d ", cb->callout_number); + } + +/* Now show position indicators */ + +for (i = 0; i < pre_start; i++) fprintf(outfile, " "); +fprintf(outfile, "^"); + +if (post_start > 0) + { + for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); + fprintf(outfile, "^"); + } + +for (i = 0; i < subject_length - pre_start - post_start + 4; i++) + fprintf(outfile, " "); + +fprintf(outfile, "%.*s", + (int)((cb->next_item_length == 0)? 1 : cb->next_item_length), + pbuffer8 + cb->pattern_position); + +fprintf(outfile, "\n"); +first_callout = FALSE; + +if (cb->mark != last_callout_mark) + { + if (cb->mark == NULL) + fprintf(outfile, "Latest Mark: \n"); + else + { + fprintf(outfile, "Latest Mark: "); + PCHARSV(cb->mark, 0, -1, utf, outfile); + putc('\n', outfile); + } + last_callout_mark = cb->mark; + } + +if (callout_data_ptr != NULL) + { + int callout_data = *((int32_t *)callout_data_ptr); + if (callout_data != 0) + { + fprintf(outfile, "Callout data = %d\n", callout_data); + return callout_data; + } + } + +return (cb->callout_number != dat_datctl.cfail[0])? 0 : + (++callout_count >= dat_datctl.cfail[1])? 1 : 0; +} + + + +/************************************************* +* Handle *MARK and copy/get tests * +*************************************************/ + +/* This function is called after complete and partial matches. It runs the +tests for substring extraction. + +Arguments: + utf TRUE for utf + capcount return from pcre2_match() + +Returns: nothing +*/ + +static void +copy_and_get(BOOL utf, int capcount) +{ +int i; +uint8_t *nptr; + +/* Test copy strings by number */ + +for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++) + { + int rc; + PCRE2_SIZE length, length2; + uint32_t copybuffer[256]; + uint32_t n = (uint32_t)(dat_datctl.copy_numbers[i]); + length = sizeof(copybuffer)/code_unit_size; + PCRE2_SUBSTRING_COPY_BYNUMBER(rc, match_data, n, copybuffer, &length); + if (rc < 0) + { + fprintf(outfile, "Copy substring %d failed (%d): ", n, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else + { + PCRE2_SUBSTRING_LENGTH_BYNUMBER(rc, match_data, n, &length2); + if (rc < 0) + { + fprintf(outfile, "Get substring %d length failed (%d): ", n, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else if (length2 != length) + { + fprintf(outfile, "Mismatched substring lengths: %lu %lu\n", + (unsigned long int)length, (unsigned long int)length2); + } + fprintf(outfile, "%2dC ", n); + PCHARSV(copybuffer, 0, length, utf, outfile); + fprintf(outfile, " (%lu)\n", (unsigned long)length); + } + } + +/* Test copy strings by name */ + +nptr = dat_datctl.copy_names; +for (;;) + { + int rc; + int groupnumber; + PCRE2_SIZE length, length2; + uint32_t copybuffer[256]; + int namelen = strlen((const char *)nptr); +#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32 + PCRE2_SIZE cnl = namelen; +#endif + if (namelen == 0) break; + +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr); +#endif +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl); +#endif +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl); +#endif + + PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer); + if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING) + fprintf(outfile, "Number not found for group '%s'\n", nptr); + + length = sizeof(copybuffer)/code_unit_size; + PCRE2_SUBSTRING_COPY_BYNAME(rc, match_data, pbuffer, copybuffer, &length); + if (rc < 0) + { + fprintf(outfile, "Copy substring '%s' failed (%d): ", nptr, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else + { + PCRE2_SUBSTRING_LENGTH_BYNAME(rc, match_data, pbuffer, &length2); + if (rc < 0) + { + fprintf(outfile, "Get substring '%s' length failed (%d): ", nptr, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else if (length2 != length) + { + fprintf(outfile, "Mismatched substring lengths: %lu %lu\n", + (unsigned long int)length, (unsigned long int)length2); + } + fprintf(outfile, " C "); + PCHARSV(copybuffer, 0, length, utf, outfile); + fprintf(outfile, " (%lu) %s", (unsigned long)length, nptr); + if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber); + else fprintf(outfile, " (non-unique)\n"); + } + nptr += namelen + 1; + } + +/* Test get strings by number */ + +for (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++) + { + int rc; + PCRE2_SIZE length; + void *gotbuffer; + uint32_t n = (uint32_t)(dat_datctl.get_numbers[i]); + PCRE2_SUBSTRING_GET_BYNUMBER(rc, match_data, n, &gotbuffer, &length); + if (rc < 0) + { + fprintf(outfile, "Get substring %d failed (%d): ", n, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else + { + fprintf(outfile, "%2dG ", n); + PCHARSV(gotbuffer, 0, length, utf, outfile); + fprintf(outfile, " (%lu)\n", (unsigned long)length); + PCRE2_SUBSTRING_FREE(gotbuffer); + } + } + +/* Test get strings by name */ + +nptr = dat_datctl.get_names; +for (;;) + { + PCRE2_SIZE length; + void *gotbuffer; + int rc; + int groupnumber; + int namelen = strlen((const char *)nptr); +#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32 + PCRE2_SIZE cnl = namelen; +#endif + if (namelen == 0) break; + +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr); +#endif +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl); +#endif +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl); +#endif + + PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer); + if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING) + fprintf(outfile, "Number not found for group '%s'\n", nptr); + + PCRE2_SUBSTRING_GET_BYNAME(rc, match_data, pbuffer, &gotbuffer, &length); + if (rc < 0) + { + fprintf(outfile, "Get substring '%s' failed (%d): ", nptr, rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else + { + fprintf(outfile, " G "); + PCHARSV(gotbuffer, 0, length, utf, outfile); + fprintf(outfile, " (%lu) %s", (unsigned long)length, nptr); + if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber); + else fprintf(outfile, " (non-unique)\n"); + PCRE2_SUBSTRING_FREE(gotbuffer); + } + nptr += namelen + 1; + } + +/* Test getting the complete list of captured strings. */ + +if ((dat_datctl.control & CTL_GETALL) != 0) + { + int rc; + void **stringlist; + PCRE2_SIZE *lengths; + PCRE2_SUBSTRING_LIST_GET(rc, match_data, &stringlist, &lengths); + if (rc < 0) + { + fprintf(outfile, "get substring list failed (%d): ", rc); + PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); + fprintf(outfile, "\n"); + } + else + { + for (i = 0; i < capcount; i++) + { + fprintf(outfile, "%2dL ", i); + PCHARSV(stringlist[i], 0, lengths[i], utf, outfile); + putc('\n', outfile); + } + if (stringlist[i] != NULL) + fprintf(outfile, "string list not terminated by NULL\n"); + PCRE2_SUBSTRING_LIST_FREE(stringlist); + } + } +} + + + +/************************************************* +* Process a data line * +*************************************************/ + +/* The line is in buffer; it will not be empty. + +Arguments: none + +Returns: PR_OK continue processing next line + PR_SKIP skip to a blank line + PR_ABEND abort the pcre2test run +*/ + +static int +process_data(void) +{ +PCRE2_SIZE len, ulen; +uint32_t gmatched; +uint32_t c, k; +uint32_t g_notempty = 0; +uint8_t *p, *pp, *start_rep; +size_t needlen; +void *use_dat_context; +BOOL utf; + +#ifdef SUPPORT_PCRE2_8 +uint8_t *q8 = NULL; +#endif +#ifdef SUPPORT_PCRE2_16 +uint16_t *q16 = NULL; +#endif +#ifdef SUPPORT_PCRE2_32 +uint32_t *q32 = NULL; +#endif + +/* Copy the default context and data control blocks to the active ones. Then +copy from the pattern the controls that can be set in either the pattern or the +data. This allows them to be overridden in the data line. We do not do this for +options because those that are common apply separately to compiling and +matching. */ + +DATCTXCPY(dat_context, default_dat_context); +memcpy(&dat_datctl, &def_datctl, sizeof(datctl)); +dat_datctl.control |= (pat_patctl.control & CTL_ALLPD); +dat_datctl.control2 |= (pat_patctl.control2 & CTL2_ALLPD); +strcpy((char *)dat_datctl.replacement, (char *)pat_patctl.replacement); + +/* Initialize for scanning the data line. */ + +#ifdef SUPPORT_PCRE2_8 +utf = ((((pat_patctl.control & CTL_POSIX) != 0)? + ((pcre2_real_code_8 *)preg.re_pcre2_code)->overall_options : + FLD(compiled_code, overall_options)) & PCRE2_UTF) != 0; +#else +utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; +#endif + +start_rep = NULL; +len = strlen((const char *)buffer); +while (len > 0 && isspace(buffer[len-1])) len--; +buffer[len] = 0; +p = buffer; +while (isspace(*p)) p++; + +/* Check that the data is well-formed UTF-8 if we're in UTF mode. To create +invalid input to pcre2_match(), you must use \x?? or \x{} sequences. */ + +if (utf) + { + uint8_t *q; + uint32_t cc; + int n = 1; + for (q = p; n > 0 && *q; q += n) n = utf82ord(q, &cc); + if (n <= 0) + { + fprintf(outfile, "** Failed: invalid UTF-8 string cannot be used as input " + "in UTF mode\n"); + return PR_OK; + } + } + +#ifdef SUPPORT_VALGRIND +/* Mark the dbuffer as addressable but undefined again. */ +if (dbuffer != NULL) + { + VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size); + } +#endif + +/* Allocate a buffer to hold the data line; len+1 is an upper bound on +the number of code units that will be needed (though the buffer may have to be +extended if replication is involved). */ + +needlen = (size_t)((len+1) * code_unit_size); +if (dbuffer == NULL || needlen >= dbuffer_size) + { + while (needlen >= dbuffer_size) dbuffer_size *= 2; + dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size); + if (dbuffer == NULL) + { + fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size); + exit(1); + } + } +SETCASTPTR(q, dbuffer); /* Sets q8, q16, or q32, as appropriate. */ + +/* Scan the data line, interpreting data escapes, and put the result into a +buffer of the appropriate width. In UTF mode, input can be UTF-8. */ + +while ((c = *p++) != 0) + { + int i = 0; + size_t replen; + + /* ] may mark the end of a replicated sequence */ + + if (c == ']' && start_rep != NULL) + { + size_t qoffset = CAST8VAR(q) - dbuffer; + size_t rep_offset = start_rep - dbuffer; + + if (*p++ != '{') + { + fprintf(outfile, "** Expected '{' after \\[....]\n"); + return PR_OK; + } + while (isdigit(*p)) i = i * 10 + *p++ - '0'; + if (*p++ != '}') + { + fprintf(outfile, "** Expected '}' after \\[...]{...\n"); + return PR_OK; + } + if (i-- == 0) + { + fprintf(outfile, "** Zero repeat not allowed\n"); + return PR_OK; + } + + replen = CAST8VAR(q) - start_rep; + needlen += replen * i; + + if (needlen >= dbuffer_size) + { + while (needlen >= dbuffer_size) dbuffer_size *= 2; + dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size); + if (dbuffer == NULL) + { + fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size); + exit(1); + } + SETCASTPTR(q, dbuffer + qoffset); + start_rep = dbuffer + rep_offset; + } + + while (i-- > 0) + { + memcpy(CAST8VAR(q), start_rep, replen); + SETPLUS(q, replen/code_unit_size); + } + + start_rep = NULL; + continue; + } + + /* Handle a non-escaped character */ + + if (c != '\\') + { + if (utf && HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); } + } + + /* Handle backslash escapes */ + + else switch ((c = *p++)) + { + case '\\': break; + case 'a': c = CHAR_BEL; break; + case 'b': c = '\b'; break; + case 'e': c = CHAR_ESC; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') + c = c * 8 + *p++ - '0'; + break; + + case 'o': + if (*p == '{') + { + uint8_t *pt = p; + c = 0; + for (pt++; isdigit(*pt) && *pt != '8' && *pt != '9'; pt++) + { + if (++i == 12) + fprintf(outfile, "** Too many octal digits in \\o{...} item; " + "using only the first twelve.\n"); + else c = c * 8 + *pt - '0'; + } + if (*pt == '}') p = pt + 1; + else fprintf(outfile, "** Missing } after \\o{ (assumed)\n"); + } + break; + + case 'x': + if (*p == '{') + { + uint8_t *pt = p; + c = 0; + + /* We used to have "while (isxdigit(*(++pt)))" here, but it fails + when isxdigit() is a macro that refers to its argument more than + once. This is banned by the C Standard, but apparently happens in at + least one MacOS environment. */ + + for (pt++; isxdigit(*pt); pt++) + { + if (++i == 9) + fprintf(outfile, "** Too many hex digits in \\x{...} item; " + "using only the first eight.\n"); + else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10); + } + if (*pt == '}') + { + p = pt + 1; + break; + } + /* Not correct form for \x{...}; fall through */ + } + + /* \x without {} always defines just one byte in 8-bit mode. This + allows UTF-8 characters to be constructed byte by byte, and also allows + invalid UTF-8 sequences to be made. Just copy the byte in UTF-8 mode. + Otherwise, pass it down as data. */ + + c = 0; + while (i++ < 2 && isxdigit(*p)) + { + c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10); + p++; + } +#if defined SUPPORT_PCRE2_8 + if (utf && (test_mode == PCRE8_MODE)) + { + *q8++ = c; + continue; + } +#endif + break; + + case 0: /* \ followed by EOF allows for an empty line */ + p--; + continue; + + case '=': /* \= terminates the data, starts modifiers */ + goto ENDSTRING; + + case '[': /* \[ introduces a replicated character sequence */ + if (start_rep != NULL) + { + fprintf(outfile, "** Nested replication is not supported\n"); + return PR_OK; + } + start_rep = CAST8VAR(q); + continue; + + default: + if (isalnum(c)) + { + fprintf(outfile, "** Unrecognized escape sequence \"\\%c\"\n", c); + return PR_OK; + } + } + + /* We now have a character value in c that may be greater than 255. + In 8-bit mode we convert to UTF-8 if we are in UTF mode. Values greater + than 127 in UTF mode must have come from \x{...} or octal constructs + because values from \x.. get this far only in non-UTF mode. */ + +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) + { + if (utf) + { + if (c > 0x7fffffff) + { + fprintf(outfile, "** Character \\x{%x} is greater than 0x7fffffff " + "and so cannot be converted to UTF-8\n", c); + return PR_OK; + } + q8 += ord2utf8(c, q8); + } + else + { + if (c > 0xffu) + { + fprintf(outfile, "** Character \\x{%x} is greater than 255 " + "and UTF-8 mode is not enabled.\n", c); + fprintf(outfile, "** Truncation will probably give the wrong " + "result.\n"); + } + *q8++ = c; + } + } +#endif +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE) + { + if (utf) + { + if (c > 0x10ffffu) + { + fprintf(outfile, "** Failed: character \\x{%x} is greater than " + "0x10ffff and so cannot be converted to UTF-16\n", c); + return PR_OK; + } + else if (c >= 0x10000u) + { + c-= 0x10000u; + *q16++ = 0xD800 | (c >> 10); + *q16++ = 0xDC00 | (c & 0x3ff); + } + else + *q16++ = c; + } + else + { + if (c > 0xffffu) + { + fprintf(outfile, "** Character \\x{%x} is greater than 0xffff " + "and UTF-16 mode is not enabled.\n", c); + fprintf(outfile, "** Truncation will probably give the wrong " + "result.\n"); + } + + *q16++ = c; + } + } +#endif +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE) + { + *q32++ = c; + } +#endif + } + +ENDSTRING: +SET(*q, 0); +len = CASTVAR(uint8_t *, q) - dbuffer; /* Length in bytes */ +ulen = len/code_unit_size; /* Length in code units */ + +/* If the string was terminated by \= we must now interpret modifiers. */ + +if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl)) + return PR_OK; + +/* Check for mutually exclusive modifiers. At present, these are all in the +first control word. */ + +for (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++) + { + c = dat_datctl.control & exclusive_dat_controls[k]; + if (c != 0 && c != (c & (~c+1))) + { + show_controls(c, 0, "** Not allowed together:"); + fprintf(outfile, "\n"); + return PR_OK; + } + } + +if (pat_patctl.replacement[0] != 0 && + (dat_datctl.control & CTL_NULLCONTEXT) != 0) + { + fprintf(outfile, "** Replacement text is not supported with null_context.\n"); + return PR_OK; + } + +/* We now have the subject in dbuffer, with len containing the byte length, and +ulen containing the code unit length. Move the data to the end of the buffer so +that a read over the end can be caught by valgrind or other means. If we have +explicit valgrind support, mark the unused start of the buffer unaddressable. +If we are using the POSIX interface, or testing zero-termination, we must +include the terminating zero in the usable data. */ + +c = code_unit_size * (((pat_patctl.control & CTL_POSIX) + + (dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1:0); +pp = memmove(dbuffer + dbuffer_size - len - c, dbuffer, len + c); +#ifdef SUPPORT_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(dbuffer, dbuffer_size - (len + c)); +#endif + +/* Now pp points to the subject string. POSIX matching is only possible in +8-bit mode, and it does not support timing or other fancy features. Some were +checked at compile time, but we need to check the match-time settings here. */ + +#ifdef SUPPORT_PCRE2_8 +if ((pat_patctl.control & CTL_POSIX) != 0) + { + int rc; + int eflags = 0; + regmatch_t *pmatch = NULL; + const char *msg = "** Ignored with POSIX interface:"; + + if (dat_datctl.cfail[0] != CFAIL_UNSET || dat_datctl.cfail[1] != CFAIL_UNSET) + prmsg(&msg, "callout_fail"); + if (dat_datctl.copy_numbers[0] >= 0 || dat_datctl.copy_names[0] != 0) + prmsg(&msg, "copy"); + if (dat_datctl.get_numbers[0] >= 0 || dat_datctl.get_names[0] != 0) + prmsg(&msg, "get"); + if (dat_datctl.jitstack != 0) prmsg(&msg, "jitstack"); + + if ((dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS) != 0) + { + fprintf(outfile, "%s", msg); + show_match_options(dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS); + msg = ""; + } + if ((dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS) != 0 || + (dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2) != 0) + { + show_controls(dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS, + dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2, msg); + msg = ""; + } + + if (msg[0] == 0) fprintf(outfile, "\n"); + + if (dat_datctl.oveccount > 0) + pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount); + if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL; + if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL; + if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY; + + rc = regexec(&preg, (const char *)pp + dat_datctl.offset, + dat_datctl.oveccount, pmatch, eflags); + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size); + fprintf(outfile, "No match: POSIX code %d: %s\n", rc, pbuffer8); + } + else if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) + fprintf(outfile, "Matched with REG_NOSUB\n"); + else if (dat_datctl.oveccount == 0) + fprintf(outfile, "Matched without capture\n"); + else + { + size_t i; + for (i = 0; i < (size_t)dat_datctl.oveccount; i++) + { + if (pmatch[i].rm_so >= 0) + { + fprintf(outfile, "%2d: ", (int)i); + PCHARSV(pp, pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so, utf, outfile); + fprintf(outfile, "\n"); + if ((i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0) || + (dat_datctl.control & CTL_ALLAFTERTEXT) != 0) + { + fprintf(outfile, "%2d+ ", (int)i); + PCHARSV(pp, pmatch[i].rm_eo, len - pmatch[i].rm_eo, + utf, outfile); + fprintf(outfile, "\n"); + } + } + } + } + free(pmatch); + return PR_OK; + } +#endif /* SUPPORT_PCRE2_8 */ + + /* Handle matching via the native interface. Check for consistency of +modifiers. */ + +if ((dat_datctl.control & (CTL_DFA|CTL_FINDLIMITS)) == (CTL_DFA|CTL_FINDLIMITS)) + { + fprintf(outfile, "** Finding match limits is not relevant for DFA matching: ignored\n"); + dat_datctl.control &= ~CTL_FINDLIMITS; + } + +/* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA +matching, even if the JIT compiler was used. */ + +if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT && + FLD(compiled_code, executable_jit) != NULL) + { + fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n"); + dat_datctl.control &= ~CTL_ALLUSEDTEXT; + } + +/* Handle passing the subject as zero-terminated. */ + +if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0) + ulen = PCRE2_ZERO_TERMINATED; + +/* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a +NULL context. */ + +use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)? + NULL : PTR(dat_context); + +/* Enable display of malloc/free if wanted. */ + +show_memory = (dat_datctl.control & CTL_MEMORY) != 0; + +/* Create and assign a JIT stack if requested. */ + +if (dat_datctl.jitstack != 0) + { + if (dat_datctl.jitstack != jit_stack_size) + { + PCRE2_JIT_STACK_FREE(jit_stack); + PCRE2_JIT_STACK_CREATE(jit_stack, 1, dat_datctl.jitstack * 1024, NULL); + jit_stack_size = dat_datctl.jitstack; + } + PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, jit_stack); + } + +/* Or de-assign */ + +else if (jit_stack != NULL) + { + PCRE2_JIT_STACK_ASSIGN(dat_context, NULL, NULL); + PCRE2_JIT_STACK_FREE(jit_stack); + jit_stack = NULL; + jit_stack_size = 0; + } + +/* When no JIT stack is assigned, we must ensure that there is a JIT callback +if we want to verify that JIT was actually used. */ + +if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL) + { + PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, NULL); + } + +/* Adjust match_data according to size of offsets required. A size of zero +causes a new match data block to be obtained that exactly fits the pattern. */ + +if (dat_datctl.oveccount == 0) + { + PCRE2_MATCH_DATA_FREE(match_data); + PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(match_data, compiled_code, NULL); + PCRE2_GET_OVECTOR_COUNT(max_oveccount, match_data); + } +else if (dat_datctl.oveccount <= max_oveccount) + { + SETFLD(match_data, oveccount, dat_datctl.oveccount); + } +else + { + max_oveccount = dat_datctl.oveccount; + PCRE2_MATCH_DATA_FREE(match_data); + PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, NULL); + } + +/* Replacement processing is ignored for DFA matching. */ + +if (dat_datctl.replacement[0] != 0 && (dat_datctl.control & CTL_DFA) != 0) + { + fprintf(outfile, "** Ignored for DFA matching: replace\n"); + dat_datctl.replacement[0] = 0; + } + +/* If a replacement string is provided, call pcre2_substitute() instead of one +of the matching functions. First we have to convert the replacement string to +the appropriate width. */ + +if (dat_datctl.replacement[0] != 0) + { + int rc; + uint8_t *pr; + uint8_t rbuffer[REPLACE_BUFFSIZE]; + uint8_t nbuffer[REPLACE_BUFFSIZE]; + uint32_t xoptions; + PCRE2_SIZE rlen, nsize, erroroffset; + BOOL badutf = FALSE; + +#ifdef SUPPORT_PCRE2_8 + uint8_t *r8 = NULL; +#endif +#ifdef SUPPORT_PCRE2_16 + uint16_t *r16 = NULL; +#endif +#ifdef SUPPORT_PCRE2_32 + uint32_t *r32 = NULL; +#endif + + if (timeitm) + fprintf(outfile, "** Timing is not supported with replace: ignored\n"); + + xoptions = (((dat_datctl.control & CTL_GLOBAL) == 0)? 0 : + PCRE2_SUBSTITUTE_GLOBAL) | + (((dat_datctl.control2 & CTL2_SUBSTITUTE_EXTENDED) == 0)? 0 : + PCRE2_SUBSTITUTE_EXTENDED) | + (((dat_datctl.control2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) == 0)? 0 : + PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) | + (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) == 0)? 0 : + PCRE2_SUBSTITUTE_UNKNOWN_UNSET) | + (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNSET_EMPTY) == 0)? 0 : + PCRE2_SUBSTITUTE_UNSET_EMPTY); + + SETCASTPTR(r, rbuffer); /* Sets r8, r16, or r32, as appropriate. */ + pr = dat_datctl.replacement; + + /* If the replacement starts with '[]' we interpret that as length + value for the replacement buffer. */ + + nsize = REPLACE_BUFFSIZE/code_unit_size; + if (*pr == '[') + { + PCRE2_SIZE n = 0; + while ((c = *(++pr)) >= CHAR_0 && c <= CHAR_9) n = n * 10 + c - CHAR_0; + if (*pr++ != ']') + { + fprintf(outfile, "Bad buffer size in replacement string\n"); + return PR_OK; + } + if (n > nsize) + { + fprintf(outfile, "Replacement buffer setting (%lu) is too large " + "(max %lu)\n", (unsigned long int)n, (unsigned long int)nsize); + return PR_OK; + } + nsize = n; + } + + /* Now copy the replacement string to a buffer of the appropriate width. No + escape processing is done for replacements. In UTF mode, check for an invalid + UTF-8 input string, and if it is invalid, just copy its code units without + UTF interpretation. This provides a means of checking that an invalid string + is detected. Otherwise, UTF-8 can be used to include wide characters in a + replacement. */ + + if (utf) badutf = valid_utf(pr, strlen((const char *)pr), &erroroffset); + + /* Not UTF or invalid UTF-8: just copy the code units. */ + + if (!utf || badutf) + { + while ((c = *pr++) != 0) + { +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) *r8++ = c; +#endif +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE) *r16++ = c; +#endif +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE) *r32++ = c; +#endif + } + } + + /* Valid UTF-8 replacement string */ + + else while ((c = *pr++) != 0) + { + if (HASUTF8EXTRALEN(c)) { GETUTF8INC(c, pr); } + +#ifdef SUPPORT_PCRE2_8 + if (test_mode == PCRE8_MODE) r8 += ord2utf8(c, r8); +#endif + +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE) + { + if (c >= 0x10000u) + { + c-= 0x10000u; + *r16++ = 0xD800 | (c >> 10); + *r16++ = 0xDC00 | (c & 0x3ff); + } + else *r16++ = c; + } +#endif + +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE) *r32++ = c; +#endif + } + + SET(*r, 0); + if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0) + rlen = PCRE2_ZERO_TERMINATED; + else + rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size; + PCRE2_SUBSTITUTE(rc, compiled_code, pp, ulen, dat_datctl.offset, + dat_datctl.options|xoptions, match_data, dat_context, + rbuffer, rlen, nbuffer, &nsize); + + if (rc < 0) + { + PCRE2_SIZE msize; + fprintf(outfile, "Failed: error %d", rc); + if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET) + fprintf(outfile, " at offset %ld in replacement", (long int)nsize); + fprintf(outfile, ": "); + PCRE2_GET_ERROR_MESSAGE(msize, rc, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, msize, FALSE, outfile); + if (rc == PCRE2_ERROR_NOMEMORY && + (xoptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0) + fprintf(outfile, ": %ld code units are needed", (long int)nsize); + } + else + { + fprintf(outfile, "%2d: ", rc); + PCHARSV(nbuffer, 0, nsize, utf, outfile); + } + + fprintf(outfile, "\n"); + } /* End of substitution handling */ + +/* When a replacement string is not provided, run a loop for global matching +with one of the basic matching functions. */ + +else for (gmatched = 0;; gmatched++) + { + PCRE2_SIZE j; + int capcount; + PCRE2_SIZE *ovector; + PCRE2_SIZE ovecsave[2]; + + ovector = FLD(match_data, ovector); + + /* After the first time round a global loop, for a normal global (/g) + iteration, save the current ovector[0,1] so that we can check that they do + change each time. Otherwise a matching bug that returns the same string + causes an infinite loop. It has happened! */ + + if (gmatched > 0 && (dat_datctl.control & CTL_GLOBAL) != 0) + { + ovecsave[0] = ovector[0]; + ovecsave[1] = ovector[1]; + } + + /* For altglobal (or first time round the loop), set an "unset" value. */ + + else ovecsave[0] = ovecsave[1] = PCRE2_UNSET; + + /* Fill the ovector with junk to detect elements that do not get set + when they should be. */ + + for (j = 0; j < 2*dat_datctl.oveccount; j++) ovector[j] = JUNK_OFFSET; + + /* When matching is via pcre2_match(), we will detect the use of JIT via the + stack callback function. */ + + jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0; + + /* Do timing if required. */ + + if (timeitm > 0) + { + register int i; + clock_t start_time, time_taken; + + if ((dat_datctl.control & CTL_DFA) != 0) + { + if ((dat_datctl.options & PCRE2_DFA_RESTART) != 0) + { + fprintf(outfile, "Timing DFA restarts is not supported\n"); + return PR_OK; + } + if (dfa_workspace == NULL) + dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); + start_time = clock(); + for (i = 0; i < timeitm; i++) + { + PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, + dat_datctl.offset, dat_datctl.options | g_notempty, match_data, + use_dat_context, dfa_workspace, DFA_WS_DIMENSION); + } + } + + else if ((pat_patctl.control & CTL_JITFAST) != 0) + { + start_time = clock(); + for (i = 0; i < timeitm; i++) + { + PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, + dat_datctl.offset, dat_datctl.options | g_notempty, match_data, + use_dat_context); + } + } + + else + { + start_time = clock(); + for (i = 0; i < timeitm; i++) + { + PCRE2_MATCH(capcount, compiled_code, pp, ulen, + dat_datctl.offset, dat_datctl.options | g_notempty, match_data, + use_dat_context); + } + } + total_match_time += (time_taken = clock() - start_time); + fprintf(outfile, "Match time %.4f milliseconds\n", + (((double)time_taken * 1000.0) / (double)timeitm) / + (double)CLOCKS_PER_SEC); + } + + /* Find the match and recursion limits if requested. The recursion limit + is not relevant for JIT. */ + + if ((dat_datctl.control & CTL_FINDLIMITS) != 0) + { + capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match"); + if (FLD(compiled_code, executable_jit) == NULL) + (void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, + "recursion"); + } + + /* Otherwise just run a single match, setting up a callout if required (the + default). */ + + else + { + if ((dat_datctl.control & CTL_CALLOUT_NONE) == 0) + { + PCRE2_SET_CALLOUT(dat_context, callout_function, + (void *)(&dat_datctl.callout_data)); + first_callout = TRUE; + last_callout_mark = NULL; + callout_count = 0; + } + else + { + PCRE2_SET_CALLOUT(dat_context, NULL, NULL); /* No callout */ + } + + /* Run a single DFA or NFA match. */ + + if ((dat_datctl.control & CTL_DFA) != 0) + { + if (dfa_workspace == NULL) + dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); + if (dfa_matched++ == 0) + dfa_workspace[0] = -1; /* To catch bad restart */ + PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, + dat_datctl.offset, dat_datctl.options | g_notempty, match_data, + use_dat_context, dfa_workspace, DFA_WS_DIMENSION); + if (capcount == 0) + { + fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n"); + capcount = dat_datctl.oveccount; + } + } + else + { + if ((pat_patctl.control & CTL_JITFAST) != 0) + PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, + dat_datctl.options | g_notempty, match_data, use_dat_context); + else + PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, + dat_datctl.options | g_notempty, match_data, use_dat_context); + if (capcount == 0) + { + fprintf(outfile, "Matched, but too many substrings\n"); + capcount = dat_datctl.oveccount; + } + } + } + + /* The result of the match is now in capcount. First handle a successful + match. */ + + if (capcount >= 0) + { + int i; + uint32_t oveccount; + + /* This is a check against a lunatic return value. */ + + PCRE2_GET_OVECTOR_COUNT(oveccount, match_data); + if (capcount > (int)oveccount) + { + fprintf(outfile, + "** PCRE2 error: returned count %d is too big for ovector count %d\n", + capcount, oveccount); + capcount = oveccount; + if ((dat_datctl.control & CTL_ANYGLOB) != 0) + { + fprintf(outfile, "** Global loop abandoned\n"); + dat_datctl.control &= ~CTL_ANYGLOB; /* Break g/G loop */ + } + } + + /* If this is not the first time round a global loop, check that the + returned string has changed. If not, there is a bug somewhere and we must + break the loop because it will go on for ever. We know that there are + always at least two elements in the ovector. */ + + if (gmatched > 0 && ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1]) + { + fprintf(outfile, + "** PCRE2 error: global repeat returned the same string as previous\n"); + fprintf(outfile, "** Global loop abandoned\n"); + dat_datctl.control &= ~CTL_ANYGLOB; /* Break g/G loop */ + } + + /* "allcaptures" requests showing of all captures in the pattern, to check + unset ones at the end. It may be set on the pattern or the data. Implement + by setting capcount to the maximum. */ + + if ((dat_datctl.control & CTL_ALLCAPTURES) != 0) + { + uint32_t maxcapcount; + if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0) + return PR_SKIP; + capcount = maxcapcount + 1; /* Allow for full match */ + if (capcount > (int)oveccount) capcount = oveccount; + } + + /* Output the captured substrings. Note that, for the matched string, + the use of \K in an assertion can make the start later than the end. */ + + for (i = 0; i < 2*capcount; i += 2) + { + PCRE2_SIZE lleft, lmiddle, lright; + PCRE2_SIZE start = ovector[i]; + PCRE2_SIZE end = ovector[i+1]; + + if (start > end) + { + start = ovector[i+1]; + end = ovector[i]; + fprintf(outfile, "Start of matched string is beyond its end - " + "displaying from end to start.\n"); + } + + fprintf(outfile, "%2d: ", i/2); + + /* Check for an unset group */ + + if (start == PCRE2_UNSET) + { + fprintf(outfile, "\n"); + continue; + } + + /* Check for silly offsets, in particular, values that have not been + set when they should have been. */ + + if (start > ulen || end > ulen) + { + fprintf(outfile, "ERROR: bad value(s) for offset(s): 0x%lx 0x%lx\n", + (unsigned long int)start, (unsigned long int)end); + continue; + } + + /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with + JIT, it is disabled above, with a comment.) When the match is done by the + interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is + set, and if the leftmost consulted character is before the start of the + match or the rightmost consulted character is past the end of the match, + we want to show all consulted characters for the main matched string, and + indicate which were lookarounds. */ + + if (i == 0) + { + BOOL showallused; + PCRE2_SIZE leftchar, rightchar; + + if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0) + { + leftchar = FLD(match_data, leftchar); + rightchar = FLD(match_data, rightchar); + showallused = i == 0 && (leftchar < start || rightchar > end); + } + else showallused = FALSE; + + if (showallused) + { + PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile); + PCHARS(lmiddle, pp, start, end - start, utf, outfile); + PCHARS(lright, pp, end, rightchar - end, utf, outfile); + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + fprintf(outfile, "\n "); + for (j = 0; j < lleft; j++) fprintf(outfile, "<"); + for (j = 0; j < lmiddle; j++) fprintf(outfile, " "); + for (j = 0; j < lright; j++) fprintf(outfile, ">"); + } + + /* When a pattern contains \K, the start of match position may be + different to the start of the matched string. When this is the case, + show it when requested. */ + + else if ((dat_datctl.control & CTL_STARTCHAR) != 0) + { + PCRE2_SIZE startchar; + PCRE2_GET_STARTCHAR(startchar, match_data); + PCHARS(lleft, pp, startchar, start - startchar, utf, outfile); + PCHARSV(pp, start, end - start, utf, outfile); + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + if (startchar != start) + { + fprintf(outfile, "\n "); + for (j = 0; j < lleft; j++) fprintf(outfile, "^"); + } + } + + /* Otherwise, just show the matched string. */ + + else + { + PCHARSV(pp, start, end - start, utf, outfile); + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + } + } + + /* Not the main matched string. Just show it unadorned. */ + + else + { + PCHARSV(pp, start, end - start, utf, outfile); + } + + fprintf(outfile, "\n"); + + /* Note: don't use the start/end variables here because we want to + show the text from what is reported as the end. */ + + if ((dat_datctl.control & CTL_ALLAFTERTEXT) != 0 || + (i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0)) + { + fprintf(outfile, "%2d+ ", i/2); + PCHARSV(pp, ovector[i+1], ulen - ovector[i+1], utf, outfile); + fprintf(outfile, "\n"); + } + } + + /* Output (*MARK) data if requested */ + + if ((dat_datctl.control & CTL_MARK) != 0 && + TESTFLD(match_data, mark, !=, NULL)) + { + fprintf(outfile, "MK: "); + PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); + fprintf(outfile, "\n"); + } + + /* Process copy/get strings */ + + copy_and_get(utf, capcount); + + } /* End of handling a successful match */ + + /* There was a partial match. The value of ovector[0] is the bumpalong point, + that is, startchar, not any \K point that might have been passed. */ + + else if (capcount == PCRE2_ERROR_PARTIAL) + { + PCRE2_SIZE poffset; + int backlength; + int rubriclength = 0; + + fprintf(outfile, "Partial match"); + if ((dat_datctl.control & CTL_MARK) != 0 && + TESTFLD(match_data, mark, !=, NULL)) + { + fprintf(outfile, ", mark="); + PCHARS(rubriclength, CASTFLD(void *, match_data, mark), 0, -1, utf, + outfile); + rubriclength += 7; + } + fprintf(outfile, ": "); + rubriclength += 15; + + poffset = backchars(pp, ovector[0], maxlookbehind, utf); + PCHARS(backlength, pp, poffset, ovector[0] - poffset, utf, outfile); + PCHARSV(pp, ovector[0], ulen - ovector[0], utf, outfile); + + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + fprintf(outfile, "\n"); + + if (backlength != 0) + { + int i; + for (i = 0; i < rubriclength; i++) fprintf(outfile, " "); + for (i = 0; i < backlength; i++) fprintf(outfile, "<"); + fprintf(outfile, "\n"); + } + + /* Process copy/get strings */ + + copy_and_get(utf, 1); + + break; /* Out of the /g loop */ + } /* End of handling partial match */ + + /* Failed to match. If this is a /g or /G loop, we might previously have + set g_notempty (to PCRE2_NOTEMPTY_ATSTART|PCRE2_ANCHORED) after a null match. + If that is the case, this is not necessarily the end. We want to advance the + start offset, and continue. We won't be at the end of the string - that was + checked before setting g_notempty. We achieve the effect by pretending that a + single character was matched. + + Complication arises in the case when the newline convention is "any", "crlf", + or "anycrlf". If the previous match was at the end of a line terminated by + CRLF, an advance of one character just passes the CR, whereas we should + prefer the longer newline sequence, as does the code in pcre2_match(). + + Otherwise, in the case of UTF-8 or UTF-16 matching, the advance must be one + character, not one byte. */ + + else if (g_notempty != 0) /* There was a previous null match */ + { + uint16_t nl = FLD(compiled_code, newline_convention); + PCRE2_SIZE start_offset = dat_datctl.offset; /* Where the match was */ + PCRE2_SIZE end_offset = start_offset + 1; + + if ((nl == PCRE2_NEWLINE_CRLF || nl == PCRE2_NEWLINE_ANY || + nl == PCRE2_NEWLINE_ANYCRLF) && + start_offset < ulen - 1 && + CODE_UNIT(pp, start_offset) == '\r' && + CODE_UNIT(pp, end_offset) == '\n') + end_offset++; + + else if (utf && test_mode != PCRE32_MODE) + { + if (test_mode == PCRE8_MODE) + { + for (; end_offset < ulen; end_offset++) + if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break; + } + else /* 16-bit mode */ + { + for (; end_offset < ulen; end_offset++) + if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break; + } + } + + SETFLDVEC(match_data, ovector, 0, start_offset); + SETFLDVEC(match_data, ovector, 1, end_offset); + } /* End of handling null match in a global loop */ + + /* A "normal" match failure. There will be a negative error number in + capcount. */ + + else + { + int mlen; + + switch(capcount) + { + case PCRE2_ERROR_NOMATCH: + if (gmatched == 0) + { + fprintf(outfile, "No match"); + if ((dat_datctl.control & CTL_MARK) != 0 && + TESTFLD(match_data, mark, !=, NULL)) + { + fprintf(outfile, ", mark = "); + PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); + } + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + fprintf(outfile, "\n"); + } + break; + + case PCRE2_ERROR_BADUTFOFFSET: + fprintf(outfile, "Error %d (bad UTF-%d offset)\n", capcount, test_mode); + break; + + default: + fprintf(outfile, "Failed: error %d: ", capcount); + PCRE2_GET_ERROR_MESSAGE(mlen, capcount, pbuffer); + PCHARSV(CASTVAR(void *, pbuffer), 0, mlen, FALSE, outfile); + if (capcount <= PCRE2_ERROR_UTF8_ERR1 && + capcount >= PCRE2_ERROR_UTF32_ERR2) + { + PCRE2_SIZE startchar; + PCRE2_GET_STARTCHAR(startchar, match_data); + fprintf(outfile, " at offset %lu", (unsigned long int)startchar); + } + fprintf(outfile, "\n"); + break; + } + + break; /* Out of the /g loop */ + } /* End of failed match handling */ + + /* Control reaches here in two circumstances: (a) after a match, and (b) + after a non-match that immediately followed a match on an empty string when + doing a global search. Such a match is done with PCRE2_NOTEMPTY_ATSTART and + PCRE2_ANCHORED set in g_notempty. The code above turns it into a fake match + of one character. So effectively we get here only after a match. If we + are not doing a global search, we are done. */ + + if ((dat_datctl.control & CTL_ANYGLOB) == 0) break; else + { + PCRE2_SIZE end_offset = FLD(match_data, ovector)[1]; + + /* We must now set up for the next iteration of a global search. If we have + matched an empty string, first check to see if we are at the end of the + subject. If so, the loop is over. Otherwise, mimic what Perl's /g option + does. Set PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED and try the match again + at the same point. If this fails it will be picked up above, where a fake + match is set up so that at this point we advance to the next character. */ + + if (FLD(match_data, ovector)[0] == end_offset) + { + if (end_offset == ulen) break; /* End of subject */ + g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; + } + + /* However, even after matching a non-empty string, there is still one + tricky case. If a pattern contains \K within a lookbehind assertion at the + start, the end of the matched string can be at the offset where the match + started. In the case of a normal /g iteration without special action, this + leads to a loop that keeps on returning the same substring. The loop would + be caught above, but we really want to move on to the next match. */ + + else + { + g_notempty = 0; /* Set for a "normal" repeat */ + if ((dat_datctl.control & CTL_GLOBAL) != 0) + { + PCRE2_SIZE startchar; + PCRE2_GET_STARTCHAR(startchar, match_data); + if (end_offset <= startchar) + { + if (startchar >= ulen) break; /* End of subject */ + end_offset = startchar + 1; + if (utf && test_mode != PCRE32_MODE) + { + if (test_mode == PCRE8_MODE) + { + for (; end_offset < ulen; end_offset++) + if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break; + } + else /* 16-bit mode */ + { + for (; end_offset < ulen; end_offset++) + if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break; + } + } + } + } + } + + /* For /g (global), update the start offset, leaving the rest alone. */ + + if ((dat_datctl.control & CTL_GLOBAL) != 0) + dat_datctl.offset = end_offset; + + /* For altglobal, just update the pointer and length. */ + + else + { + pp += end_offset * code_unit_size; + len -= end_offset * code_unit_size; + ulen -= end_offset; + } + } + } /* End of global loop */ + +show_memory = FALSE; +return PR_OK; +} + + + + +/************************************************* +* Print PCRE2 version * +*************************************************/ + +static void +print_version(FILE *f) +{ +VERSION_TYPE *vp; +fprintf(f, "PCRE2 version "); +for (vp = version; *vp != 0; vp++) fprintf(f, "%c", *vp); +fprintf(f, "\n"); +} + + + +/************************************************* +* Print Unicode version * +*************************************************/ + +static void +print_unicode_version(FILE *f) +{ +VERSION_TYPE *vp; +fprintf(f, "Unicode version "); +for (vp = uversion; *vp != 0; vp++) fprintf(f, "%c", *vp); +} + + + +/************************************************* +* Print JIT target * +*************************************************/ + +static void +print_jit_target(FILE *f) +{ +VERSION_TYPE *vp; +for (vp = jittarget; *vp != 0; vp++) fprintf(f, "%c", *vp); +} + + + +/************************************************* +* Print newline configuration * +*************************************************/ + +/* Output is always to stdout. + +Arguments: + rc the return code from PCRE2_CONFIG_NEWLINE + isc TRUE if called from "-C newline" +Returns: nothing +*/ + +static void +print_newline_config(uint32_t optval, BOOL isc) +{ +if (!isc) printf(" Newline sequence is "); +if (optval < sizeof(newlines)/sizeof(char *)) + printf("%s\n", newlines[optval]); +else + printf("a non-standard value: %d\n", optval); +} + + + +/************************************************* +* Usage function * +*************************************************/ + +static void +usage(void) +{ +printf("Usage: pcre2test [options] [ []]\n\n"); +printf("Input and output default to stdin and stdout.\n"); +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) +printf("If input is a terminal, readline() is used to read from it.\n"); +#else +printf("This version of pcre2test is not linked with readline().\n"); +#endif +printf("\nOptions:\n"); +#ifdef SUPPORT_PCRE2_8 +printf(" -8 use the 8-bit library\n"); +#endif +#ifdef SUPPORT_PCRE2_16 +printf(" -16 use the 16-bit library\n"); +#endif +#ifdef SUPPORT_PCRE2_32 +printf(" -32 use the 32-bit library\n"); +#endif +printf(" -b set default pattern control 'fullbincode'\n"); +printf(" -C show PCRE2 compile-time options and exit\n"); +printf(" -C arg show a specific compile-time option and exit with its\n"); +printf(" value if numeric (else 0). The arg can be:\n"); +printf(" backslash-C use of \\C is enabled [0, 1]\n"); +printf(" bsr \\R type [ANYCRLF, ANY]\n"); +printf(" ebcdic compiled for EBCDIC character code [0,1]\n"); +printf(" ebcdic-nl NL code if compiled for EBCDIC\n"); +printf(" jit just-in-time compiler supported [0, 1]\n"); +printf(" linksize internal link size [2, 3, 4]\n"); +printf(" newline newline type [CR, LF, CRLF, ANYCRLF, ANY]\n"); +printf(" pcre2-8 8 bit library support enabled [0, 1]\n"); +printf(" pcre2-16 16 bit library support enabled [0, 1]\n"); +printf(" pcre2-32 32 bit library support enabled [0, 1]\n"); +printf(" unicode Unicode and UTF support enabled [0, 1]\n"); +printf(" -d set default pattern control 'debug'\n"); +printf(" -dfa set default subject control 'dfa'\n"); +printf(" -help show usage information\n"); +printf(" -i set default pattern control 'info'\n"); +printf(" -jit set default pattern control 'jit'\n"); +printf(" -q quiet: do not output PCRE2 version number at start\n"); +printf(" -pattern set default pattern control fields\n"); +printf(" -subject set default subject control fields\n"); +printf(" -S set stack size to megabytes\n"); +printf(" -t [] time compilation and execution, repeating times\n"); +printf(" -tm [] time execution (matching) only, repeating times\n"); +printf(" -T same as -t, but show total times at the end\n"); +printf(" -TM same as -tm, but show total time at the end\n"); +printf(" -version show PCRE2 version and exit\n"); +} + + + +/************************************************* +* Handle -C option * +*************************************************/ + +/* This option outputs configuration options and sets an appropriate return +code when asked for a single option. The code is abstracted into a separate +function because of its size. Use whichever pcre2_config() function is +available. + +Argument: an option name or NULL +Returns: the return code +*/ + +static int +c_option(const char *arg) +{ +uint32_t optval; +int yield = 0; + +if (arg != NULL) + { + unsigned int i; + + for (i = 0; i < COPTLISTCOUNT; i++) + if (strcmp(arg, coptlist[i].name) == 0) break; + + if (i >= COPTLISTCOUNT) + { + fprintf(stderr, "** Unknown -C option '%s'\n", arg); + return -1; + } + + switch (coptlist[i].type) + { + case CONF_BSR: + (void)PCRE2_CONFIG(coptlist[i].value, &optval); + printf("%s\n", optval? "ANYCRLF" : "ANY"); + break; + + case CONF_FIX: + yield = coptlist[i].value; + printf("%d\n", yield); + break; + + case CONF_FIZ: + optval = coptlist[i].value; + printf("%d\n", optval); + break; + + case CONF_INT: + (void)PCRE2_CONFIG(coptlist[i].value, &yield); + printf("%d\n", yield); + break; + + case CONF_NL: + (void)PCRE2_CONFIG(coptlist[i].value, &optval); + print_newline_config(optval, TRUE); + break; + } + +/* For VMS, return the value by setting a symbol, for certain values only. */ + +#ifdef __VMS + if (copytlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT) + { + char ucname[16]; + strcpy(ucname, coptlist[i].name); + for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i]; + vms_setsymbol(ucname, 0, optval); + } +#endif + + return yield; + } + +/* No argument for -C: output all configuration information. */ + +print_version(stdout); +printf("Compiled with\n"); + +#ifdef EBCDIC +printf(" EBCDIC code support: LF is 0x%02x\n", CHAR_LF); +#if defined NATIVE_ZOS +printf(" EBCDIC code page %s or similar\n", pcrz_cpversion()); +#endif +#endif + +#ifdef SUPPORT_PCRE2_8 +printf(" 8-bit support\n"); +#endif +#ifdef SUPPORT_PCRE2_16 +printf(" 16-bit support\n"); +#endif +#ifdef SUPPORT_PCRE2_32 +printf(" 32-bit support\n"); +#endif + +(void)PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, &optval); +if (optval != 0) + { + printf(" UTF and UCP support ("); + print_unicode_version(stdout); + printf(")\n"); + } +else printf(" No Unicode support\n"); + +(void)PCRE2_CONFIG(PCRE2_CONFIG_JIT, &optval); +if (optval != 0) + { + printf(" Just-in-time compiler support: "); + print_jit_target(stdout); + printf("\n"); + } +else + { + printf(" No just-in-time compiler support\n"); + } + +(void)PCRE2_CONFIG(PCRE2_CONFIG_NEWLINE, &optval); +print_newline_config(optval, FALSE); +(void)PCRE2_CONFIG(PCRE2_CONFIG_BSR, &optval); +printf(" \\R matches %s\n", optval? "CR, LF, or CRLF only" : + "all Unicode newlines"); +#ifdef NEVER_BACKSLASH_C +printf(" \\C is not supported\n"); +#else +printf(" \\C is supported\n"); +#endif +(void)PCRE2_CONFIG(PCRE2_CONFIG_LINKSIZE, &optval); +printf(" Internal link size = %d\n", optval); +(void)PCRE2_CONFIG(PCRE2_CONFIG_PARENSLIMIT, &optval); +printf(" Parentheses nest limit = %d\n", optval); +(void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval); +printf(" Default match limit = %d\n", optval); +(void)PCRE2_CONFIG(PCRE2_CONFIG_RECURSIONLIMIT, &optval); +printf(" Default recursion depth limit = %d\n", optval); +(void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &optval); +printf(" Match recursion uses %s", optval? "stack" : "heap"); + +printf("\n"); +return 0; +} + + + +/************************************************* +* Main Program * +*************************************************/ + +int +main(int argc, char **argv) +{ +uint32_t yield = 0; +uint32_t op = 1; +uint32_t stack_size; +BOOL notdone = TRUE; +BOOL quiet = FALSE; +BOOL showtotaltimes = FALSE; +BOOL skipping = FALSE; +char *arg_subject = NULL; +char *arg_pattern = NULL; + +/* The offsets to the options and control bits fields of the pattern and data +control blocks must be the same so that common options and controls such as +"anchored" or "memory" can work for either of them from a single table entry. +We cannot test this till runtime because "offsetof" does not work in the +preprocessor. */ + +if (PO(options) != DO(options) || PO(control) != DO(control) || + PO(control2) != DO(control2)) + { + fprintf(stderr, "** Coding error: " + "options and control offsets for pattern and data must be the same.\n"); + return 1; + } + +/* Get the PCRE2 and Unicode version number and JIT target information, at the +same time checking that a request for the length gives the same answer. Also +check lengths for non-string items. */ + +if (PCRE2_CONFIG(PCRE2_CONFIG_VERSION, NULL) != + PCRE2_CONFIG(PCRE2_CONFIG_VERSION, version) || + + PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, NULL) != + PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, uversion) || + + PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, NULL) != + PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, jittarget) || + + PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, NULL) != sizeof(uint32_t) || + PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, NULL) != sizeof(uint32_t)) + { + fprintf(stderr, "** Error in pcre2_config(): bad length\n"); + return 1; + } + +/* Get buffers from malloc() so that valgrind will check their misuse when +debugging. They grow automatically when very long lines are read. The 16- +and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */ + +buffer = (uint8_t *)malloc(pbuffer8_size); +pbuffer8 = (uint8_t *)malloc(pbuffer8_size); + +/* The following _setmode() stuff is some Windows magic that tells its runtime +library to translate CRLF into a single LF character. At least, that's what +I've been told: never having used Windows I take this all on trust. Originally +it set 0x8000, but then I was advised that _O_BINARY was better. */ + +#if defined(_WIN32) || defined(WIN32) +_setmode( _fileno( stdout ), _O_BINARY ); +#endif + +/* Initialization that does not depend on the running mode. */ + +locale_name[0] = 0; +memset(&def_patctl, 0, sizeof(patctl)); +memset(&def_datctl, 0, sizeof(datctl)); +def_datctl.oveccount = DEFAULT_OVECCOUNT; +def_datctl.copy_numbers[0] = -1; +def_datctl.get_numbers[0] = -1; +def_datctl.cfail[0] = def_datctl.cfail[1] = CFAIL_UNSET; + +/* Scan command line options. */ + +while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) + { + char *endptr; + char *arg = argv[op]; + unsigned long uli; + + /* Display and/or set return code for configuration options. */ + + if (strcmp(arg, "-C") == 0) + { + yield = c_option(argv[op + 1]); + goto EXIT; + } + + /* Select operating mode */ + + if (strcmp(arg, "-8") == 0) + { +#ifdef SUPPORT_PCRE2_8 + test_mode = PCRE8_MODE; +#else + fprintf(stderr, + "** This version of PCRE2 was built without 8-bit support\n"); + exit(1); +#endif + } + else if (strcmp(arg, "-16") == 0) + { +#ifdef SUPPORT_PCRE2_16 + test_mode = PCRE16_MODE; +#else + fprintf(stderr, + "** This version of PCRE2 was built without 16-bit support\n"); + exit(1); +#endif + } + else if (strcmp(arg, "-32") == 0) + { +#ifdef SUPPORT_PCRE2_32 + test_mode = PCRE32_MODE; +#else + fprintf(stderr, + "** This version of PCRE2 was built without 32-bit support\n"); + exit(1); +#endif + } + + /* Set quiet (no version verification) */ + + else if (strcmp(arg, "-q") == 0) quiet = TRUE; + + /* Set system stack size */ + + else if (strcmp(arg, "-S") == 0 && argc > 2 && + ((uli = strtoul(argv[op+1], &endptr, 10)), *endptr == 0)) + { +#if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS) || defined(__VMS) + fprintf(stderr, "pcre2test: -S is not supported on this OS\n"); + exit(1); +#else + int rc; + struct rlimit rlim; + if (U32OVERFLOW(uli)) + { + fprintf(stderr, "+++ Argument for -S is too big\n"); + exit(1); + } + stack_size = (uint32_t)uli; + getrlimit(RLIMIT_STACK, &rlim); + rlim.rlim_cur = stack_size * 1024 * 1024; + if (rlim.rlim_cur > rlim.rlim_max) + { + fprintf(stderr, + "pcre2test: requested stack size %luM is greater than hard limit %lu\n", + (unsigned long int)stack_size, + (unsigned long int)(rlim.rlim_max)); + exit(1); + } + rc = setrlimit(RLIMIT_STACK, &rlim); + if (rc != 0) + { + fprintf(stderr, "pcre2test: setting stack size %luM failed: %s\n", + (unsigned long int)stack_size, strerror(errno)); + exit(1); + } + op++; + argc--; +#endif + } + + /* Set some common pattern and subject controls */ + + else if (strcmp(arg, "-dfa") == 0) def_datctl.control |= CTL_DFA; + else if (strcmp(arg, "-b") == 0) def_patctl.control |= CTL_FULLBINCODE; + else if (strcmp(arg, "-d") == 0) def_patctl.control |= CTL_DEBUG; + else if (strcmp(arg, "-i") == 0) def_patctl.control |= CTL_INFO; + else if (strcmp(arg, "-jit") == 0) + { + def_patctl.jit = 7; /* full & partial */ +#ifndef SUPPORT_JIT + fprintf(stderr, "** Warning: JIT support is not available: " + "-jit calls functions that do nothing.\n"); +#endif + } + + /* Set timing parameters */ + + else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0 || + strcmp(arg, "-T") == 0 || strcmp(arg, "-TM") == 0) + { + int both = arg[2] == 0; + showtotaltimes = arg[1] == 'T'; + if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0)) + { + if (U32OVERFLOW(uli)) + { + fprintf(stderr, "+++ Argument for %s is too big\n", arg); + exit(1); + } + timeitm = (int)uli; + op++; + argc--; + } + else timeitm = LOOPREPEAT; + if (both) timeit = timeitm; + } + + /* Give help */ + + else if (strcmp(arg, "-help") == 0 || + strcmp(arg, "--help") == 0) + { + usage(); + goto EXIT; + } + + /* Show version */ + + else if (strcmp(arg, "-version") == 0 || + strcmp(arg, "--version") == 0) + { + print_version(stdout); + goto EXIT; + } + + /* The following options save their data for processing once we know what + the running mode is. */ + + else if (strcmp(arg, "-subject") == 0) + { + arg_subject = argv[op+1]; + goto CHECK_VALUE_EXISTS; + } + + else if (strcmp(arg, "-pattern") == 0) + { + arg_pattern = argv[op+1]; + CHECK_VALUE_EXISTS: + if (argc <= 2) + { + fprintf(stderr, "** Missing value for %s\n", arg); + yield = 1; + goto EXIT; + } + op++; + argc--; + } + + /* Unrecognized option */ + + else + { + fprintf(stderr, "** Unknown or malformed option '%s'\n", arg); + usage(); + yield = 1; + goto EXIT; + } + op++; + argc--; + } + +/* Initialize things that cannot be done until we know which test mode we are +running in. When HEAP_MATCH_RECURSE is undefined, calling pcre2_set_recursion_ +memory_management() is a no-op, but we call it in order to exercise it. Also +exercise the general context copying function, which is not otherwise used. */ + +code_unit_size = test_mode/8; +max_oveccount = DEFAULT_OVECCOUNT; + +/* Use macros to save a lot of duplication. */ + +#define CREATECONTEXTS \ + G(general_context,BITS) = G(pcre2_general_context_create_,BITS)(&my_malloc, &my_free, NULL); \ + G(general_context_copy,BITS) = G(pcre2_general_context_copy_,BITS)(G(general_context,BITS)); \ + G(default_pat_context,BITS) = G(pcre2_compile_context_create_,BITS)(G(general_context,BITS)); \ + G(pat_context,BITS) = G(pcre2_compile_context_copy_,BITS)(G(default_pat_context,BITS)); \ + G(default_dat_context,BITS) = G(pcre2_match_context_create_,BITS)(G(general_context,BITS)); \ + G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \ + G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS)) + +#ifdef HEAP_MATCH_RECURSE +#define SETRECURSEMEMMAN \ + (void)G(pcre2_set_recursion_memory_management_,BITS) \ + (G(default_dat_context,BITS), \ + &my_stack_malloc, &my_stack_free, NULL) +#else +#define SETRECURSEMEMMAN \ + (void)G(pcre2_set_recursion_memory_management_,BITS)(NULL, NULL, NULL, NULL) +#endif + +/* Call the appropriate functions for the current mode. */ + +#ifdef SUPPORT_PCRE2_8 +#undef BITS +#define BITS 8 +if (test_mode == PCRE8_MODE) + { + CREATECONTEXTS; + SETRECURSEMEMMAN; + } +#endif + +#ifdef SUPPORT_PCRE2_16 +#undef BITS +#define BITS 16 +if (test_mode == PCRE16_MODE) + { + CREATECONTEXTS; + SETRECURSEMEMMAN; + } +#endif + +#ifdef SUPPORT_PCRE2_32 +#undef BITS +#define BITS 32 +if (test_mode == PCRE32_MODE) + { + CREATECONTEXTS; + SETRECURSEMEMMAN; + } +#endif + +/* Set a default parentheses nest limit that is large enough to run the +standard tests (this also exercises the function). */ + +PCRE2_SET_PARENS_NEST_LIMIT(default_pat_context, 220); + +/* Handle command line modifier settings, sending any error messages to +stderr. We need to know the mode before modifying the context, and it is tidier +to do them all in the same way. */ + +outfile = stderr; +if ((arg_pattern != NULL && + !decode_modifiers((uint8_t *)arg_pattern, CTX_DEFPAT, &def_patctl, NULL)) || + (arg_subject != NULL && + !decode_modifiers((uint8_t *)arg_subject, CTX_DEFDAT, NULL, &def_datctl))) + { + yield = 1; + goto EXIT; + } + +/* Sort out the input and output files, defaulting to stdin/stdout. */ + +infile = stdin; +outfile = stdout; + +if (argc > 1 && strcmp(argv[op], "-") != 0) + { + infile = fopen(argv[op], INPUT_MODE); + if (infile == NULL) + { + printf("** Failed to open '%s'\n", argv[op]); + yield = 1; + goto EXIT; + } + } + +if (argc > 2) + { + outfile = fopen(argv[op+1], OUTPUT_MODE); + if (outfile == NULL) + { + printf("** Failed to open '%s'\n", argv[op+1]); + yield = 1; + goto EXIT; + } + } + +/* Output a heading line unless quiet, then process input lines. */ + +if (!quiet) print_version(outfile); + +SET(compiled_code, NULL); + +#ifdef SUPPORT_PCRE2_8 +preg.re_pcre2_code = NULL; +preg.re_match_data = NULL; +#endif + +while (notdone) + { + uint8_t *p; + int rc = PR_OK; + BOOL expectdata = TEST(compiled_code, !=, NULL); +#ifdef SUPPORT_PCRE2_8 + expectdata |= preg.re_pcre2_code != NULL; +#endif + + if (extend_inputline(infile, buffer, expectdata? "data> " : " re> ") == NULL) + break; + if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)buffer); + fflush(outfile); + p = buffer; + + /* If we have a pattern set up for testing, or we are skipping after a + compile failure, a blank line terminates this test; otherwise process the + line as a data line. */ + + if (expectdata || skipping) + { + while (isspace(*p)) p++; + if (*p == 0) + { +#ifdef SUPPORT_PCRE2_8 + if (preg.re_pcre2_code != NULL) + { + regfree(&preg); + preg.re_pcre2_code = NULL; + preg.re_match_data = NULL; + } +#endif /* SUPPORT_PCRE2_8 */ + if (TEST(compiled_code, !=, NULL)) + { + SUB1(pcre2_code_free, compiled_code); + SET(compiled_code, NULL); + } + skipping = FALSE; + setlocale(LC_CTYPE, "C"); + } + else if (!skipping && !(p[0] == '\\' && p[1] == '=' && isspace(p[2]))) + rc = process_data(); + } + + /* We do not have a pattern set up for testing. Lines starting with # are + either comments or special commands. Blank lines are ignored. Otherwise, the + line must start with a valid delimiter. It is then processed as a pattern + line. */ + + else if (*p == '#') + { + if (isspace(p[1]) || p[1] == '!' || p[1] == 0) continue; + rc = process_command(); + } + + else if (strchr("/!\"'`%&-=_:;,@~", *p) != NULL) + { + rc = process_pattern(); + dfa_matched = 0; + } + + else + { + while (isspace(*p)) p++; + if (*p != 0) + { + fprintf(outfile, "** Invalid pattern delimiter '%c' (x%x).\n", *buffer, + *buffer); + rc = PR_SKIP; + } + } + + if (rc == PR_SKIP && !INTERACTIVE(infile)) skipping = TRUE; + else if (rc == PR_ABEND) + { + fprintf(outfile, "** pcre2test run abandoned\n"); + yield = 1; + goto EXIT; + } + } + +/* Finish off a normal run. */ + +if (INTERACTIVE(infile)) fprintf(outfile, "\n"); + +if (showtotaltimes) + { + const char *pad = ""; + fprintf(outfile, "--------------------------------------\n"); + if (timeit > 0) + { + fprintf(outfile, "Total compile time %.4f milliseconds\n", + (((double)total_compile_time * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + if (total_jit_compile_time > 0) + fprintf(outfile, "Total JIT compile %.4f milliseconds\n", + (((double)total_jit_compile_time * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + pad = " "; + } + fprintf(outfile, "Total match time %s%.4f milliseconds\n", pad, + (((double)total_match_time * 1000.0) / (double)timeitm) / + (double)CLOCKS_PER_SEC); + } + + +EXIT: + +if (infile != NULL && infile != stdin) fclose(infile); +if (outfile != NULL && outfile != stdout) fclose(outfile); + +free(buffer); +free(dbuffer); +free(pbuffer8); +free(dfa_workspace); +free((void *)locale_tables); +PCRE2_MATCH_DATA_FREE(match_data); +SUB1(pcre2_code_free, compiled_code); + +while(patstacknext-- > 0) + { + SET(compiled_code, patstack[patstacknext]); + SUB1(pcre2_code_free, compiled_code); + } + +PCRE2_JIT_FREE_UNUSED_MEMORY(general_context); +if (jit_stack != NULL) + { + PCRE2_JIT_STACK_FREE(jit_stack); + } + +#define FREECONTEXTS \ + G(pcre2_general_context_free_,BITS)(G(general_context,BITS)); \ + G(pcre2_general_context_free_,BITS)(G(general_context_copy,BITS)); \ + G(pcre2_compile_context_free_,BITS)(G(pat_context,BITS)); \ + G(pcre2_compile_context_free_,BITS)(G(default_pat_context,BITS)); \ + G(pcre2_match_context_free_,BITS)(G(dat_context,BITS)); \ + G(pcre2_match_context_free_,BITS)(G(default_dat_context,BITS)) + +#ifdef SUPPORT_PCRE2_8 +#undef BITS +#define BITS 8 +regfree(&preg); +FREECONTEXTS; +#endif + +#ifdef SUPPORT_PCRE2_16 +#undef BITS +#define BITS 16 +free(pbuffer16); +FREECONTEXTS; +#endif + +#ifdef SUPPORT_PCRE2_32 +#undef BITS +#define BITS 32 +free(pbuffer32); +FREECONTEXTS; +#endif + +#if defined(__VMS) + yield = SS$_NORMAL; /* Return values via DCL symbols */ +#endif + +return yield; +} + +/* End of pcre2test.c */ diff --git a/pcre2/src/sljit/sljitConfig.h b/pcre2/src/sljit/sljitConfig.h new file mode 100644 index 000000000..1c8a521aa --- /dev/null +++ b/pcre2/src/sljit/sljitConfig.h @@ -0,0 +1,135 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SLJIT_CONFIG_H_ +#define _SLJIT_CONFIG_H_ + +/* --------------------------------------------------------------------- */ +/* Custom defines */ +/* --------------------------------------------------------------------- */ + +/* Put your custom defines here. This empty section will never change + which helps maintaining patches (with diff / patch utilities). */ + +/* --------------------------------------------------------------------- */ +/* Architecture */ +/* --------------------------------------------------------------------- */ + +/* Architecture selection. */ +/* #define SLJIT_CONFIG_X86_32 1 */ +/* #define SLJIT_CONFIG_X86_64 1 */ +/* #define SLJIT_CONFIG_ARM_V5 1 */ +/* #define SLJIT_CONFIG_ARM_V7 1 */ +/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ +/* #define SLJIT_CONFIG_ARM_64 1 */ +/* #define SLJIT_CONFIG_PPC_32 1 */ +/* #define SLJIT_CONFIG_PPC_64 1 */ +/* #define SLJIT_CONFIG_MIPS_32 1 */ +/* #define SLJIT_CONFIG_MIPS_64 1 */ +/* #define SLJIT_CONFIG_SPARC_32 1 */ +/* #define SLJIT_CONFIG_TILEGX 1 */ + +/* #define SLJIT_CONFIG_AUTO 1 */ +/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ + +/* --------------------------------------------------------------------- */ +/* Utilities */ +/* --------------------------------------------------------------------- */ + +/* Useful for thread-safe compiling of global functions. */ +#ifndef SLJIT_UTIL_GLOBAL_LOCK +/* Enabled by default */ +#define SLJIT_UTIL_GLOBAL_LOCK 1 +#endif + +/* Implements a stack like data structure (by using mmap / VirtualAlloc). */ +#ifndef SLJIT_UTIL_STACK +/* Enabled by default */ +#define SLJIT_UTIL_STACK 1 +#endif + +/* Single threaded application. Does not require any locks. */ +#ifndef SLJIT_SINGLE_THREADED +/* Disabled by default. */ +#define SLJIT_SINGLE_THREADED 0 +#endif + +/* --------------------------------------------------------------------- */ +/* Configuration */ +/* --------------------------------------------------------------------- */ + +/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should + define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */ +#ifndef SLJIT_STD_MACROS_DEFINED +/* Disabled by default. */ +#define SLJIT_STD_MACROS_DEFINED 0 +#endif + +/* Executable code allocation: + If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should + define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */ +#ifndef SLJIT_EXECUTABLE_ALLOCATOR +/* Enabled by default. */ +#define SLJIT_EXECUTABLE_ALLOCATOR 1 +#endif + +/* Force cdecl calling convention even if a better calling + convention (e.g. fastcall) is supported by the C compiler. + If this option is enabled, C functions without + SLJIT_CALL can also be called from JIT code. */ +#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION +/* Disabled by default */ +#define SLJIT_USE_CDECL_CALLING_CONVENTION 0 +#endif + +/* Return with error when an invalid argument is passed. */ +#ifndef SLJIT_ARGUMENT_CHECKS +/* Disabled by default */ +#define SLJIT_ARGUMENT_CHECKS 0 +#endif + +/* Debug checks (assertions, etc.). */ +#ifndef SLJIT_DEBUG +/* Enabled by default */ +#define SLJIT_DEBUG 1 +#endif + +/* Verbose operations. */ +#ifndef SLJIT_VERBOSE +/* Enabled by default */ +#define SLJIT_VERBOSE 1 +#endif + +/* + SLJIT_IS_FPU_AVAILABLE + The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE. + zero value - FPU is NOT present. + nonzero value - FPU is present. +*/ + +/* For further configurations, see the beginning of sljitConfigInternal.h */ + +#endif diff --git a/pcre2/src/sljit/sljitConfigInternal.h b/pcre2/src/sljit/sljitConfigInternal.h new file mode 100644 index 000000000..16e3547c9 --- /dev/null +++ b/pcre2/src/sljit/sljitConfigInternal.h @@ -0,0 +1,713 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SLJIT_CONFIG_INTERNAL_H_ +#define _SLJIT_CONFIG_INTERNAL_H_ + +/* + SLJIT defines the following architecture dependent types and macros: + + Types: + sljit_sb, sljit_ub : signed and unsigned 8 bit byte + sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type + sljit_si, sljit_ui : signed and unsigned 32 bit integer type + sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer + sljit_p : unsgined pointer value (usually the same as sljit_uw, but + some 64 bit ABIs may use 32 bit pointers) + sljit_s : single precision floating point value + sljit_d : double precision floating point value + + Macros for feature detection (boolean): + SLJIT_32BIT_ARCHITECTURE : 32 bit architecture + SLJIT_64BIT_ARCHITECTURE : 64 bit architecture + SLJIT_LITTLE_ENDIAN : little endian architecture + SLJIT_BIG_ENDIAN : big endian architecture + SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) + SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information + + Constants: + SLJIT_NUMBER_OF_REGISTERS : number of available registers + SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers + SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers + SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers + SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers + SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers + SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index + SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing + a double precision floating point array by index + SLJIT_SINGLE_SHIFT : the shift required to apply when accessing + a single precision floating point array by index + SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) + SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address + + Other macros: + SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT + SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) +*/ + +/*****************/ +/* Sanity check. */ +/*****************/ + +#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ + || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) +#error "An architecture must be selected" +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ + + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 +#error "Multiple architectures are selected" +#endif + +/********************************************************/ +/* Automatic CPU detection (requires compiler support). */ +/********************************************************/ + +#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) + +#ifndef _WIN32 + +#if defined(__i386__) || defined(__i386) +#define SLJIT_CONFIG_X86_32 1 +#elif defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(__arm__) || defined(__ARM__) +#ifdef __thumb2__ +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) +#define SLJIT_CONFIG_ARM_V7 1 +#else +#define SLJIT_CONFIG_ARM_V5 1 +#endif +#elif defined (__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 +#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__)) +#define SLJIT_CONFIG_PPC_64 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) +#define SLJIT_CONFIG_PPC_32 1 +#elif defined(__mips__) && !defined(_LP64) +#define SLJIT_CONFIG_MIPS_32 1 +#elif defined(__mips64) +#define SLJIT_CONFIG_MIPS_64 1 +#elif defined(__sparc__) || defined(__sparc) +#define SLJIT_CONFIG_SPARC_32 1 +#elif defined(__tilegx__) +#define SLJIT_CONFIG_TILEGX 1 +#else +/* Unsupported architecture */ +#define SLJIT_CONFIG_UNSUPPORTED 1 +#endif + +#else /* !_WIN32 */ + +#if defined(_M_X64) || defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(_ARM_) +#define SLJIT_CONFIG_ARM_V5 1 +#else +#define SLJIT_CONFIG_X86_32 1 +#endif + +#endif /* !WIN32 */ +#endif /* SLJIT_CONFIG_AUTO */ + +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +#undef SLJIT_EXECUTABLE_ALLOCATOR +#endif + +/******************************/ +/* CPU family type detection. */ +/******************************/ + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +#define SLJIT_CONFIG_ARM_32 1 +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#define SLJIT_CONFIG_X86 1 +#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +#define SLJIT_CONFIG_ARM 1 +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_CONFIG_PPC 1 +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +#define SLJIT_CONFIG_MIPS 1 +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) || (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64) +#define SLJIT_CONFIG_SPARC 1 +#endif + +/**********************************/ +/* External function definitions. */ +/**********************************/ + +#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) + +/* These libraries are needed for the macros below. */ +#include +#include + +#endif /* SLJIT_STD_MACROS_DEFINED */ + +/* General macros: + Note: SLJIT is designed to be independent from them as possible. + + In release mode (SLJIT_DEBUG is not defined) only the following + external functions are needed: +*/ + +#ifndef SLJIT_MALLOC +#define SLJIT_MALLOC(size, allocator_data) malloc(size) +#endif + +#ifndef SLJIT_FREE +#define SLJIT_FREE(ptr, allocator_data) free(ptr) +#endif + +#ifndef SLJIT_MEMMOVE +#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) +#endif + +#ifndef SLJIT_ZEROMEM +#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) +#endif + +/***************************/ +/* Compiler helper macros. */ +/***************************/ + +#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) + +#if defined(__GNUC__) && (__GNUC__ >= 3) +#define SLJIT_LIKELY(x) __builtin_expect((x), 1) +#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0) +#else +#define SLJIT_LIKELY(x) (x) +#define SLJIT_UNLIKELY(x) (x) +#endif + +#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ + +#ifndef SLJIT_INLINE +/* Inline functions. Some old compilers do not support them. */ +#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510 +#define SLJIT_INLINE +#else +#define SLJIT_INLINE __inline +#endif +#endif /* !SLJIT_INLINE */ + +#ifndef SLJIT_NOINLINE +/* Not inline functions. */ +#if defined(__GNUC__) +#define SLJIT_NOINLINE __attribute__ ((noinline)) +#else +#define SLJIT_NOINLINE +#endif +#endif /* !SLJIT_INLINE */ + +#ifndef SLJIT_CONST +/* Const variables. */ +#define SLJIT_CONST const +#endif + +#ifndef SLJIT_UNUSED_ARG +/* Unused arguments. */ +#define SLJIT_UNUSED_ARG(arg) (void)arg +#endif + +/*********************************/ +/* Type of public API functions. */ +/*********************************/ + +#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) +/* Static ABI functions. For all-in-one programs. */ + +#if defined(__GNUC__) +/* Disable unused warnings in gcc. */ +#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused)) +#else +#define SLJIT_API_FUNC_ATTRIBUTE static +#endif + +#else +#define SLJIT_API_FUNC_ATTRIBUTE +#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ + +/****************************/ +/* Instruction cache flush. */ +/****************************/ + +#ifndef SLJIT_CACHE_FLUSH + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* Not required to implement on archs with unified caches. */ +#define SLJIT_CACHE_FLUSH(from, to) + +#elif defined __APPLE__ + +/* Supported by all macs since Mac OS 10.5. + However, it does not work on non-jailbroken iOS devices, + although the compilation is successful. */ + +#define SLJIT_CACHE_FLUSH(from, to) \ + sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) + +#elif defined __ANDROID__ + +/* Android lacks __clear_cache; instead, cacheflush should be used. */ + +#define SLJIT_CACHE_FLUSH(from, to) \ + cacheflush((long)(from), (long)(to), 0) + +#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) + +/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + ppc_cache_flush((from), (to)) + +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + +/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + sparc_cache_flush((from), (to)) + +#else + +/* Calls __ARM_NR_cacheflush on ARM-Linux. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + __clear_cache((char*)(from), (char*)(to)) + +#endif + +#endif /* !SLJIT_CACHE_FLUSH */ + +/******************************************************/ +/* Byte/half/int/word/single/double type definitions. */ +/******************************************************/ + +/* 8 bit byte type. */ +typedef unsigned char sljit_ub; +typedef signed char sljit_sb; + +/* 16 bit half-word type. */ +typedef unsigned short int sljit_uh; +typedef signed short int sljit_sh; + +/* 32 bit integer type. */ +typedef unsigned int sljit_ui; +typedef signed int sljit_si; + +/* Machine word type. Enough for storing a pointer. + 32 bit for 32 bit machines. + 64 bit for 64 bit machines. */ +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +/* Just to have something. */ +#define SLJIT_WORD_SHIFT 0 +typedef unsigned long int sljit_uw; +typedef long int sljit_sw; +#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +#define SLJIT_32BIT_ARCHITECTURE 1 +#define SLJIT_WORD_SHIFT 2 +typedef unsigned int sljit_uw; +typedef int sljit_sw; +#else +#define SLJIT_64BIT_ARCHITECTURE 1 +#define SLJIT_WORD_SHIFT 3 +#ifdef _WIN32 +typedef unsigned __int64 sljit_uw; +typedef __int64 sljit_sw; +#else +typedef unsigned long int sljit_uw; +typedef long int sljit_sw; +#endif +#endif + +typedef sljit_uw sljit_p; + +/* Floating point types. */ +typedef float sljit_s; +typedef double sljit_d; + +/* Shift for pointer sized data. */ +#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT + +/* Shift for double precision sized data. */ +#define SLJIT_DOUBLE_SHIFT 3 +#define SLJIT_SINGLE_SHIFT 2 + +#ifndef SLJIT_W + +/* Defining long constants. */ +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#define SLJIT_W(w) (w##ll) +#else +#define SLJIT_W(w) (w) +#endif + +#endif /* !SLJIT_W */ + +/*************************/ +/* Endianness detection. */ +/*************************/ + +#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) + +/* These macros are mostly useful for the applications. */ +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + +#ifdef __LITTLE_ENDIAN__ +#define SLJIT_LITTLE_ENDIAN 1 +#else +#define SLJIT_BIG_ENDIAN 1 +#endif + +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + +#ifdef __MIPSEL__ +#define SLJIT_LITTLE_ENDIAN 1 +#else +#define SLJIT_BIG_ENDIAN 1 +#endif + +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + +#define SLJIT_BIG_ENDIAN 1 + +#else +#define SLJIT_LITTLE_ENDIAN 1 +#endif + +#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */ + +/* Sanity check. */ +#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#error "Exactly one endianness must be selected" +#endif + +#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#error "Exactly one endianness must be selected" +#endif + +#ifndef SLJIT_UNALIGNED + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_UNALIGNED 1 +#endif + +#endif /* !SLJIT_UNALIGNED */ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +/* Auto detect SSE2 support using CPUID. + On 64 bit x86 cpus, sse2 must be present. */ +#define SLJIT_DETECT_SSE2 1 +#endif + +/*****************************************************************************************/ +/* Calling convention of functions generated by SLJIT or called from the generated code. */ +/*****************************************************************************************/ + +#ifndef SLJIT_CALL + +#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) + +/* Force cdecl. */ +#define SLJIT_CALL + +#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +#if defined(__GNUC__) && !defined(__APPLE__) + +#define SLJIT_CALL __attribute__ ((fastcall)) +#define SLJIT_X86_32_FASTCALL 1 + +#elif defined(_MSC_VER) + +#define SLJIT_CALL __fastcall +#define SLJIT_X86_32_FASTCALL 1 + +#elif defined(__BORLANDC__) + +#define SLJIT_CALL __msfastcall +#define SLJIT_X86_32_FASTCALL 1 + +#else /* Unknown compiler. */ + +/* The cdecl attribute is the default. */ +#define SLJIT_CALL + +#endif + +#else /* Non x86-32 architectures. */ + +#define SLJIT_CALL + +#endif /* SLJIT_CONFIG_X86_32 */ + +#endif /* !SLJIT_CALL */ + +#ifndef SLJIT_INDIRECT_CALL +#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \ + || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) +/* It seems certain ppc compilers use an indirect addressing for functions + which makes things complicated. */ +#define SLJIT_INDIRECT_CALL 1 +#endif +#endif /* SLJIT_INDIRECT_CALL */ + +/* The offset which needs to be substracted from the return address to +determine the next executed instruction after return. */ +#ifndef SLJIT_RETURN_ADDRESS_OFFSET +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define SLJIT_RETURN_ADDRESS_OFFSET 8 +#else +#define SLJIT_RETURN_ADDRESS_OFFSET 0 +#endif +#endif /* SLJIT_RETURN_ADDRESS_OFFSET */ + +/***************************************************/ +/* Functions of the built-in executable allocator. */ +/***************************************************/ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); +#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) +#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) +#endif + +/**********************************************/ +/* Registers and locals offset determination. */ +/**********************************************/ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +#define SLJIT_NUMBER_OF_REGISTERS 10 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) +#define SLJIT_LOCALS_OFFSET_BASE ((2 + 4) * sizeof(sljit_sw)) +#else +/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */ +#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1 + 4) * sizeof(sljit_sw)) +#endif /* SLJIT_X86_32_FASTCALL */ + +#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +#ifndef _WIN64 +#define SLJIT_NUMBER_OF_REGISTERS 12 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6 +#define SLJIT_LOCALS_OFFSET_BASE (sizeof(sljit_sw)) +#else +#define SLJIT_NUMBER_OF_REGISTERS 12 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_LOCALS_OFFSET_BASE ((4 + 2) * sizeof(sljit_sw)) +#endif /* _WIN64 */ + +#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + +#define SLJIT_NUMBER_OF_REGISTERS 11 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_LOCALS_OFFSET_BASE 0 + +#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + +#define SLJIT_NUMBER_OF_REGISTERS 11 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 +#define SLJIT_LOCALS_OFFSET_BASE 0 + +#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) + +#define SLJIT_NUMBER_OF_REGISTERS 25 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 +#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw)) + +#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) + +#define SLJIT_NUMBER_OF_REGISTERS 22 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17 +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX) +#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw)) +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +/* Add +1 for double alignment. */ +#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw)) +#else +#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw)) +#endif /* SLJIT_CONFIG_PPC_64 || _AIX */ + +#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) + +#define SLJIT_NUMBER_OF_REGISTERS 17 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw)) +#else +#define SLJIT_LOCALS_OFFSET_BASE 0 +#endif + +#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) + +#define SLJIT_NUMBER_OF_REGISTERS 18 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14 +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +/* Add +1 for double alignment. */ +#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw)) +#endif + +#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) + +#define SLJIT_NUMBER_OF_REGISTERS 10 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5 +#define SLJIT_LOCALS_OFFSET_BASE 0 + +#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + +#define SLJIT_NUMBER_OF_REGISTERS 0 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0 +#define SLJIT_LOCALS_OFFSET_BASE 0 + +#endif + +#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE) + +#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \ + (SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS) + +#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6 +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64) +#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1 +#else +#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 +#endif + +#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ + (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) + +/*************************************/ +/* Debug and verbose related macros. */ +/*************************************/ + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#include +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + +#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP) + +/* SLJIT_HALT_PROCESS must halt the process. */ +#ifndef SLJIT_HALT_PROCESS +#include + +#define SLJIT_HALT_PROCESS() \ + abort(); +#endif /* !SLJIT_HALT_PROCESS */ + +#include + +#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */ + +/* Feel free to redefine these two macros. */ +#ifndef SLJIT_ASSERT + +#define SLJIT_ASSERT(x) \ + do { \ + if (SLJIT_UNLIKELY(!(x))) { \ + printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ + SLJIT_HALT_PROCESS(); \ + } \ + } while (0) + +#endif /* !SLJIT_ASSERT */ + +#ifndef SLJIT_ASSERT_STOP + +#define SLJIT_ASSERT_STOP() \ + do { \ + printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ + SLJIT_HALT_PROCESS(); \ + } while (0) + +#endif /* !SLJIT_ASSERT_STOP */ + +#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ + +/* Forcing empty, but valid statements. */ +#undef SLJIT_ASSERT +#undef SLJIT_ASSERT_STOP + +#define SLJIT_ASSERT(x) \ + do { } while (0) +#define SLJIT_ASSERT_STOP() \ + do { } while (0) + +#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ + +#ifndef SLJIT_COMPILE_ASSERT + +/* Should be improved eventually. */ +#define SLJIT_COMPILE_ASSERT(x, description) \ + SLJIT_ASSERT(x) + +#endif /* !SLJIT_COMPILE_ASSERT */ + +#endif diff --git a/pcre2/src/sljit/sljitExecAllocator.c b/pcre2/src/sljit/sljitExecAllocator.c new file mode 100644 index 000000000..f24ed3379 --- /dev/null +++ b/pcre2/src/sljit/sljitExecAllocator.c @@ -0,0 +1,312 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple executable memory allocator + + It is assumed, that executable code blocks are usually medium (or sometimes + large) memory blocks, and the allocator is not too frequently called (less + optimized than other allocators). Thus, using it as a generic allocator is + not suggested. + + How does it work: + Memory is allocated in continuous memory areas called chunks by alloc_chunk() + Chunk format: + [ block ][ block ] ... [ block ][ block terminator ] + + All blocks and the block terminator is started with block_header. The block + header contains the size of the previous and the next block. These sizes + can also contain special values. + Block size: + 0 - The block is a free_block, with a different size member. + 1 - The block is a block terminator. + n - The block is used at the moment, and the value contains its size. + Previous block size: + 0 - This is the first block of the memory chunk. + n - The size of the previous block. + + Using these size values we can go forward or backward on the block chain. + The unused blocks are stored in a chain list pointed by free_blocks. This + list is useful if we need to find a suitable memory area when the allocator + is called. + + When a block is freed, the new free block is connected to its adjacent free + blocks if possible. + + [ free block ][ used block ][ free block ] + and "used block" is freed, the three blocks are connected together: + [ one big free block ] +*/ + +/* --------------------------------------------------------------------- */ +/* System (OS) functions */ +/* --------------------------------------------------------------------- */ + +/* 64 KByte. */ +#define CHUNK_SIZE 0x10000 + +/* + alloc_chunk / free_chunk : + * allocate executable system memory chunks + * the size is always divisible by CHUNK_SIZE + allocator_grab_lock / allocator_release_lock : + * make the allocator thread safe + * can be empty if the OS (or the application) does not support threading + * only the allocator requires this lock, sljit is fully thread safe + as it only uses local variables +*/ + +#ifdef _WIN32 + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +} + +static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) +{ + SLJIT_UNUSED_ARG(size); + VirtualFree(chunk, 0, MEM_RELEASE); +} + +#else + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void* retval; + +#ifdef MAP_ANON + retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); +#else + if (dev_zero < 0) { + if (open_dev_zero()) + return NULL; + } + retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); +#endif + + return (retval != MAP_FAILED) ? retval : NULL; +} + +static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#endif + +/* --------------------------------------------------------------------- */ +/* Common functions */ +/* --------------------------------------------------------------------- */ + +#define CHUNK_MASK (~(CHUNK_SIZE - 1)) + +struct block_header { + sljit_uw size; + sljit_uw prev_size; +}; + +struct free_block { + struct block_header header; + struct free_block *next; + struct free_block *prev; + sljit_uw size; +}; + +#define AS_BLOCK_HEADER(base, offset) \ + ((struct block_header*)(((sljit_ub*)base) + offset)) +#define AS_FREE_BLOCK(base, offset) \ + ((struct free_block*)(((sljit_ub*)base) + offset)) +#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) +#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) + +static struct free_block* free_blocks; +static sljit_uw allocated_size; +static sljit_uw total_size; + +static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) +{ + free_block->header.size = 0; + free_block->size = size; + + free_block->next = free_blocks; + free_block->prev = 0; + if (free_blocks) + free_blocks->prev = free_block; + free_blocks = free_block; +} + +static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) +{ + if (free_block->next) + free_block->next->prev = free_block->prev; + + if (free_block->prev) + free_block->prev->next = free_block->next; + else { + SLJIT_ASSERT(free_blocks == free_block); + free_blocks = free_block->next; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + struct block_header *header; + struct block_header *next_header; + struct free_block *free_block; + sljit_uw chunk_size; + + allocator_grab_lock(); + if (size < sizeof(struct free_block)) + size = sizeof(struct free_block); + size = ALIGN_SIZE(size); + + free_block = free_blocks; + while (free_block) { + if (free_block->size >= size) { + chunk_size = free_block->size; + if (chunk_size > size + 64) { + /* We just cut a block from the end of the free block. */ + chunk_size -= size; + free_block->size = chunk_size; + header = AS_BLOCK_HEADER(free_block, chunk_size); + header->prev_size = chunk_size; + AS_BLOCK_HEADER(header, size)->prev_size = size; + } + else { + sljit_remove_free_block(free_block); + header = (struct block_header*)free_block; + size = chunk_size; + } + allocated_size += size; + header->size = size; + allocator_release_lock(); + return MEM_START(header); + } + free_block = free_block->next; + } + + chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; + header = (struct block_header*)alloc_chunk(chunk_size); + if (!header) { + allocator_release_lock(); + return NULL; + } + + chunk_size -= sizeof(struct block_header); + total_size += chunk_size; + + header->prev_size = 0; + if (chunk_size > size + 64) { + /* Cut the allocated space into a free and a used block. */ + allocated_size += size; + header->size = size; + chunk_size -= size; + + free_block = AS_FREE_BLOCK(header, size); + free_block->header.prev_size = size; + sljit_insert_free_block(free_block, chunk_size); + next_header = AS_BLOCK_HEADER(free_block, chunk_size); + } + else { + /* All space belongs to this allocation. */ + allocated_size += chunk_size; + header->size = chunk_size; + next_header = AS_BLOCK_HEADER(header, chunk_size); + } + next_header->size = 1; + next_header->prev_size = chunk_size; + allocator_release_lock(); + return MEM_START(header); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + struct block_header *header; + struct free_block* free_block; + + allocator_grab_lock(); + header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); + allocated_size -= header->size; + + /* Connecting free blocks together if possible. */ + + /* If header->prev_size == 0, free_block will equal to header. + In this case, free_block->header.size will be > 0. */ + free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size); + if (SLJIT_UNLIKELY(!free_block->header.size)) { + free_block->size += header->size; + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + else { + free_block = (struct free_block*)header; + sljit_insert_free_block(free_block, header->size); + } + + header = AS_BLOCK_HEADER(free_block, free_block->size); + if (SLJIT_UNLIKELY(!header->size)) { + free_block->size += ((struct free_block*)header)->size; + sljit_remove_free_block((struct free_block*)header); + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + + /* The whole chunk is free. */ + if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { + /* If this block is freed, we still have (allocated_size / 2) free space. */ + if (total_size - free_block->size > (allocated_size * 3 / 2)) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + sizeof(struct block_header)); + } + } + + allocator_release_lock(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + struct free_block* free_block; + struct free_block* next_free_block; + + allocator_grab_lock(); + + free_block = free_blocks; + while (free_block) { + next_free_block = free_block->next; + if (!free_block->header.prev_size && + AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + sizeof(struct block_header)); + } + free_block = next_free_block; + } + + SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); + allocator_release_lock(); +} diff --git a/pcre2/src/sljit/sljitLir.c b/pcre2/src/sljit/sljitLir.c new file mode 100644 index 000000000..0f1b1c9cc --- /dev/null +++ b/pcre2/src/sljit/sljitLir.c @@ -0,0 +1,2029 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sljitLir.h" + +#define CHECK_ERROR() \ + do { \ + if (SLJIT_UNLIKELY(compiler->error)) \ + return compiler->error; \ + } while (0) + +#define CHECK_ERROR_PTR() \ + do { \ + if (SLJIT_UNLIKELY(compiler->error)) \ + return NULL; \ + } while (0) + +#define FAIL_IF(expr) \ + do { \ + if (SLJIT_UNLIKELY(expr)) \ + return compiler->error; \ + } while (0) + +#define PTR_FAIL_IF(expr) \ + do { \ + if (SLJIT_UNLIKELY(expr)) \ + return NULL; \ + } while (0) + +#define FAIL_IF_NULL(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_ALLOC_FAILED; \ + return SLJIT_ERR_ALLOC_FAILED; \ + } \ + } while (0) + +#define PTR_FAIL_IF_NULL(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_ALLOC_FAILED; \ + return NULL; \ + } \ + } while (0) + +#define PTR_FAIL_WITH_EXEC_IF(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \ + return NULL; \ + } \ + } while (0) + +#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + +#define GET_OPCODE(op) \ + ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + +#define GET_FLAGS(op) \ + ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) + +#define GET_ALL_FLAGS(op) \ + ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + +#define TYPE_CAST_NEEDED(op) \ + (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) + +#define BUF_SIZE 4096 + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) +#define ABUF_SIZE 2048 +#else +#define ABUF_SIZE 4096 +#endif + +/* Parameter parsing. */ +#define REG_MASK 0x3f +#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) +#define OFFS_REG_MASK (REG_MASK << 8) +#define TO_OFFS_REG(reg) ((reg) << 8) +/* When reg cannot be unused. */ +#define FAST_IS_REG(reg) ((reg) <= REG_MASK) +/* When reg can be unused. */ +#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK) + +/* Jump flags. */ +#define JUMP_LABEL 0x1 +#define JUMP_ADDR 0x2 +/* SLJIT_REWRITABLE_JUMP is 0x1000. */ + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +# define PATCH_MB 0x4 +# define PATCH_MW 0x8 +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +# define PATCH_MD 0x10 +#endif +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +# define IS_BL 0x4 +# define PATCH_B 0x8 +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +# define CPOOL_SIZE 512 +#endif + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +# define IS_COND 0x04 +# define IS_BL 0x08 + /* conditional + imm8 */ +# define PATCH_TYPE1 0x10 + /* conditional + imm20 */ +# define PATCH_TYPE2 0x20 + /* IT + imm24 */ +# define PATCH_TYPE3 0x30 + /* imm11 */ +# define PATCH_TYPE4 0x40 + /* imm24 */ +# define PATCH_TYPE5 0x50 + /* BL + imm24 */ +# define PATCH_BL 0x60 + /* 0xf00 cc code for branches */ +#endif + +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +# define IS_COND 0x004 +# define IS_CBZ 0x008 +# define IS_BL 0x010 +# define PATCH_B 0x020 +# define PATCH_COND 0x040 +# define PATCH_ABS48 0x080 +# define PATCH_ABS64 0x100 +#endif + +#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) +# define IS_COND 0x004 +# define IS_CALL 0x008 +# define PATCH_B 0x010 +# define PATCH_ABS_B 0x020 +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +# define PATCH_ABS32 0x040 +# define PATCH_ABS48 0x080 +#endif +# define REMOVE_COND 0x100 +#endif + +#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) +# define IS_MOVABLE 0x004 +# define IS_JAL 0x008 +# define IS_CALL 0x010 +# define IS_BIT26_COND 0x020 +# define IS_BIT16_COND 0x040 + +# define IS_COND (IS_BIT26_COND | IS_BIT16_COND) + +# define PATCH_B 0x080 +# define PATCH_J 0x100 + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +# define PATCH_ABS32 0x200 +# define PATCH_ABS48 0x400 +#endif + + /* instruction types */ +# define MOVABLE_INS 0 + /* 1 - 31 last destination register */ + /* no destination (i.e: store) */ +# define UNMOVABLE_INS 32 + /* FPU status register */ +# define FCSR_FCC 33 +#endif + +#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +# define IS_JAL 0x04 +# define IS_COND 0x08 + +# define PATCH_B 0x10 +# define PATCH_J 0x20 +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +# define IS_MOVABLE 0x04 +# define IS_COND 0x08 +# define IS_CALL 0x10 + +# define PATCH_B 0x20 +# define PATCH_CALL 0x40 + + /* instruction types */ +# define MOVABLE_INS 0 + /* 1 - 31 last destination register */ + /* no destination (i.e: store) */ +# define UNMOVABLE_INS 32 + +# define DST_INS_MASK 0xff + + /* ICC_SET is the same as SET_FLAGS. */ +# define ICC_IS_SET (1 << 23) +# define FCC_IS_SET (1 << 24) +#endif + +/* Stack management. */ + +#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \ + (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \ + (saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \ + extra) * sizeof(sljit_sw)) + +#define ADJUST_LOCAL_OFFSET(p, i) \ + if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ + (i) += SLJIT_LOCALS_OFFSET; + +#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */ + +/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */ +#include "sljitUtils.c" + +#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +#include "sljitExecAllocator.c" +#endif + +/* Argument checking features. */ + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +/* Returns with error when an invalid argument is passed. */ + +#define CHECK_ARGUMENT(x) \ + do { \ + if (SLJIT_UNLIKELY(!(x))) \ + return 1; \ + } while (0) + +#define CHECK_RETURN_TYPE sljit_si +#define CHECK_RETURN_OK return 0 + +#define CHECK(x) \ + do { \ + if (SLJIT_UNLIKELY(x)) { \ + compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ + return SLJIT_ERR_BAD_ARGUMENT; \ + } \ + } while (0) + +#define CHECK_PTR(x) \ + do { \ + if (SLJIT_UNLIKELY(x)) { \ + compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ + return NULL; \ + } \ + } while (0) + +#define CHECK_REG_INDEX(x) \ + do { \ + if (SLJIT_UNLIKELY(x)) { \ + return -2; \ + } \ + } while (0) + +#elif (defined SLJIT_DEBUG && SLJIT_DEBUG) + +/* Assertion failure occures if an invalid argument is passed. */ +#undef SLJIT_ARGUMENT_CHECKS +#define SLJIT_ARGUMENT_CHECKS 1 + +#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x) +#define CHECK_RETURN_TYPE void +#define CHECK_RETURN_OK return +#define CHECK(x) x +#define CHECK_PTR(x) x +#define CHECK_REG_INDEX(x) x + +#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + +/* Arguments are not checked. */ +#define CHECK_RETURN_TYPE void +#define CHECK_RETURN_OK return +#define CHECK(x) x +#define CHECK_PTR(x) x +#define CHECK_REG_INDEX(x) x + +#else + +/* Arguments are not checked. */ +#define CHECK(x) +#define CHECK_PTR(x) +#define CHECK_REG_INDEX(x) + +#endif /* SLJIT_ARGUMENT_CHECKS */ + +/* --------------------------------------------------------------------- */ +/* Public functions */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +#define SLJIT_NEEDS_COMPILER_INIT 1 +static sljit_si compiler_initialized = 0; +/* A thread safe initialization. */ +static void init_compiler(void); +#endif + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) +{ + struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data); + if (!compiler) + return NULL; + SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); + + SLJIT_COMPILE_ASSERT( + sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1 + && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 + && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 + && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) + && sizeof(sljit_p) <= sizeof(sljit_sw) + && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) + && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), + invalid_integer_types); + SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, + int_op_and_single_op_must_be_the_same); + SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, + rewritable_jump_and_single_op_must_not_be_the_same); + + /* Only the non-zero members must be set. */ + compiler->error = SLJIT_SUCCESS; + + compiler->allocator_data = allocator_data; + compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); + compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data); + + if (!compiler->buf || !compiler->abuf) { + if (compiler->buf) + SLJIT_FREE(compiler->buf, allocator_data); + if (compiler->abuf) + SLJIT_FREE(compiler->abuf, allocator_data); + SLJIT_FREE(compiler, allocator_data); + return NULL; + } + + compiler->buf->next = NULL; + compiler->buf->used_size = 0; + compiler->abuf->next = NULL; + compiler->abuf->used_size = 0; + + compiler->scratches = -1; + compiler->saveds = -1; + compiler->fscratches = -1; + compiler->fsaveds = -1; + compiler->local_size = -1; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->args = -1; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + + CPOOL_SIZE * sizeof(sljit_ub), allocator_data); + if (!compiler->cpool) { + SLJIT_FREE(compiler->buf, allocator_data); + SLJIT_FREE(compiler->abuf, allocator_data); + SLJIT_FREE(compiler, allocator_data); + return NULL; + } + compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); + compiler->cpool_diff = 0xffffffff; +#endif + +#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) + compiler->delay_slot = UNMOVABLE_INS; +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + compiler->delay_slot = UNMOVABLE_INS; +#endif + +#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) + if (!compiler_initialized) { + init_compiler(); + compiler_initialized = 1; + } +#endif + + return compiler; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + struct sljit_memory_fragment *curr; + void *allocator_data = compiler->allocator_data; + SLJIT_UNUSED_ARG(allocator_data); + + buf = compiler->buf; + while (buf) { + curr = buf; + buf = buf->next; + SLJIT_FREE(curr, allocator_data); + } + + buf = compiler->abuf; + while (buf) { + curr = buf; + buf = buf->next; + SLJIT_FREE(curr, allocator_data); + } + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + SLJIT_FREE(compiler->cpool, allocator_data); +#endif + SLJIT_FREE(compiler, allocator_data); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) +{ + if (compiler->error == SLJIT_SUCCESS) + compiler->error = SLJIT_ERR_ALLOC_FAILED; +} + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + /* Remove thumb mode flag. */ + SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); +} +#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + /* Resolve indirection. */ + code = (void*)(*(sljit_uw*)code); + SLJIT_FREE_EXEC(code); +} +#else +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + SLJIT_FREE_EXEC(code); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) +{ + if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) { + jump->flags &= ~JUMP_ADDR; + jump->flags |= JUMP_LABEL; + jump->u.label = label; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) +{ + if (SLJIT_LIKELY(!!jump)) { + jump->flags &= ~JUMP_LABEL; + jump->flags |= JUMP_ADDR; + jump->u.target = target; + } +} + +/* --------------------------------------------------------------------- */ +/* Private functions */ +/* --------------------------------------------------------------------- */ + +static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + SLJIT_ASSERT(size <= 256); + if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + ret = compiler->buf->memory + compiler->buf->used_size; + compiler->buf->used_size += size; + return ret; + } + new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data); + PTR_FAIL_IF_NULL(new_frag); + new_frag->next = compiler->buf; + compiler->buf = new_frag; + new_frag->used_size = size; + return new_frag->memory; +} + +static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + SLJIT_ASSERT(size <= 256); + if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + ret = compiler->abuf->memory + compiler->abuf->used_size; + compiler->abuf->used_size += size; + return ret; + } + new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data); + PTR_FAIL_IF_NULL(new_frag); + new_frag->next = compiler->abuf; + compiler->abuf = new_frag; + new_frag->used_size = size; + return new_frag->memory; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +{ + CHECK_ERROR_PTR(); + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + if (size <= 0 || size > 128) + return NULL; + size = (size + 7) & ~7; +#else + if (size <= 0 || size > 64) + return NULL; + size = (size + 3) & ~3; +#endif + return ensure_abuf(compiler, size); +} + +static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf = compiler->buf; + struct sljit_memory_fragment *prev = NULL; + struct sljit_memory_fragment *tmp; + + do { + tmp = buf->next; + buf->next = prev; + prev = buf; + buf = tmp; + } while (buf != NULL); + + compiler->buf = prev; +} + +static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(local_size); + + compiler->options = options; + compiler->scratches = scratches; + compiler->saveds = saveds; + compiler->fscratches = fscratches; + compiler->fsaveds = fsaveds; +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->logical_local_size = local_size; +#endif +} + +static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(local_size); + + compiler->options = options; + compiler->scratches = scratches; + compiler->saveds = saveds; + compiler->fscratches = fscratches; + compiler->fsaveds = fsaveds; +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->logical_local_size = local_size; +#endif +} + +static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) +{ + label->next = NULL; + label->size = compiler->size; + if (compiler->last_label) + compiler->last_label->next = label; + else + compiler->labels = label; + compiler->last_label = label; +} + +static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags) +{ + jump->next = NULL; + jump->flags = flags; + if (compiler->last_jump) + compiler->last_jump->next = jump; + else + compiler->jumps = jump; + compiler->last_jump = jump; +} + +static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) +{ + const_->next = NULL; + const_->addr = compiler->size; + if (compiler->last_const) + compiler->last_const->next = const_; + else + compiler->consts = const_; + compiler->last_const = const_; +} + +#define ADDRESSING_DEPENDS_ON(exp, reg) \ + (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) +#define FUNCTION_CHECK_OP() \ + CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ + switch (GET_OPCODE(op)) { \ + case SLJIT_NOT: \ + case SLJIT_CLZ: \ + case SLJIT_AND: \ + case SLJIT_OR: \ + case SLJIT_XOR: \ + case SLJIT_SHL: \ + case SLJIT_LSHR: \ + case SLJIT_ASHR: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \ + break; \ + case SLJIT_NEG: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ + break; \ + case SLJIT_MUL: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ + break; \ + case SLJIT_ADD: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \ + break; \ + case SLJIT_SUB: \ + break; \ + case SLJIT_ADDC: \ + case SLJIT_SUBC: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \ + break; \ + case SLJIT_BREAKPOINT: \ + case SLJIT_NOP: \ + case SLJIT_LUMUL: \ + case SLJIT_LSMUL: \ + case SLJIT_MOV: \ + case SLJIT_MOV_UI: \ + case SLJIT_MOV_P: \ + case SLJIT_MOVU: \ + case SLJIT_MOVU_UI: \ + case SLJIT_MOVU_P: \ + /* Nothing allowed */ \ + CHECK_ARGUMENT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + break; \ + default: \ + /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + break; \ + } + +#define FUNCTION_CHECK_FOP() \ + CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ + switch (GET_OPCODE(op)) { \ + case SLJIT_DCMP: \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ + break; \ + default: \ + /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + break; \ + } + +#define FUNCTION_CHECK_IS_REG(r) \ + (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ + ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) + +#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \ + ((r) == SLJIT_UNUSED || \ + ((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ + ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#define CHECK_NOT_VIRTUAL_REGISTER(p) \ + CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6); +#else +#define CHECK_NOT_VIRTUAL_REGISTER(p) +#endif + +#define FUNCTION_CHECK_SRC(p, i) \ + CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ + if (FUNCTION_CHECK_IS_REG(p)) \ + CHECK_ARGUMENT((i) == 0); \ + else if ((p) == SLJIT_IMM) \ + ; \ + else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ + CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ + else { \ + CHECK_ARGUMENT((p) & SLJIT_MEM); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ + CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ + if ((p) & OFFS_REG_MASK) { \ + CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ + CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ + CHECK_ARGUMENT(!((i) & ~0x3)); \ + } \ + CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ + } + +#define FUNCTION_CHECK_DST(p, i) \ + CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ + if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \ + CHECK_ARGUMENT((i) == 0); \ + else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ + CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ + else { \ + CHECK_ARGUMENT((p) & SLJIT_MEM); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ + CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ + if ((p) & OFFS_REG_MASK) { \ + CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ + CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ + CHECK_ARGUMENT(!((i) & ~0x3)); \ + } \ + CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ + } + +#define FUNCTION_FCHECK(p, i) \ + CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \ + if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \ + ((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \ + CHECK_ARGUMENT(i == 0); \ + else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ + CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ + else { \ + CHECK_ARGUMENT((p) & SLJIT_MEM); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ + CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ + if ((p) & OFFS_REG_MASK) { \ + CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ + CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ + CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \ + } \ + CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ + } + +#define FUNCTION_CHECK_OP1() \ + if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ + CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP); \ + CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP); \ + if ((src & SLJIT_MEM) && (src & REG_MASK)) \ + CHECK_ARGUMENT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \ + } + +#endif /* SLJIT_ARGUMENT_CHECKS */ + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) +{ + compiler->verbose = verbose; +} + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#ifdef _WIN64 +# define SLJIT_PRINT_D "I64" +#else +# define SLJIT_PRINT_D "l" +#endif +#else +# define SLJIT_PRINT_D "" +#endif + +#define sljit_verbose_reg(compiler, r) \ + do { \ + if ((r) < (SLJIT_R0 + compiler->scratches)) \ + fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \ + else \ + fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \ + } while (0) + +#define sljit_verbose_param(compiler, p, i) \ + if ((p) & SLJIT_IMM) \ + fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ + else if ((p) & SLJIT_MEM) { \ + if ((p) & REG_MASK) { \ + fputc('[', compiler->verbose); \ + sljit_verbose_reg(compiler, (p) & REG_MASK); \ + if ((p) & OFFS_REG_MASK) { \ + fprintf(compiler->verbose, " + "); \ + sljit_verbose_reg(compiler, OFFS_REG(p)); \ + if (i) \ + fprintf(compiler->verbose, " * %d", 1 << (i)); \ + } \ + else if (i) \ + fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \ + fputc(']', compiler->verbose); \ + } \ + else \ + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ + } else if (p) \ + sljit_verbose_reg(compiler, p); \ + else \ + fprintf(compiler->verbose, "unused"); + +#define sljit_verbose_fparam(compiler, p, i) \ + if ((p) & SLJIT_MEM) { \ + if ((p) & REG_MASK) { \ + fputc('[', compiler->verbose); \ + sljit_verbose_reg(compiler, (p) & REG_MASK); \ + if ((p) & OFFS_REG_MASK) { \ + fprintf(compiler->verbose, " + "); \ + sljit_verbose_reg(compiler, OFFS_REG(p)); \ + if (i) \ + fprintf(compiler->verbose, "%d", 1 << (i)); \ + } \ + else if (i) \ + fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \ + fputc(']', compiler->verbose); \ + } \ + else \ + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ + } \ + else { \ + if ((p) < (SLJIT_FR0 + compiler->fscratches)) \ + fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \ + else \ + fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \ + } + +static SLJIT_CONST char* op0_names[] = { + (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul", + (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi" +}; + +static SLJIT_CONST char* op1_names[] = { + (char*)"mov", (char*)"mov_ub", (char*)"mov_sb", (char*)"mov_uh", + (char*)"mov_sh", (char*)"mov_ui", (char*)"mov_si", (char*)"mov_p", + (char*)"movu", (char*)"movu_ub", (char*)"movu_sb", (char*)"movu_uh", + (char*)"movu_sh", (char*)"movu_ui", (char*)"movu_si", (char*)"movu_p", + (char*)"not", (char*)"neg", (char*)"clz", +}; + +static SLJIT_CONST char* op2_names[] = { + (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", + (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", + (char*)"shl", (char*)"lshr", (char*)"ashr", +}; + +static SLJIT_CONST char* fop1_names[] = { + (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", + (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", + (char*)"abs", +}; + +static SLJIT_CONST char* fop2_names[] = { + (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" +}; + +#define JUMP_PREFIX(type) \ + ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_INT_OP) ? "i_" : "") \ + : ((type & 0xff) <= SLJIT_D_ORDERED ? ((type & SLJIT_SINGLE_OP) ? "s_" : "d_") : "")) + +static char* jump_names[] = { + (char*)"equal", (char*)"not_equal", + (char*)"less", (char*)"greater_equal", + (char*)"greater", (char*)"less_equal", + (char*)"sig_less", (char*)"sig_greater_equal", + (char*)"sig_greater", (char*)"sig_less_equal", + (char*)"overflow", (char*)"not_overflow", + (char*)"mul_overflow", (char*)"mul_not_overflow", + (char*)"equal", (char*)"not_equal", + (char*)"less", (char*)"greater_equal", + (char*)"greater", (char*)"less_equal", + (char*)"unordered", (char*)"ordered", + (char*)"jump", (char*)"fast_call", + (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" +}; + +#endif /* SLJIT_VERBOSE */ + +/* --------------------------------------------------------------------- */ +/* Arch dependent */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + struct sljit_jump *jump; +#endif + + SLJIT_UNUSED_ARG(compiler); + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(compiler->size > 0); + jump = compiler->jumps; + while (jump) { + /* All jumps have target. */ + CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR)); + jump = jump->next; + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(compiler); + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); + CHECK_ARGUMENT(args >= 0 && args <= 3); + CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(args <= saveds); + CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", + args, scratches, saveds, fscratches, fsaveds, local_size); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); + CHECK_ARGUMENT(args >= 0 && args <= 3); + CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(args <= saveds); + CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", + args, scratches, saveds, fscratches, fsaveds, local_size); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(compiler->scratches >= 0); + if (op != SLJIT_UNUSED) { + CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P); + FUNCTION_CHECK_SRC(src, srcw); + } + else + CHECK_ARGUMENT(src == 0 && srcw == 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (op == SLJIT_UNUSED) + fprintf(compiler->verbose, " return\n"); + else { + fprintf(compiler->verbose, " return.%s ", op1_names[op - SLJIT_OP1_BASE]); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fast_enter "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fast_return "); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL) + || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI)); + CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ); + FUNCTION_CHECK_OP(); + FUNCTION_CHECK_SRC(src, srcw); + FUNCTION_CHECK_DST(dst, dstw); + FUNCTION_CHECK_OP1(); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR); + FUNCTION_CHECK_OP(); + FUNCTION_CHECK_SRC(src1, src1w); + FUNCTION_CHECK_SRC(src2, src2w); + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si reg) +{ + SLJIT_UNUSED_ARG(reg); +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_si reg) +{ + SLJIT_UNUSED_ARG(reg); +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + int i; +#endif + + SLJIT_UNUSED_ARG(compiler); + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(instruction); +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + CHECK_ARGUMENT(size > 0 && size < 16); +#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0) + || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); +#else + CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); +#endif + +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " op_custom"); + for (i = 0; i < size; i++) + fprintf(compiler->verbose, " 0x%x", ((sljit_ub*)instruction)[i]); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DMOV && GET_OPCODE(op) <= SLJIT_DABS); + FUNCTION_CHECK_FOP(); + FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) + fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONVD_FROMS - SLJIT_FOP1_BASE], + (op & SLJIT_SINGLE_OP) ? "s.fromd" : "d.froms"); + else + fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", + fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE]); + + sljit_verbose_fparam(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_DCMP); + FUNCTION_CHECK_FOP(); + FUNCTION_FCHECK(src1, src1w); + FUNCTION_FCHECK(src2, src2w); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop1_names[SLJIT_DCMP - SLJIT_FOP1_BASE], + (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : ""); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_CONVI_FROMD); + FUNCTION_CHECK_FOP(); + FUNCTION_FCHECK(src, srcw); + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + (GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? "i" : "w", + (op & SLJIT_SINGLE_OP) ? "s" : "d"); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVD_FROMW && GET_OPCODE(op) <= SLJIT_CONVD_FROMI); + FUNCTION_CHECK_FOP(); + FUNCTION_CHECK_SRC(src, srcw); + FUNCTION_FCHECK(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + (op & SLJIT_SINGLE_OP) ? "s" : "d", + (GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? "i" : "w"); + sljit_verbose_fparam(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DADD && GET_OPCODE(op) <= SLJIT_DDIV); + FUNCTION_CHECK_FOP(); + FUNCTION_FCHECK(src1, src1w); + FUNCTION_FCHECK(src2, src2w); + FUNCTION_FCHECK(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE]); + sljit_verbose_fparam(compiler, dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, "label:\n"); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3); + CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_INT_OP)); + CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " jump%s.%s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + JUMP_PREFIX(type), jump_names[type & 0xff]); +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL); + FUNCTION_CHECK_SRC(src1, src1w); + FUNCTION_CHECK_SRC(src2, src2w); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " cmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + (type & SLJIT_INT_OP) ? "i_" : "", jump_names[type & 0xff]); + sljit_verbose_param(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_is_fpu_available()); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_D_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + FUNCTION_FCHECK(src1, src1w); + FUNCTION_FCHECK(src2, src2w); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fcmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + (type & SLJIT_SINGLE_OP) ? "s_" : "d_", jump_names[type & 0xff]); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); + CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches); + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI + || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); + CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); + CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); + if (GET_OPCODE(op) < SLJIT_ADD) { + CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0); + } else { + CHECK_ARGUMENT(src == dst && srcw == dstw); + } + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " flags.%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", + GET_OPCODE(op) >= SLJIT_OP2_BASE ? op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE] : op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + sljit_verbose_param(compiler, dst, dstw); + if (src != SLJIT_UNUSED) { + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src, srcw); + } + fprintf(compiler->verbose, ", %s%s\n", JUMP_PREFIX(type), jump_names[type & 0xff]); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +{ + SLJIT_UNUSED_ARG(offset); + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " local_base "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + SLJIT_UNUSED_ARG(init_value); + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " const "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); + } +#endif + CHECK_RETURN_OK; +} + +#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ + +#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ + SLJIT_COMPILE_ASSERT(!(SLJIT_CONVW_FROMD & 0x1) && !(SLJIT_CONVD_FROMW & 0x1), \ + invalid_float_opcodes); \ + if (GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_DCMP) { \ + if (GET_OPCODE(op) == SLJIT_DCMP) { \ + CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); \ + return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \ + } \ + if ((GET_OPCODE(op) | 0x1) == SLJIT_CONVI_FROMD) { \ + CHECK(check_sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); \ + return sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \ + } \ + CHECK(check_sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); \ + return sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \ + } \ + CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); + +static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + /* Return if don't need to do anything. */ + if (op == SLJIT_UNUSED) + return SLJIT_SUCCESS; + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) + return SLJIT_SUCCESS; +#else + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) + return SLJIT_SUCCESS; +#endif + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + compiler->skip_checks = 1; +#endif + return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); +} + +/* CPU description section */ + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) +#define SLJIT_CPUINFO_PART1 " 32bit (" +#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#define SLJIT_CPUINFO_PART1 " 64bit (" +#else +#error "Internal error: CPU type info missing" +#endif + +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define SLJIT_CPUINFO_PART2 "little endian + " +#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) +#define SLJIT_CPUINFO_PART2 "big endian + " +#else +#error "Internal error: CPU type info missing" +#endif + +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) +#define SLJIT_CPUINFO_PART3 "unaligned)" +#else +#define SLJIT_CPUINFO_PART3 "aligned)" +#endif + +#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +# include "sljitNativeX86_common.c" +#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +# include "sljitNativeARM_32.c" +#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +# include "sljitNativeARM_32.c" +#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +# include "sljitNativeARM_T2_32.c" +#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +# include "sljitNativeARM_64.c" +#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) +# include "sljitNativePPC_common.c" +#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) +# include "sljitNativeMIPS_common.c" +#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) +# include "sljitNativeSPARC_common.c" +#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +# include "sljitNativeTILEGX_64.c" +#endif + +#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* Default compare for most architectures. */ + sljit_si flags, tmp_src, condition; + sljit_sw tmp_srcw; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); + + condition = type & 0xff; +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) + if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) { + if ((src1 & SLJIT_IMM) && !src1w) { + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + src2w = 0; + } + if ((src2 & SLJIT_IMM) && !src2w) + return emit_cmp_to0(compiler, type, src1, src1w); + } +#endif + + if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { + /* Immediate is prefered as second argument by most architectures. */ + switch (condition) { + case SLJIT_LESS: + condition = SLJIT_GREATER; + break; + case SLJIT_GREATER_EQUAL: + condition = SLJIT_LESS_EQUAL; + break; + case SLJIT_GREATER: + condition = SLJIT_LESS; + break; + case SLJIT_LESS_EQUAL: + condition = SLJIT_GREATER_EQUAL; + break; + case SLJIT_SIG_LESS: + condition = SLJIT_SIG_GREATER; + break; + case SLJIT_SIG_GREATER_EQUAL: + condition = SLJIT_SIG_LESS_EQUAL; + break; + case SLJIT_SIG_GREATER: + condition = SLJIT_SIG_LESS; + break; + case SLJIT_SIG_LESS_EQUAL: + condition = SLJIT_SIG_GREATER_EQUAL; + break; + } + type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); + tmp_src = src1; + src1 = src2; + src2 = tmp_src; + tmp_srcw = src1w; + src1w = src2w; + src2w = tmp_srcw; + } + + if (condition <= SLJIT_NOT_ZERO) + flags = SLJIT_SET_E; + else if (condition <= SLJIT_LESS_EQUAL) + flags = SLJIT_SET_U; + else + flags = SLJIT_SET_S; + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), + SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si flags, condition; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); + + condition = type & 0xff; + flags = (condition <= SLJIT_D_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; + if (type & SLJIT_SINGLE_OP) + flags |= SLJIT_SINGLE_OP; + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + sljit_emit_fop1(compiler, SLJIT_DCMP | flags, src1, src1w, src2, src2w); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); +} + +#endif + +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +{ + CHECK_ERROR(); + CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); + + ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + if (offset != 0) + return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset); + return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0); +} + +#endif + +#else /* SLJIT_CONFIG_UNSUPPORTED */ + +/* Empty function bodies for those machines, which are not (yet) supported. */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "unsupported"; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) +{ + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT_STOP(); + return NULL; +} + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(verbose); + SLJIT_ASSERT_STOP(); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + SLJIT_UNUSED_ARG(code); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(options); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(fscratches); + SLJIT_UNUSED_ARG(fsaveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(options); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(fscratches); + SLJIT_UNUSED_ARG(fsaveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + SLJIT_ASSERT_STOP(); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(instruction); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + SLJIT_ASSERT_STOP(); + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) +{ + SLJIT_UNUSED_ARG(jump); + SLJIT_UNUSED_ARG(label); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) +{ + SLJIT_UNUSED_ARG(jump); + SLJIT_UNUSED_ARG(target); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_UNUSED_ARG(type); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(offset); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(initval); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + SLJIT_UNUSED_ARG(addr); + SLJIT_UNUSED_ARG(new_addr); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + SLJIT_UNUSED_ARG(addr); + SLJIT_UNUSED_ARG(new_constant); + SLJIT_ASSERT_STOP(); +} + +#endif diff --git a/pcre2/src/sljit/sljitLir.h b/pcre2/src/sljit/sljitLir.h new file mode 100644 index 000000000..2e2e9ac09 --- /dev/null +++ b/pcre2/src/sljit/sljitLir.h @@ -0,0 +1,1249 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SLJIT_LIR_H_ +#define _SLJIT_LIR_H_ + +/* + ------------------------------------------------------------------------ + Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC) + ------------------------------------------------------------------------ + + Short description + Advantages: + - The execution can be continued from any LIR instruction. In other + words, it is possible to jump to any label from anywhere, even from + a code fragment, which is compiled later, if both compiled code + shares the same context. See sljit_emit_enter for more details + - Supports self modifying code: target of (conditional) jump and call + instructions and some constant values can be dynamically modified + during runtime + - although it is not suggested to do it frequently + - can be used for inline caching: save an important value once + in the instruction stream + - since this feature limits the optimization possibilities, a + special flag must be passed at compile time when these + instructions are emitted + - A fixed stack space can be allocated for local variables + - The compiler is thread-safe + - The compiler is highly configurable through preprocessor macros. + You can disable unneeded features (multithreading in single + threaded applications), and you can use your own system functions + (including memory allocators). See sljitConfig.h + Disadvantages: + - No automatic register allocation, and temporary results are + not stored on the stack. (hence the name comes) + In practice: + - This approach is very effective for interpreters + - One of the saved registers typically points to a stack interface + - It can jump to any exception handler anytime (even if it belongs + to another function) + - Hot paths can be modified during runtime reflecting the changes + of the fastest execution path of the dynamic language + - SLJIT supports complex memory addressing modes + - mainly position and context independent code (except some cases) + + For valgrind users: + - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" +*/ + +#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG) +#include "sljitConfig.h" +#endif + +/* The following header file defines useful macros for fine tuning +sljit based code generators. They are listed in the beginning +of sljitConfigInternal.h */ + +#include "sljitConfigInternal.h" + +/* --------------------------------------------------------------------- */ +/* Error codes */ +/* --------------------------------------------------------------------- */ + +/* Indicates no error. */ +#define SLJIT_SUCCESS 0 +/* After the call of sljit_generate_code(), the error code of the compiler + is set to this value to avoid future sljit calls (in debug mode at least). + The complier should be freed after sljit_generate_code(). */ +#define SLJIT_ERR_COMPILED 1 +/* Cannot allocate non executable memory. */ +#define SLJIT_ERR_ALLOC_FAILED 2 +/* Cannot allocate executable memory. + Only for sljit_generate_code() */ +#define SLJIT_ERR_EX_ALLOC_FAILED 3 +/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */ +#define SLJIT_ERR_UNSUPPORTED 4 +/* An ivalid argument is passed to any SLJIT function. */ +#define SLJIT_ERR_BAD_ARGUMENT 5 + +/* --------------------------------------------------------------------- */ +/* Registers */ +/* --------------------------------------------------------------------- */ + +/* + Scratch (R) registers: registers whose may not preserve their values + across function calls. + + Saved (S) registers: registers whose preserve their values across + function calls. + + The scratch and saved register sets are overlap. The last scratch register + is the first saved register, the one before the last is the second saved + register, and so on. + + If an architecture provides two scratch and three saved registers, + its scratch and saved register sets are the following: + + R0 | [S4] | R0 and S4 represent the same physical register + R1 | [S3] | R1 and S3 represent the same physical register + [R2] | S2 | R2 and S2 represent the same physical register + [R3] | S1 | R3 and S1 represent the same physical register + [R4] | S0 | R4 and S0 represent the same physical register + + Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and + SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture. + + Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10 + and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers + are virtual on x86-32. See below. + + The purpose of this definition is convenience. Although a register + is either scratch register or saved register, SLJIT allows accessing + them from the other set. For example, four registers can be used as + scratch registers and the fifth one as saved register on the architecture + above. Of course the last two scratch registers (R2 and R3) from this + four will be saved on the stack, because they are defined as saved + registers in the application binary interface. Still R2 and R3 can be + used for referencing to these registers instead of S2 and S1, which + makes easier to write platform independent code. Scratch registers + can be saved registers in a similar way, but these extra saved + registers will not be preserved across function calls! Hence the + application must save them on those platforms, where the number of + saved registers is too low. This can be done by copy them onto + the stack and restore them after a function call. + + Note: To emphasize that registers assigned to R2-R4 are saved + registers, they are enclosed by square brackets. S3-S4 + are marked in a similar way. + + Note: sljit_emit_enter and sljit_set_context defines whether a register + is S or R register. E.g: when 3 scratches and 1 saved is mapped + by sljit_emit_enter, the allowed register set will be: R0-R2 and + S0. Although S2 is mapped to the same position as R2, it does not + available in the current configuration. Furthermore the R3 (S1) + register does not available as well. +*/ + +/* When SLJIT_UNUSED is specified as destination, the result is discarded. */ +#define SLJIT_UNUSED 0 + +/* Scratch registers. */ +#define SLJIT_R0 1 +#define SLJIT_R1 2 +#define SLJIT_R2 3 +/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they + are allocated on the stack). These registers are called virtual + and cannot be used for memory addressing (cannot be part of + any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such + limitation on other CPUs. See sljit_get_register_index(). */ +#define SLJIT_R3 4 +#define SLJIT_R4 5 +#define SLJIT_R5 6 +#define SLJIT_R6 7 +#define SLJIT_R7 8 +#define SLJIT_R8 9 +#define SLJIT_R9 10 +/* All R registers provided by the architecture can be accessed by SLJIT_R(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */ +#define SLJIT_R(i) (1 + (i)) + +/* Saved registers. */ +#define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS) +#define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1) +#define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2) +/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they + are allocated on the stack). These registers are called virtual + and cannot be used for memory addressing (cannot be part of + any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such + limitation on other CPUs. See sljit_get_register_index(). */ +#define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3) +#define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4) +#define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5) +#define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6) +#define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7) +#define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8) +#define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9) +/* All S registers provided by the architecture can be accessed by SLJIT_S(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */ +#define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i)) + +/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */ +#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1) + +/* The SLJIT_SP provides direct access to the linear stack space allocated by + sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP). + The immediate offset is extended by the relative stack offset automatically. + The sljit_get_local_base can be used to obtain the absolute offset. */ +#define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1) + +/* Return with machine word. */ + +#define SLJIT_RETURN_REG SLJIT_R0 + +/* x86 prefers specific registers for special purposes. In case of shift + by register it supports only SLJIT_R2 for shift argument + (which is the src2 argument of sljit_emit_op2). If another register is + used, sljit must exchange data between registers which cause a minor + slowdown. Other architectures has no such limitation. */ + +#define SLJIT_PREF_SHIFT_REG SLJIT_R2 + +/* --------------------------------------------------------------------- */ +/* Floating point registers */ +/* --------------------------------------------------------------------- */ + +/* Each floating point register can store a double or single precision + value. The FR and FS register sets are overlap in the same way as R + and S register sets. See above. */ + +/* Note: SLJIT_UNUSED as destination is not valid for floating point + operations, since they cannot be used for setting flags. */ + +/* Floating point scratch registers. */ +#define SLJIT_FR0 1 +#define SLJIT_FR1 2 +#define SLJIT_FR2 3 +#define SLJIT_FR3 4 +#define SLJIT_FR4 5 +#define SLJIT_FR5 6 +/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */ +#define SLJIT_FR(i) (1 + (i)) + +/* Floating point saved registers. */ +#define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS) +#define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1) +#define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2) +#define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3) +#define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4) +#define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5) +/* All S registers provided by the architecture can be accessed by SLJIT_FS(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ +#define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) + +/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */ +#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1) + +/* --------------------------------------------------------------------- */ +/* Main structures and functions */ +/* --------------------------------------------------------------------- */ + +/* + The following structures are private, and can be changed in the + future. Keeping them here allows code inlining. +*/ + +struct sljit_memory_fragment { + struct sljit_memory_fragment *next; + sljit_uw used_size; + /* Must be aligned to sljit_sw. */ + sljit_ub memory[1]; +}; + +struct sljit_label { + struct sljit_label *next; + sljit_uw addr; + /* The maximum size difference. */ + sljit_uw size; +}; + +struct sljit_jump { + struct sljit_jump *next; + sljit_uw addr; + sljit_sw flags; + union { + sljit_uw target; + struct sljit_label* label; + } u; +}; + +struct sljit_const { + struct sljit_const *next; + sljit_uw addr; +}; + +struct sljit_compiler { + sljit_si error; + sljit_si options; + + struct sljit_label *labels; + struct sljit_jump *jumps; + struct sljit_const *consts; + struct sljit_label *last_label; + struct sljit_jump *last_jump; + struct sljit_const *last_const; + + void *allocator_data; + struct sljit_memory_fragment *buf; + struct sljit_memory_fragment *abuf; + + /* Used scratch registers. */ + sljit_si scratches; + /* Used saved registers. */ + sljit_si saveds; + /* Used float scratch registers. */ + sljit_si fscratches; + /* Used float saved registers. */ + sljit_si fsaveds; + /* Local stack size. */ + sljit_si local_size; + /* Code size. */ + sljit_uw size; + /* For statistical purposes. */ + sljit_uw executable_size; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si args; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si mode32; +#endif + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + sljit_si flags_saved; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + /* Constant pool handling. */ + sljit_uw *cpool; + sljit_ub *cpool_unique; + sljit_uw cpool_diff; + sljit_uw cpool_fill; + /* Other members. */ + /* Contains pointer, "ldr pc, [...]" pairs. */ + sljit_uw patches; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + /* Temporary fields. */ + sljit_uw shift_imm; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) + sljit_sw imm; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) + sljit_si delay_slot; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + sljit_si delay_slot; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + FILE* verbose; +#endif + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG) + /* Local size passed to the functions. */ + sljit_si logical_local_size; +#endif + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + sljit_si skip_checks; +#endif +}; + +/* --------------------------------------------------------------------- */ +/* Main functions */ +/* --------------------------------------------------------------------- */ + +/* Creates an sljit compiler. The allocator_data is required by some + custom memory managers. This pointer is passed to SLJIT_MALLOC + and SLJIT_FREE macros. Most allocators (including the default + one) ignores this value, and it is recommended to pass NULL + as a dummy value for allocator_data. + + Returns NULL if failed. */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data); + +/* Frees everything except the compiled machine code. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); + +/* Returns the current error code. If an error is occurred, future sljit + calls which uses the same compiler argument returns early with the same + error code. Thus there is no need for checking the error after every + call, it is enough to do it before the code is compiled. Removing + these checks increases the performance of the compiling process. */ +static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } + +/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except + if an error was detected before. After the error code is set + the compiler behaves as if the allocation failure happened + during an sljit function call. This can greatly simplify error + checking, since only the compiler status needs to be checked + after the compilation. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler); + +/* + Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, + and <= 128 bytes on 64 bit architectures. The memory area is owned by the + compiler, and freed by sljit_free_compiler. The returned pointer is + sizeof(sljit_sw) aligned. Excellent for allocating small blocks during + the compiling, and no need to worry about freeing them. The size is + enough to contain at most 16 pointers. If the size is outside of the range, + the function will return with NULL. However, this return value does not + indicate that there is no more memory (does not set the current error code + of the compiler to out-of-memory status). +*/ +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +/* Passing NULL disables verbose. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); + +/* + After the machine code generation is finished we can retrieve the allocated + executable memory size, although this area may not be fully filled with + instructions depending on some optimizations. This function is useful only + for statistical purposes. + + Before a successful code generation, this function returns with 0. +*/ +static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } + +/* Instruction generation. Returns with any error code. If there is no + error, they return with SLJIT_SUCCESS. */ + +/* + The executable code is a function call from the viewpoint of the C + language. The function calls must obey to the ABI (Application + Binary Interface) of the platform, which specify the purpose of + all machine registers and stack handling among other things. The + sljit_emit_enter function emits the necessary instructions for + setting up a new context for the executable code and moves function + arguments to the saved registers. Furthermore the options argument + can be used to pass configuration options to the compiler. The + available options are listed before sljit_emit_enter. + + The number of sljit_sw arguments passed to the generated function + are specified in the "args" parameter. The number of arguments must + be less than or equal to 3. The first argument goes to SLJIT_S0, + the second goes to SLJIT_S1 and so on. The register set used by + the function must be declared as well. The number of scratch and + saved registers used by the function must be passed to sljit_emit_enter. + Only R registers between R0 and "scratches" argument can be used + later. E.g. if "scratches" is set to 2, the register set will be + limited to R0 and R1. The S registers and the floating point + registers ("fscratches" and "fsaveds") are specified in a similar + way. The sljit_emit_enter is also capable of allocating a stack + space for local variables. The "local_size" argument contains the + size in bytes of this local area and its staring address is stored + in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and + SLJIT_SP + local_size (exclusive) can be modified freely until + the function returns. The stack space is not initialized. + + Note: the following conditions must met: + 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS + 0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS + scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS + 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + 0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + + Note: every call of sljit_emit_enter and sljit_set_context + overwrites the previous context. +*/ + +/* The absolute address returned by sljit_get_local_base with +offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */ +#define SLJIT_DOUBLE_ALIGNMENT 0x00000001 + +/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ +#define SLJIT_MAX_LOCAL_SIZE 65536 + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); + +/* The machine code has a context (which contains the local stack space size, + number of used registers, etc.) which initialized by sljit_emit_enter. Several + functions (like sljit_emit_return) requres this context to be able to generate + the appropriate code. However, some code fragments (like inline cache) may have + no normal entry point so their context is unknown for the compiler. Their context + can be provided to the compiler by the sljit_set_context function. + + Note: every call of sljit_emit_enter and sljit_set_context overwrites + the previous context. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); + +/* Return from machine code. The op argument can be SLJIT_UNUSED which means the + function does not return with anything or any opcode between SLJIT_MOV and + SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op + is SLJIT_UNUSED, otherwise see below the description about source and + destination arguments. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, + sljit_si src, sljit_sw srcw); + +/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and + even the stack frame is passed to the callee. The return address is preserved in + dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function + is sljit_p), and sljit_emit_fast_return can use this as a return value later. */ + +/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine + instructions are needed. Excellent for small uility functions, where saving registers + and setting up a new stack frame would cost too much performance. However, it is still + possible to return to the address of the caller (or anywhere else). */ + +/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */ + +/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, + since many architectures do clever branch prediction on call / return instruction pairs. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw); + +/* + Source and destination values for arithmetical instructions + imm - a simple immediate value (cannot be used as a destination) + reg - any of the registers (immediate argument must be 0) + [imm] - absolute immediate memory address + [reg+imm] - indirect memory address + [reg+(reg<addr; } +static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } +static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; } + +/* Only the address is required to rewrite the code. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant); + +/* --------------------------------------------------------------------- */ +/* Miscellaneous utility functions */ +/* --------------------------------------------------------------------- */ + +#define SLJIT_MAJOR_VERSION 0 +#define SLJIT_MINOR_VERSION 93 + +/* Get the human readable name of the platform. Can be useful on platforms + like ARM, where ARM and Thumb2 functions can be mixed, and + it is useful to know the type of the code generator. */ +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); + +/* Portable helper function to get an offset of a member. */ +#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) +/* This global lock is useful to compile common functions. */ +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void); +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void); +#endif + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) + +/* The sljit_stack is a utiliy feature of sljit, which allocates a + writable memory region between base (inclusive) and limit (exclusive). + Both base and limit is a pointer, and base is always <= than limit. + This feature uses the "address space reserve" feature + of modern operating systems. Basically we don't need to allocate a + huge memory block in one step for the worst case, we can start with + a smaller chunk and extend it later. Since the address space is + reserved, the data never copied to other regions, thus it is safe + to store pointers here. */ + +/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more). + Note: stack growing should not happen in small steps: 4k, 16k or even + bigger growth is better. + Note: this structure may not be supported by all operating systems. + Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK + is not defined. */ + +struct sljit_stack { + /* User data, anything can be stored here. + Starting with the same value as base. */ + sljit_uw top; + /* These members are read only. */ + sljit_uw base; + sljit_uw limit; + sljit_uw max_limit; +}; + +/* Returns NULL if unsuccessful. + Note: limit and max_limit contains the size for stack allocation. + Note: the top field is initialized to base. + Note: see sljit_create_compiler for the explanation of allocator_data. */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data); +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data); + +/* Can be used to increase (allocate) or decrease (free) the memory area. + Returns with a non-zero value if unsuccessful. If new_limit is greater than + max_limit, it will fail. It is very easy to implement a stack data structure, + since the growth ratio can be added to the current limit, and sljit_stack_resize + will do all the necessary checks. The fields of the stack are not changed if + sljit_stack_resize fails. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_uw new_limit); + +#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */ + +#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + +/* Get the entry address of a given function. */ +#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name) + +#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ + +/* All JIT related code should be placed in the same context (library, binary, etc.). */ + +#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name) + +/* For powerpc64, the function pointers point to a context descriptor. */ +struct sljit_function_context { + sljit_sw addr; + sljit_sw r2; + sljit_sw r11; +}; + +/* Fill the context arguments using the addr and the function. + If func_ptr is NULL, it will not be set to the address of context + If addr is NULL, the function address also comes from the func pointer. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func); + +#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ + +/* --------------------------------------------------------------------- */ +/* CPU specific functions */ +/* --------------------------------------------------------------------- */ + +/* The following function is a helper function for sljit_emit_op_custom. + It returns with the real machine register index ( >=0 ) of any SLJIT_R, + SLJIT_S and SLJIT_SP registers. + + Note: it returns with -1 for virtual registers (only on x86-32). */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); + +/* The following function is a helper function for sljit_emit_op_custom. + It returns with the real machine register index of any SLJIT_FLOAT register. + + Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); + +/* Any instruction can be inserted into the instruction stream by + sljit_emit_op_custom. It has a similar purpose as inline assembly. + The size parameter must match to the instruction size of the target + architecture: + + x86: 0 < size <= 15. The instruction argument can be byte aligned. + Thumb2: if size == 2, the instruction argument must be 2 byte aligned. + if size == 4, the instruction argument must be 4 byte aligned. + Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size); + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* Returns with non-zero if sse2 is available. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void); + +/* Returns with non-zero if cmov instruction is available. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); + +/* Emit a conditional mov instruction on x86 CPUs. This instruction + moves src to destination, if the condition is satisfied. Unlike + other arithmetic instructions, destination must be a register. + Before such instructions are emitted, cmov support should be + checked by sljit_x86_is_cmov_available function. + type must be between SLJIT_EQUAL and SLJIT_S_ORDERED + dst_reg must be a valid register and it can be combined + with SLJIT_INT_OP to perform 32 bit arithmetic + Flags: I - (never set any flags) + */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_si type, + sljit_si dst_reg, + sljit_si src, sljit_sw srcw); + +#endif + +#endif /* _SLJIT_LIR_H_ */ diff --git a/pcre2/src/sljit/sljitNativeARM_32.c b/pcre2/src/sljit/sljitNativeARM_32.c new file mode 100644 index 000000000..5cd4c71a2 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeARM_32.c @@ -0,0 +1,2566 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + return "ARMv7" SLJIT_CPUINFO; +#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + return "ARMv5" SLJIT_CPUINFO; +#else +#error "Internal error: Unknown ARM architecture" +#endif +} + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5) + +#define TMP_FREG1 (0) +#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +/* In ARM instruction words. + Cache lines are usually 32 byte aligned. */ +#define CONST_POOL_ALIGNMENT 8 +#define CONST_POOL_EMPTY 0xffffffff + +#define ALIGN_INSTRUCTION(ptr) \ + (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) +#define MAX_DIFFERENCE(max_diff) \ + (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + +/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { + 0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15 +}; + +#define RM(rm) (reg_map[rm]) +#define RD(rd) (reg_map[rd] << 12) +#define RN(rn) (reg_map[rn] << 16) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +/* The instruction includes the AL condition. + INST_NAME - CONDITIONAL remove this flag. */ +#define COND_MASK 0xf0000000 +#define CONDITIONAL 0xe0000000 +#define PUSH_POOL 0xff000000 + +/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */ +#define ADC_DP 0x5 +#define ADD_DP 0x4 +#define AND_DP 0x0 +#define B 0xea000000 +#define BIC_DP 0xe +#define BL 0xeb000000 +#define BLX 0xe12fff30 +#define BX 0xe12fff10 +#define CLZ 0xe16f0f10 +#define CMP_DP 0xa +#define BKPT 0xe1200070 +#define EOR_DP 0x1 +#define MOV_DP 0xd +#define MUL 0xe0000090 +#define MVN_DP 0xf +#define NOP 0xe1a00000 +#define ORR_DP 0xc +#define PUSH 0xe92d0000 +#define POP 0xe8bd0000 +#define RSB_DP 0x3 +#define RSC_DP 0x7 +#define SBC_DP 0x6 +#define SMULL 0xe0c00090 +#define SUB_DP 0x2 +#define UMULL 0xe0800090 +#define VABS_F32 0xeeb00ac0 +#define VADD_F32 0xee300a00 +#define VCMP_F32 0xeeb40a40 +#define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F64_F32 0xeeb70ac0 +#define VCVT_S32_F32 0xeebd0ac0 +#define VDIV_F32 0xee800a00 +#define VMOV_F32 0xeeb00a40 +#define VMOV 0xee000a10 +#define VMRS 0xeef1fa10 +#define VMUL_F32 0xee200a00 +#define VNEG_F32 0xeeb10a40 +#define VSTR_F32 0xed000a00 +#define VSUB_F32 0xee300a40 + +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +/* Arm v7 specific instructions. */ +#define MOVW 0xe3000000 +#define MOVT 0xe3400000 +#define SXTB 0xe6af0070 +#define SXTH 0xe6bf0070 +#define UXTB 0xe6ef0070 +#define UXTH 0xe6ff0070 +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + +static sljit_si push_cpool(struct sljit_compiler *compiler) +{ + /* Pushing the constant pool into the instruction stream. */ + sljit_uw* inst; + sljit_uw* cpool_ptr; + sljit_uw* cpool_end; + sljit_si i; + + /* The label could point the address after the constant pool. */ + if (compiler->last_label && compiler->last_label->size == compiler->size) + compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; + + SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = 0xff000000 | compiler->cpool_fill; + + for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = 0; + } + + cpool_ptr = compiler->cpool; + cpool_end = cpool_ptr + compiler->cpool_fill; + while (cpool_ptr < cpool_end) { + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = *cpool_ptr++; + } + compiler->cpool_diff = CONST_POOL_EMPTY; + compiler->cpool_fill = 0; + return SLJIT_SUCCESS; +} + +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +{ + sljit_uw* ptr; + + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) + FAIL_IF(push_cpool(compiler)); + + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst; + return SLJIT_SUCCESS; +} + +static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +{ + sljit_uw* ptr; + sljit_uw cpool_index = CPOOL_SIZE; + sljit_uw* cpool_ptr; + sljit_uw* cpool_end; + sljit_ub* cpool_unique_ptr; + + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) + FAIL_IF(push_cpool(compiler)); + else if (compiler->cpool_fill > 0) { + cpool_ptr = compiler->cpool; + cpool_end = cpool_ptr + compiler->cpool_fill; + cpool_unique_ptr = compiler->cpool_unique; + do { + if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) { + cpool_index = cpool_ptr - compiler->cpool; + break; + } + cpool_ptr++; + cpool_unique_ptr++; + } while (cpool_ptr < cpool_end); + } + + if (cpool_index == CPOOL_SIZE) { + /* Must allocate a new entry in the literal pool. */ + if (compiler->cpool_fill < CPOOL_SIZE) { + cpool_index = compiler->cpool_fill; + compiler->cpool_fill++; + } + else { + FAIL_IF(push_cpool(compiler)); + cpool_index = 0; + compiler->cpool_fill = 1; + } + } + + SLJIT_ASSERT((inst & 0xfff) == 0); + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst | cpool_index; + + compiler->cpool[cpool_index] = literal; + compiler->cpool_unique[cpool_index] = 0; + if (compiler->cpool_diff == CONST_POOL_EMPTY) + compiler->cpool_diff = compiler->size; + return SLJIT_SUCCESS; +} + +static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +{ + sljit_uw* ptr; + if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) + FAIL_IF(push_cpool(compiler)); + + SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst | compiler->cpool_fill; + + compiler->cpool[compiler->cpool_fill] = literal; + compiler->cpool_unique[compiler->cpool_fill] = 1; + compiler->cpool_fill++; + if (compiler->cpool_diff == CONST_POOL_EMPTY) + compiler->cpool_diff = compiler->size; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) +{ + /* Place for at least two instruction (doesn't matter whether the first has a literal). */ + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) + return push_cpool(compiler); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler) +{ + /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ + SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); + return push_inst(compiler, BLX | RM(TMP_REG1)); +} + +static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size) +{ + sljit_uw diff; + sljit_uw ind; + sljit_uw counter = 0; + sljit_uw* clear_const_pool = const_pool; + sljit_uw* clear_const_pool_end = const_pool + cpool_size; + + SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT); + /* Set unused flag for all literals in the constant pool. + I.e.: unused literals can belong to branches, which can be encoded as B or BL. + We can "compress" the constant pool by discarding these literals. */ + while (clear_const_pool < clear_const_pool_end) + *clear_const_pool++ = (sljit_uw)(-1); + + while (last_pc_patch < code_ptr) { + /* Data transfer instruction with Rn == r15. */ + if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { + diff = const_pool - last_pc_patch; + ind = (*last_pc_patch) & 0xfff; + + /* Must be a load instruction with immediate offset. */ + SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); + if ((sljit_si)const_pool[ind] < 0) { + const_pool[ind] = counter; + ind = counter; + counter++; + } + else + ind = const_pool[ind]; + + SLJIT_ASSERT(diff >= 1); + if (diff >= 2 || ind > 0) { + diff = (diff + ind - 2) << 2; + SLJIT_ASSERT(diff <= 0xfff); + *last_pc_patch = (*last_pc_patch & ~0xfff) | diff; + } + else + *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004; + } + last_pc_patch++; + } + return counter; +} + +/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ +struct future_patch { + struct future_patch* next; + sljit_si index; + sljit_si value; +}; + +static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +{ + sljit_si value; + struct future_patch *curr_patch, *prev_patch; + + SLJIT_UNUSED_ARG(compiler); + + /* Using the values generated by patch_pc_relative_loads. */ + if (!*first_patch) + value = (sljit_si)cpool_start_address[cpool_current_index]; + else { + curr_patch = *first_patch; + prev_patch = 0; + while (1) { + if (!curr_patch) { + value = (sljit_si)cpool_start_address[cpool_current_index]; + break; + } + if ((sljit_uw)curr_patch->index == cpool_current_index) { + value = curr_patch->value; + if (prev_patch) + prev_patch->next = curr_patch->next; + else + *first_patch = curr_patch->next; + SLJIT_FREE(curr_patch, compiler->allocator_data); + break; + } + prev_patch = curr_patch; + curr_patch = curr_patch->next; + } + } + + if (value >= 0) { + if ((sljit_uw)value > cpool_current_index) { + curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data); + if (!curr_patch) { + while (*first_patch) { + curr_patch = *first_patch; + *first_patch = (*first_patch)->next; + SLJIT_FREE(curr_patch, compiler->allocator_data); + } + return SLJIT_ERR_ALLOC_FAILED; + } + curr_patch->next = *first_patch; + curr_patch->index = value; + curr_patch->value = cpool_start_address[value]; + *first_patch = curr_patch; + } + cpool_start_address[value] = *buf_ptr; + } + return SLJIT_SUCCESS; +} + +#else + +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +{ + sljit_uw* ptr; + + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +{ + FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); + return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); +} + +#endif + +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +{ + sljit_sw diff; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (jump->flags & IS_BL) + code_ptr--; + + if (jump->flags & JUMP_ADDR) + diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + if (jump->flags & IS_BL) { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK); + jump->flags |= PATCH_B; + return 1; + } + } + else { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); + jump->flags |= PATCH_B; + } + } +#else + if (jump->flags & JUMP_ADDR) + diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + if (diff <= 0x01ffffff && diff >= -0x02000000) { + code_ptr -= 2; + *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK); + jump->flags |= PATCH_B; + return 1; + } +#endif + return 0; +} + +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) +{ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw *ptr = (sljit_uw*)addr; + sljit_uw *inst = (sljit_uw*)ptr[0]; + sljit_uw mov_pc = ptr[1]; + sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); + + if (diff <= 0x7fffff && diff >= -0x800000) { + /* Turn to branch. */ + if (!bl) { + inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } else { + inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); + inst[1] = NOP; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } + } + } else { + /* Get the position of the constant. */ + if (mov_pc & (1 << 23)) + ptr = inst + ((mov_pc & 0xfff) >> 2) + 2; + else + ptr = inst + 1; + + if (*inst != mov_pc) { + inst[0] = mov_pc; + if (!bl) { + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } else { + inst[1] = BLX | RM(TMP_REG1); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } + } + } + *ptr = new_addr; + } +#else + sljit_uw *inst = (sljit_uw*)addr; + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); + inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } +#endif +} + +static sljit_uw get_imm(sljit_uw imm); + +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush) +{ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw *ptr = (sljit_uw*)addr; + sljit_uw *inst = (sljit_uw*)ptr[0]; + sljit_uw ldr_literal = ptr[1]; + sljit_uw src2; + + src2 = get_imm(new_constant); + if (src2) { + *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + src2 = get_imm(~new_constant); + if (src2) { + *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + if (ldr_literal & (1 << 23)) + ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2; + else + ptr = inst + 1; + + if (*inst != ldr_literal) { + *inst = ldr_literal; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } + *ptr = new_constant; +#else + sljit_uw *inst = (sljit_uw*)addr; + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); + inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_uw *code; + sljit_uw *code_ptr; + sljit_uw *buf_ptr; + sljit_uw *buf_end; + sljit_uw size; + sljit_uw word_count; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw cpool_size; + sljit_uw cpool_skip_alignment; + sljit_uw cpool_current_index; + sljit_uw *cpool_start_address; + sljit_uw *last_pc_patch; + struct future_patch *first_patch; +#endif + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + /* Second code generation pass. */ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + size = compiler->size + (compiler->patches << 1); + if (compiler->cpool_fill > 0) + size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; +#else + size = compiler->size; +#endif + code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + cpool_size = 0; + cpool_skip_alignment = 0; + cpool_current_index = 0; + cpool_start_address = NULL; + first_patch = NULL; + last_pc_patch = code; +#endif + + code_ptr = code; + word_count = 0; + + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + + if (label && label->size == 0) { + label->addr = (sljit_uw)code; + label->size = 0; + label = label->next; + } + + do { + buf_ptr = (sljit_uw*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + word_count++; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (cpool_size > 0) { + if (cpool_skip_alignment > 0) { + buf_ptr++; + cpool_skip_alignment--; + } + else { + if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { + SLJIT_FREE_EXEC(code); + compiler->error = SLJIT_ERR_ALLOC_FAILED; + return NULL; + } + buf_ptr++; + if (++cpool_current_index >= cpool_size) { + SLJIT_ASSERT(!first_patch); + cpool_size = 0; + if (label && label->size == word_count) { + /* Points after the current instruction. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + } + } + } + else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { +#endif + *code_ptr = *buf_ptr++; + /* These structures are ordered by their address. */ + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (detect_jump_type(jump, code_ptr, code)) + code_ptr--; + jump->addr = (sljit_uw)code_ptr; +#else + jump->addr = (sljit_uw)(code_ptr - 2); + if (detect_jump_type(jump, code_ptr, code)) + code_ptr -= 2; +#endif + jump = jump->next; + } + if (label && label->size == word_count) { + /* code_ptr can be affected above. */ + label->addr = (sljit_uw)(code_ptr + 1); + label->size = (code_ptr + 1) - code; + label = label->next; + } + if (const_ && const_->addr == word_count) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + const_->addr = (sljit_uw)code_ptr; +#else + const_->addr = (sljit_uw)(code_ptr - 1); +#endif + const_ = const_->next; + } + code_ptr++; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + } + else { + /* Fortunately, no need to shift. */ + cpool_size = *buf_ptr++ & ~PUSH_POOL; + SLJIT_ASSERT(cpool_size > 0); + cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1); + cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); + if (cpool_current_index > 0) { + /* Unconditional branch. */ + *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); + code_ptr = cpool_start_address + cpool_current_index; + } + cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; + cpool_current_index = 0; + last_pc_patch = code_ptr; + } +#endif + } while (buf_ptr < buf_end); + buf = buf->next; + } while (buf); + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + SLJIT_ASSERT(cpool_size == 0); + if (compiler->cpool_fill > 0) { + cpool_start_address = ALIGN_INSTRUCTION(code_ptr); + cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); + if (cpool_current_index > 0) + code_ptr = cpool_start_address + cpool_current_index; + + buf_ptr = compiler->cpool; + buf_end = buf_ptr + compiler->cpool_fill; + cpool_current_index = 0; + while (buf_ptr < buf_end) { + if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { + SLJIT_FREE_EXEC(code); + compiler->error = SLJIT_ERR_ALLOC_FAILED; + return NULL; + } + buf_ptr++; + cpool_current_index++; + } + SLJIT_ASSERT(!first_patch); + } +#endif + + jump = compiler->jumps; + while (jump) { + buf_ptr = (sljit_uw*)jump->addr; + + if (jump->flags & PATCH_B) { + if (!(jump->flags & JUMP_ADDR)) { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + else { + SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + } + else if (jump->flags & SLJIT_REWRITABLE_JUMP) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + jump->addr = (sljit_uw)code_ptr; + code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[1] = *buf_ptr; + inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + code_ptr += 2; +#else + inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); +#endif + } + else { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (jump->flags & IS_BL) + buf_ptr--; + if (*buf_ptr & (1 << 23)) + buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; + else + buf_ptr += 1; + *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; +#else + inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); +#endif + } + jump = jump->next; + } + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + const_ = compiler->consts; + while (const_) { + buf_ptr = (sljit_uw*)const_->addr; + const_->addr = (sljit_uw)code_ptr; + + code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[1] = *buf_ptr; + if (*buf_ptr & (1 << 23)) + buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; + else + buf_ptr += 1; + /* Set the value again (can be a simple constant). */ + inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0); + code_ptr += 2; + + const_ = const_->next; + } +#endif + + SLJIT_ASSERT(code_ptr - code <= (sljit_si)size); + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* emit_op inp_flags. + WRITE_BACK must be the first, since it is a flag. */ +#define WRITE_BACK 0x01 +#define ALLOW_IMM 0x02 +#define ALLOW_INV_IMM 0x04 +#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) +#define ARG_TEST 0x08 + +/* Creates an index in data_transfer_insts array. */ +#define WORD_DATA 0x00 +#define BYTE_DATA 0x10 +#define HALF_DATA 0x20 +#define SIGNED_DATA 0x40 +#define LOAD_DATA 0x80 + +/* Condition: AL. */ +#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ + (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si size, i, tmp; + sljit_uw push; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + /* Push saved registers, temporary registers + stmdb sp!, {..., lr} */ + push = PUSH | (1 << 14); + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) + push |= 1 << reg_map[i]; + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) + push |= 1 << reg_map[i]; + + FAIL_IF(push_inst(compiler, push)); + + /* Stack must be aligned to 8 bytes: */ + size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + local_size = ((size + local_size + 7) & ~7) - size; + compiler->local_size = local_size; + if (local_size > 0) + FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); + + if (args >= 1) + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S0, SLJIT_UNUSED, RM(SLJIT_R0)))); + if (args >= 2) + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S1, SLJIT_UNUSED, RM(SLJIT_R1)))); + if (args >= 3) + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S2, SLJIT_UNUSED, RM(SLJIT_R2)))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + compiler->local_size = ((size + local_size + 7) & ~7) - size; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si i, tmp; + sljit_uw pop; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size > 0) + FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size)); + + /* Push saved registers, temporary registers + ldmia sp!, {..., pc} */ + pop = POP | (1 << 15); + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) + pop |= 1 << reg_map[i]; + + for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) + pop |= 1 << reg_map[i]; + + return push_inst(compiler, pop); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* s/l - store/load (1 bit) + u/s - signed/unsigned (1 bit) + w/b/h/N - word/byte/half/NOT allowed (2 bit) + It contans 16 items, but not all are different. */ + +static sljit_sw data_transfer_insts[16] = { +/* s u w */ 0xe5000000 /* str */, +/* s u b */ 0xe5400000 /* strb */, +/* s u h */ 0xe10000b0 /* strh */, +/* s u N */ 0x00000000 /* not allowed */, +/* s s w */ 0xe5000000 /* str */, +/* s s b */ 0xe5400000 /* strb */, +/* s s h */ 0xe10000b0 /* strh */, +/* s s N */ 0x00000000 /* not allowed */, + +/* l u w */ 0xe5100000 /* ldr */, +/* l u b */ 0xe5500000 /* ldrb */, +/* l u h */ 0xe11000b0 /* ldrh */, +/* l u N */ 0x00000000 /* not allowed */, +/* l s w */ 0xe5100000 /* ldr */, +/* l s b */ 0xe11000d0 /* ldrsb */, +/* l s h */ 0xe11000f0 /* ldrsh */, +/* l s N */ 0x00000000 /* not allowed */, +}; + +#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \ + (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2)) +/* Normal ldr/str instruction. + Type2: ldrsb, ldrh, ldrsh */ +#define IS_TYPE1_TRANSFER(type) \ + (data_transfer_insts[(type) >> 4] & 0x04000000) +#define TYPE2_TRANSFER_IMM(imm) \ + (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) + +/* flags: */ + /* Arguments are swapped. */ +#define ARGS_SWAPPED 0x01 + /* Inverted immediate. */ +#define INV_IMM 0x02 + /* Source and destination is register. */ +#define REG_DEST 0x04 +#define REG_SOURCE 0x08 + /* One instruction is enough. */ +#define FAST_DEST 0x10 + /* Multiple instructions are required. */ +#define SLOW_DEST 0x20 +/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */ +#define SET_FLAGS (1 << 20) +/* dst: reg + src1: reg + src2: reg or imm (if allowed) + SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */ +#define SRC2_IMM (1 << 25) + +#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2))) + +#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2)) + +#define EMIT_SHIFT_INS_AND_RETURN(opcode) \ + SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \ + if (compiler->shift_imm != 0x20) { \ + SLJIT_ASSERT(src1 == TMP_REG1); \ + SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ + if (compiler->shift_imm != 0) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \ + } \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + sljit_sw mul_inst; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if (dst != src2) { + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (op == SLJIT_MOV_UB) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]))); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]))); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_NOT: + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(!(flags & INV_IMM)); + SLJIT_ASSERT(!(src2 & SRC2_IMM)); + FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); + if (flags & SET_FLAGS) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); + return SLJIT_SUCCESS; + + case SLJIT_ADD: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP); + + case SLJIT_ADDC: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP); + + case SLJIT_SUB: + SLJIT_ASSERT(!(flags & INV_IMM)); + if (!(flags & ARGS_SWAPPED)) + EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP); + + case SLJIT_SUBC: + SLJIT_ASSERT(!(flags & INV_IMM)); + if (!(flags & ARGS_SWAPPED)) + EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP); + + case SLJIT_MUL: + SLJIT_ASSERT(!(flags & INV_IMM)); + SLJIT_ASSERT(!(src2 & SRC2_IMM)); + if (SLJIT_UNLIKELY(op & SLJIT_SET_O)) + mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12); + else + mul_inst = MUL | (reg_map[dst] << 16); + + if (dst != src2) + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2])); + else if (dst != src1) + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1])); + else { + /* Rm and Rd must not be the same register. */ + SLJIT_ASSERT(dst != TMP_REG1); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2]))); + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1])); + } + + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + + /* We need to use TMP_REG3. */ + compiler->cache_arg = 0; + compiler->cache_argw = 0; + /* cmp TMP_REG2, dst asr #31. */ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0)); + + case SLJIT_AND: + if (!(flags & INV_IMM)) + EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP); + + case SLJIT_OR: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP); + + case SLJIT_XOR: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP); + + case SLJIT_SHL: + EMIT_SHIFT_INS_AND_RETURN(0); + + case SLJIT_LSHR: + EMIT_SHIFT_INS_AND_RETURN(1); + + case SLJIT_ASHR: + EMIT_SHIFT_INS_AND_RETURN(2); + } + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +#undef EMIT_DATA_PROCESS_INS_AND_RETURN +#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN +#undef EMIT_SHIFT_INS_AND_RETURN + +/* Tests whether the immediate can be stored in the 12 bit imm field. + Returns with 0 if not possible. */ +static sljit_uw get_imm(sljit_uw imm) +{ + sljit_si rol; + + if (imm <= 0xff) + return SRC2_IMM | imm; + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol = 8; + } + else { + imm = (imm << 24) | (imm >> 8); + rol = 0; + } + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol += 4; + } + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + return SRC2_IMM | (imm >> 24) | (rol << 8); + else + return 0; +} + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +{ + sljit_uw mask; + sljit_uw imm1; + sljit_uw imm2; + sljit_si rol; + + /* Step1: Search a zero byte (8 continous zero bit). */ + mask = 0xff000000; + rol = 8; + while(1) { + if (!(imm & mask)) { + /* Rol imm by rol. */ + imm = (imm << rol) | (imm >> (32 - rol)); + /* Calculate arm rol. */ + rol = 4 + (rol >> 1); + break; + } + rol += 2; + mask >>= 2; + if (mask & 0x3) { + /* rol by 8. */ + imm = (imm << 8) | (imm >> 24); + mask = 0xff00; + rol = 24; + while (1) { + if (!(imm & mask)) { + /* Rol imm by rol. */ + imm = (imm << rol) | (imm >> (32 - rol)); + /* Calculate arm rol. */ + rol = (rol >> 1) - 8; + break; + } + rol += 2; + mask >>= 2; + if (mask & 0x3) + return 0; + } + break; + } + } + + /* The low 8 bit must be zero. */ + SLJIT_ASSERT(!(imm & 0xff)); + + if (!(imm & 0xff000000)) { + imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); + imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); + } + else if (imm & 0xc0000000) { + imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); + imm <<= 8; + rol += 4; + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol += 4; + } + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + else + return 0; + } + else { + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); + imm <<= 8; + rol += 4; + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + else + return 0; + } + + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1))); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2))); + return 1; +} +#endif + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm) +{ + sljit_uw tmp; + +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + if (!(imm & ~0xffff)) + return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); +#endif + + /* Create imm by 1 inst. */ + tmp = get_imm(imm); + if (tmp) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); + + tmp = get_imm(~imm); + if (tmp) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp)); + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + /* Create imm by 2 inst. */ + FAIL_IF(generate_int(compiler, reg, imm, 1)); + FAIL_IF(generate_int(compiler, reg, ~imm, 0)); + + /* Load integer. */ + return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm); +#else + return emit_imm(compiler, reg, imm); +#endif +} + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + value = get_imm(value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value)); + } + else { + value = get_imm(-value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value)); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_uw imm; + + if (arg & SLJIT_IMM) { + imm = get_imm(argw); + if (imm) { + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm))); + return -1; + } + imm = get_imm(~argw); + if (imm) { + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm))); + return -1; + } + return 0; + } + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads/stores. */ + if (!(arg & REG_MASK)) + return 0; + + if (arg & OFFS_REG_MASK) { + if ((argw & 0x3) != 0 && !IS_TYPE1_TRANSFER(inp_flags)) + return 0; + + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, + RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)))); + return -1; + } + + if (IS_TYPE1_TRANSFER(inp_flags)) { + if (argw >= 0 && argw <= 0xfff) { + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw))); + return -1; + } + if (argw < 0 && argw >= -0xfff) { + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw))); + return -1; + } + } + else { + if (argw >= 0 && argw <= 0xff) { + if (inp_flags & ARG_TEST) + return 1; + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)))); + return -1; + } + if (argw < 0 && argw >= -0xff) { + if (inp_flags & ARG_TEST) + return 1; + argw = -argw; + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)))); + return -1; + } + } + + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + /* Immediate caching is not supported as it would be an operation on constant arguments. */ + if (arg & SLJIT_IMM) + return 0; + + /* Always a simple operation. */ + if (arg & OFFS_REG_MASK) + return 0; + + if (!(arg & REG_MASK)) { + /* Immediate access. */ + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) + return 1; + return 0; + } + + if (argw <= 0xfffff && argw >= -0xfffff) + return 0; + + if (argw == next_argw && (next_arg & SLJIT_MEM)) + return 1; + + if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) + return 1; + + return 0; +} + +#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \ + if (max_delta & 0xf00) \ + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \ + else \ + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm)))); + +#define TEST_WRITE_BACK() \ + if (inp_flags & WRITE_BACK) { \ + tmp_r = arg & REG_MASK; \ + if (reg == tmp_r) { \ + /* This can only happen for stores */ \ + /* since ldr reg, [reg, ...]! has no meaning */ \ + SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \ + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg)))); \ + reg = TMP_REG3; \ + } \ + } + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_sw max_delta; + sljit_sw sign; + sljit_uw imm; + + if (arg & SLJIT_IMM) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + return load_immediate(compiler, reg, argw); + } + + SLJIT_ASSERT(arg & SLJIT_MEM); + + tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; + max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff; + + if ((arg & REG_MASK) == SLJIT_UNUSED) { + /* Write back is not used. */ + imm = (sljit_uw)(argw - compiler->cache_argw); + if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + if (imm <= (sljit_uw)max_delta) { + sign = 1; + argw = argw - compiler->cache_argw; + } + else { + sign = 0; + argw = compiler->cache_argw - argw; + } + + GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw); + return SLJIT_SUCCESS; + } + + /* With write back, we can create some sophisticated loads, but + it is hard to decide whether we should convert downward (0s) or upward (1s). */ + imm = (sljit_uw)(argw - next_argw); + if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0); + return SLJIT_SUCCESS; + } + + if (arg & OFFS_REG_MASK) { + SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); + if (inp_flags & WRITE_BACK) + tmp_r = arg & REG_MASK; + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)))); + return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0))); + } + + imm = (sljit_uw)(argw - compiler->cache_argw); + if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + imm = (sljit_uw)-(sljit_sw)imm; + GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + + imm = get_imm(argw & ~max_delta); + if (imm) { + TEST_WRITE_BACK(); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm))); + GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + return SLJIT_SUCCESS; + } + + imm = get_imm(-argw & ~max_delta); + if (imm) { + argw = -argw; + TEST_WRITE_BACK(); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm))); + GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + return SLJIT_SUCCESS; + } + + if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { + TEST_WRITE_BACK(); + return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); + } + + if (argw == next_argw && (next_arg & SLJIT_MEM)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + + TEST_WRITE_BACK(); + return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); + } + + imm = (sljit_uw)(argw - next_argw); + if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK]))); + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0); + return SLJIT_SUCCESS; + } + + if ((arg & REG_MASK) == tmp_r) { + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + + /* We prefers register and simple consts. */ + sljit_si dst_r; + sljit_si src1_r; + sljit_si src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + /* Destination check. */ + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else { + SLJIT_ASSERT(dst & SLJIT_MEM); + if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { + flags |= FAST_DEST; + dst_r = TMP_REG2; + } + else { + flags |= SLOW_DEST; + dst_r = 0; + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) + src1_r = src1; + else if (FAST_IS_REG(src2)) { + flags |= ARGS_SWAPPED; + src1_r = src2; + src2 = src1; + src2w = src1w; + } + else do { /* do { } while(0) is used because of breaks. */ + src1_r = 0; + if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { + /* The second check will generate a hit. */ + src2_r = get_imm(src1w); + if (src2_r) { + flags |= ARGS_SWAPPED; + src1 = src2; + src1w = src2w; + break; + } + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src1w); + if (src2_r) { + flags |= ARGS_SWAPPED | INV_IMM; + src1 = src2; + src1w = src2w; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-src1w); + if (src2_r) { + /* Note: ARGS_SWAPPED is intentionally not applied! */ + src1 = src2; + src1w = src2w; + op = SLJIT_SUB | GET_ALL_FLAGS(op); + break; + } + } + } + + if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1_r = TMP_REG1; + } + } while (0); + + /* Source 2. */ + if (src2_r == 0) { + if (FAST_IS_REG(src2)) { + src2_r = src2; + flags |= REG_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else do { /* do { } while(0) is used because of breaks. */ + if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) { + src2_r = get_imm(src2w); + if (src2_r) + break; + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src2w); + if (src2_r) { + flags |= INV_IMM; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-src2w); + if (src2_r) { + op = SLJIT_SUB | GET_ALL_FLAGS(op); + flags &= ~ARGS_SWAPPED; + break; + } + } + if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { + src2_r = get_imm(-src2w); + if (src2_r) { + op = SLJIT_ADD | GET_ALL_FLAGS(op); + flags &= ~ARGS_SWAPPED; + break; + } + } + } + + /* src2_r is 0. */ + if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { + FAIL_IF(compiler->error); + src2_r = sugg_src2_r; + } + } while (0); + } + + /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero. + If they are zero, they must not be registers. */ + if (src1_r == 0 && src2_r == 0 && dst_r == 0) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); + flags |= ARGS_SWAPPED; + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + src1_r = TMP_REG1; + src2_r = TMP_REG2; + } + else if (src1_r == 0 && src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + src1_r = TMP_REG1; + } + else if (src1_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + src1_r = TMP_REG1; + } + else if (src2_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + src2_r = sugg_src2_r; + } + + if (dst_r == 0) + dst_r = TMP_REG2; + + if (src1_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + src1_r = TMP_REG1; + } + + if (src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); + src2_r = sugg_src2_r; + } + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (flags & (FAST_DEST | SLOW_DEST)) { + if (flags & FAST_DEST) + FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); + else + FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); + } + return SLJIT_SUCCESS; +} + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + FAIL_IF(push_inst(compiler, BKPT)); + break; + case SLJIT_NOP: + FAIL_IF(push_inst(compiler, NOP)); + break; + case SLJIT_LUMUL: + case SLJIT_LSMUL: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + | (reg_map[SLJIT_R1] << 16) + | (reg_map[SLJIT_R0] << 12) + | (reg_map[SLJIT_R0] << 8) + | reg_map[SLJIT_R1]); +#else + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1)))); + return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + | (reg_map[SLJIT_R1] << 16) + | (reg_map[SLJIT_R0] << 12) + | (reg_map[SLJIT_R0] << 8) + | reg_map[TMP_REG1]); +#endif + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping); + + if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */)); + FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */)); + } + else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) + FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); + +#if defined(__GNUC__) + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, + ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); +#else +#error "Software divmod functions are needed" +#endif + + if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */)); + FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */)); + } + else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) + return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + case SLJIT_SUB: + case SLJIT_SUBC: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (src2 & SLJIT_IMM) { + compiler->shift_imm = src2w & 0x1f; + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); + } + else { + compiler->shift_imm = 0x20; + return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); + } + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg << 1; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + return push_inst(compiler, *(sljit_uw*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + +/* 0 - no fpu + 1 - vfp */ +static sljit_si arm_fpu_type = -1; + +static void init_compiler(void) +{ + if (arm_fpu_type != -1) + return; + + /* TODO: Only the OS can help to determine the correct fpu type. */ + arm_fpu_type = 1; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + if (arm_fpu_type == -1) + init_compiler(); + return arm_fpu_type; +#endif +} + +#else + +#define arm_fpu_type 1 + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +#endif + +#define FPU_LOAD (1 << 20) +#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ + ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs)) +#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ + ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)))); + arg = SLJIT_MEM | TMP_REG1; + argw = 0; + } + + /* Fast loads and stores. */ + if ((arg & REG_MASK)) { + if (!(argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2)); + } + + if (compiler->cache_arg == arg) { + tmp = argw - compiler->cache_argw; + if (!(tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2)); + if (!(-tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); + } + } + + if (arg & REG_MASK) { + if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0)); + } + imm = get_imm(argw & ~0x3fc); + if (imm) { + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm))); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm) { + argw = -argw; + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm))); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + if (arg & REG_MASK) { + FAIL_IF(load_immediate(compiler, TMP_REG1, argw)); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1]))); + } + else + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + src = TMP_FREG1; + } + + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_SINGLE_OP, TMP_FREG1, src, 0))); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (TMP_FREG1 << 16)); + + /* Store the integer value from a VFP register. */ + return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16))); + else if (src & SLJIT_MEM) { + /* Load the integer value into a VFP register. */ + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16))); + } + + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_SINGLE_OP, dst_r, TMP_FREG1, 0))); + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + src2 = TMP_FREG2; + } + + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, src1, src2, 0))); + return push_inst(compiler, VMRS); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) + op ^= SLJIT_SINGLE_OP; + + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw)); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + break; + case SLJIT_DABS: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + break; + case SLJIT_CONVD_FROMS: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + op ^= SLJIT_SINGLE_OP; + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + break; + + case SLJIT_DSUB: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + break; + + case SLJIT_DMUL: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + break; + + case SLJIT_DDIV: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + break; + } + + if (dst_r == TMP_FREG1) + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + + return SLJIT_SUCCESS; +} + +#undef FPU_LOAD +#undef EMIT_FPU_DATA_TRANSFER +#undef EMIT_FPU_OPERATION + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3)))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src)))); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) + FAIL_IF(compiler->error); + else { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0)); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2)))); + } + } + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); + return push_inst(compiler, BLX | RM(TMP_REG3)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + case SLJIT_MUL_NOT_OVERFLOW: + case SLJIT_D_EQUAL: + return 0x00000000; + + case SLJIT_NOT_EQUAL: + case SLJIT_MUL_OVERFLOW: + case SLJIT_D_NOT_EQUAL: + return 0x10000000; + + case SLJIT_LESS: + case SLJIT_D_LESS: + return 0x30000000; + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + return 0x20000000; + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + return 0x80000000; + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + return 0x90000000; + + case SLJIT_SIG_LESS: + return 0xb0000000; + + case SLJIT_SIG_GREATER_EQUAL: + return 0xa0000000; + + case SLJIT_SIG_GREATER: + return 0xc0000000; + + case SLJIT_SIG_LESS_EQUAL: + return 0xd0000000; + + case SLJIT_OVERFLOW: + case SLJIT_D_UNORDERED: + return 0x60000000; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_D_ORDERED: + return 0x70000000; + + default: + SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); + return 0xe0000000; + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In ARM, we don't need to touch the arguments. */ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (type >= SLJIT_FAST_CALL) + PTR_FAIL_IF(prepare_blx(compiler)); + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, + type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0)); + + if (jump->flags & SLJIT_REWRITABLE_JUMP) { + jump->addr = compiler->size; + compiler->patches++; + } + + if (type >= SLJIT_FAST_CALL) { + jump->flags |= IS_BL; + PTR_FAIL_IF(emit_blx(compiler)); + } + + if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) + jump->addr = compiler->size; +#else + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_BL; + PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); + PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type))); + jump->addr = compiler->size; +#endif + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + /* In ARM, we don't need to touch the arguments. */ + if (!(src & SLJIT_IMM)) { + if (FAST_IS_REG(src)) + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); + + SLJIT_ASSERT(src & SLJIT_MEM); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); + jump->u.target = srcw; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (type >= SLJIT_FAST_CALL) + FAIL_IF(prepare_blx(compiler)); + FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); + if (type >= SLJIT_FAST_CALL) + FAIL_IF(emit_blx(compiler)); +#else + FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); + FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); +#endif + jump->addr = compiler->size; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_uw cc, ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type & 0xff); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0))); + FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc)); + return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + } + + ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { + FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc)); + /* The condition must always be set, even if the ORR/EOR is not executed above. */ + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc)); + FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000))); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); + + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si reg; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); + compiler->patches++; +#else + PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); +#endif + set_const(const_, compiler); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + inline_set_jump_addr(addr, new_addr, 1); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + inline_set_const(addr, new_constant, 1); +} diff --git a/pcre2/src/sljit/sljitNativeARM_64.c b/pcre2/src/sljit/sljitNativeARM_64.c new file mode 100644 index 000000000..044a675ee --- /dev/null +++ b/pcre2/src/sljit/sljitNativeARM_64.c @@ -0,0 +1,2050 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "ARM-64" SLJIT_CPUINFO; +} + +/* Length of an instruction word */ +typedef sljit_ui sljit_ins; + +#define TMP_ZERO (0) + +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5) +#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6) + +#define TMP_FREG1 (0) +#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { + 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31 +}; + +#define W_OP (1 << 31) +#define RD(rd) (reg_map[rd]) +#define RT(rt) (reg_map[rt]) +#define RN(rn) (reg_map[rn] << 5) +#define RT2(rt2) (reg_map[rt2] << 10) +#define RM(rm) (reg_map[rm] << 16) +#define VD(vd) (vd) +#define VT(vt) (vt) +#define VN(vn) ((vn) << 5) +#define VM(vm) ((vm) << 16) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define ADC 0x9a000000 +#define ADD 0x8b000000 +#define ADDI 0x91000000 +#define AND 0x8a000000 +#define ANDI 0x92000000 +#define ASRV 0x9ac02800 +#define B 0x14000000 +#define B_CC 0x54000000 +#define BL 0x94000000 +#define BLR 0xd63f0000 +#define BR 0xd61f0000 +#define BRK 0xd4200000 +#define CBZ 0xb4000000 +#define CLZ 0xdac01000 +#define CSINC 0x9a800400 +#define EOR 0xca000000 +#define EORI 0xd2000000 +#define FABS 0x1e60c000 +#define FADD 0x1e602800 +#define FCMP 0x1e602000 +#define FCVT 0x1e224000 +#define FCVTZS 0x9e780000 +#define FDIV 0x1e601800 +#define FMOV 0x1e604000 +#define FMUL 0x1e600800 +#define FNEG 0x1e614000 +#define FSUB 0x1e603800 +#define LDRI 0xf9400000 +#define LDP 0xa9400000 +#define LDP_PST 0xa8c00000 +#define LSLV 0x9ac02000 +#define LSRV 0x9ac02400 +#define MADD 0x9b000000 +#define MOVK 0xf2800000 +#define MOVN 0x92800000 +#define MOVZ 0xd2800000 +#define NOP 0xd503201f +#define ORN 0xaa200000 +#define ORR 0xaa000000 +#define ORRI 0xb2000000 +#define RET 0xd65f0000 +#define SBC 0xda000000 +#define SBFM 0x93000000 +#define SCVTF 0x9e620000 +#define SDIV 0x9ac00c00 +#define SMADDL 0x9b200000 +#define SMULH 0x9b403c00 +#define STP 0xa9000000 +#define STP_PRE 0xa9800000 +#define STRI 0xf9000000 +#define STR_FI 0x3d000000 +#define STR_FR 0x3c206800 +#define STUR_FI 0x3c000000 +#define SUB 0xcb000000 +#define SUBI 0xd1000000 +#define SUBS 0xeb000000 +#define UBFM 0xd3000000 +#define UDIV 0x9ac00800 +#define UMULH 0x9bc03c00 + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +{ + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21))); + return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21)); +} + +static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) +{ + sljit_si dst = inst[0] & 0x1f; + SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); + inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); + inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); + inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21); + inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); +} + +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) { + jump->flags |= PATCH_ABS64; + return 0; + } + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4); + + if (jump->flags & IS_COND) { + diff += sizeof(sljit_ins); + if (diff <= 0xfffff && diff >= -0x100000) { + code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1; + jump->addr -= sizeof(sljit_ins); + jump->flags |= PATCH_COND; + return 5; + } + diff -= sizeof(sljit_ins); + } + + if (diff <= 0x7ffffff && diff >= -0x8000000) { + jump->flags |= PATCH_B; + return 4; + } + + if (target_addr <= 0xffffffffl) { + if (jump->flags & IS_COND) + code_ptr[-5] -= (2 << 5); + code_ptr[-2] = code_ptr[0]; + return 2; + } + if (target_addr <= 0xffffffffffffl) { + if (jump->flags & IS_COND) + code_ptr[-5] -= (1 << 5); + jump->flags |= PATCH_ABS48; + code_ptr[-1] = code_ptr[0]; + return 1; + } + + jump->flags |= PATCH_ABS64; + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + sljit_si dst; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + /* These structures are ordered by their address. */ + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { + jump->addr = (sljit_uw)(code_ptr - 4); + code_ptr -= detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + if (jump->flags & PATCH_B) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000); + buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff); + if (jump->flags & IS_COND) + buf_ptr[-1] -= (4 << 5); + break; + } + if (jump->flags & PATCH_COND) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000); + buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5); + break; + } + + SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl); + SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl); + + dst = buf_ptr[0] & 0x1f; + buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5); + buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21); + if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) + buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21); + if (jump->flags & PATCH_ABS64) + buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21); + } while (0); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Core code generator functions. */ +/* --------------------------------------------------------------------- */ + +#define COUNT_TRAILING_ZERO(value, result) \ + result = 0; \ + if (!(value & 0xffffffff)) { \ + result += 32; \ + value >>= 32; \ + } \ + if (!(value & 0xffff)) { \ + result += 16; \ + value >>= 16; \ + } \ + if (!(value & 0xff)) { \ + result += 8; \ + value >>= 8; \ + } \ + if (!(value & 0xf)) { \ + result += 4; \ + value >>= 4; \ + } \ + if (!(value & 0x3)) { \ + result += 2; \ + value >>= 2; \ + } \ + if (!(value & 0x1)) { \ + result += 1; \ + value >>= 1; \ + } + +#define LOGICAL_IMM_CHECK 0x100 + +static sljit_ins logical_imm(sljit_sw imm, sljit_si len) +{ + sljit_si negated, ones, right; + sljit_uw mask, uimm; + sljit_ins ins; + + if (len & LOGICAL_IMM_CHECK) { + len &= ~LOGICAL_IMM_CHECK; + if (len == 32 && (imm == 0 || imm == -1)) + return 0; + if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1)) + return 0; + } + + SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) + || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1)); + uimm = (sljit_uw)imm; + while (1) { + if (len <= 0) { + SLJIT_ASSERT_STOP(); + return 0; + } + mask = ((sljit_uw)1 << len) - 1; + if ((uimm & mask) != ((uimm >> len) & mask)) + break; + len >>= 1; + } + + len <<= 1; + + negated = 0; + if (uimm & 0x1) { + negated = 1; + uimm = ~uimm; + } + + if (len < 64) + uimm &= ((sljit_uw)1 << len) - 1; + + /* Unsigned right shift. */ + COUNT_TRAILING_ZERO(uimm, right); + + /* Signed shift. We also know that the highest bit is set. */ + imm = (sljit_sw)~uimm; + SLJIT_ASSERT(imm < 0); + + COUNT_TRAILING_ZERO(imm, ones); + + if (~imm) + return 0; + + if (len == 64) + ins = 1 << 22; + else + ins = (0x3f - ((len << 1) - 1)) << 10; + + if (negated) + return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16); + + return ins | ((ones - 1) << 10) | ((len - right) << 16); +} + +#undef COUNT_TRAILING_ZERO + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm) +{ + sljit_uw imm = (sljit_uw)simm; + sljit_si i, zeros, ones, first; + sljit_ins bitmask; + + if (imm <= 0xffff) + return push_inst(compiler, MOVZ | RD(dst) | (imm << 5)); + + if (simm >= -0x10000 && simm < 0) + return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)); + + if (imm <= 0xffffffffl) { + if ((imm & 0xffff0000l) == 0xffff0000) + return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5)); + if ((imm & 0xffff) == 0xffff) + return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + bitmask = logical_imm(simm, 16); + if (bitmask != 0) + return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask); + } + else { + bitmask = logical_imm(simm, 32); + if (bitmask != 0) + return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask); + } + + if (imm <= 0xffffffffl) { + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); + return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + } + + if (simm >= -0x100000000l && simm < 0) { + FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5))); + return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + } + + /* A large amount of number can be constructed from ORR and MOVx, + but computing them is costly. We don't */ + + zeros = 0; + ones = 0; + for (i = 4; i > 0; i--) { + if ((simm & 0xffff) == 0) + zeros++; + if ((simm & 0xffff) == 0xffff) + ones++; + simm >>= 16; + } + + simm = (sljit_sw)imm; + first = 1; + if (ones > zeros) { + simm = ~simm; + for (i = 0; i < 4; i++) { + if (!(simm & 0xffff)) { + simm >>= 16; + continue; + } + if (first) { + first = 0; + FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + } + else + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21))); + simm >>= 16; + } + return SLJIT_SUCCESS; + } + + for (i = 0; i < 4; i++) { + if (!(simm & 0xffff)) { + simm >>= 16; + continue; + } + if (first) { + first = 0; + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + } + else + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + simm >>= 16; + } + return SLJIT_SUCCESS; +} + +#define ARG1_IMM 0x0010000 +#define ARG2_IMM 0x0020000 +#define INT_OP 0x0040000 +#define SET_FLAGS 0x0080000 +#define UNUSED_RETURN 0x0100000 +#define SLOW_DEST 0x0200000 +#define SLOW_SRC1 0x0400000 +#define SLOW_SRC2 0x0800000 + +#define CHECK_FLAGS(flag_bits) \ + if (flags & SET_FLAGS) { \ + inv_bits |= flag_bits; \ + if (flags & UNUSED_RETURN) \ + dst = TMP_ZERO; \ + } + +static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2) +{ + /* dst must be register, TMP_REG1 + arg1 must be register, TMP_REG1, imm + arg2 must be register, TMP_REG2, imm */ + sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; + sljit_ins inst_bits; + sljit_si op = (flags & 0xffff); + sljit_si reg; + sljit_sw imm, nimm; + + if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { + /* Both are immediates. */ + flags &= ~ARG1_IMM; + if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB) + arg1 = TMP_ZERO; + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + } + + if (flags & (ARG1_IMM | ARG2_IMM)) { + reg = (flags & ARG2_IMM) ? arg1 : arg2; + imm = (flags & ARG2_IMM) ? arg2 : arg1; + + switch (op) { + case SLJIT_MUL: + case SLJIT_NEG: + case SLJIT_CLZ: + case SLJIT_ADDC: + case SLJIT_SUBC: + /* No form with immediate operand (except imm 0, which + is represented by a ZERO register). */ + break; + case SLJIT_MOV: + SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); + return load_immediate(compiler, dst, imm); + case SLJIT_NOT: + SLJIT_ASSERT(flags & ARG2_IMM); + FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); + goto set_flags; + case SLJIT_SUB: + if (flags & ARG1_IMM) + break; + imm = -imm; + /* Fall through. */ + case SLJIT_ADD: + if (imm == 0) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg)); + } + if (imm > 0 && imm <= 0xfff) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10)); + } + nimm = -imm; + if (nimm > 0 && nimm <= 0xfff) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10)); + } + if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)); + } + if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)); + } + if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) { + FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22))); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10)); + } + if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) { + FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22))); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10)); + } + break; + case SLJIT_AND: + inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); + if (!inst_bits) + break; + CHECK_FLAGS(3 << 29); + return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); + case SLJIT_OR: + case SLJIT_XOR: + inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); + if (!inst_bits) + break; + if (op == SLJIT_OR) + inst_bits |= ORRI; + else + inst_bits |= EORI; + FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg))); + goto set_flags; + case SLJIT_SHL: + if (flags & ARG1_IMM) + break; + if (flags & INT_OP) { + imm &= 0x1f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10))); + } + else { + imm &= 0x3f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10))); + } + goto set_flags; + case SLJIT_LSHR: + case SLJIT_ASHR: + if (flags & ARG1_IMM) + break; + if (op == SLJIT_ASHR) + inv_bits |= 1 << 30; + if (flags & INT_OP) { + imm &= 0x1f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10))); + } + else { + imm &= 0x3f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10))); + } + goto set_flags; + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (flags & ARG2_IMM) { + if (arg2 == 0) + arg2 = TMP_ZERO; + else { + FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); + arg2 = TMP_REG2; + } + } + else { + if (arg1 == 0) + arg1 = TMP_ZERO; + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + } + } + + /* Both arguments are registers. */ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + case SLJIT_MOVU: + case SLJIT_MOVU_P: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_MOV_UB: + case SLJIT_MOVU_UB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); + case SLJIT_MOV_SB: + case SLJIT_MOVU_SB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (!(flags & INT_OP)) + inv_bits |= 1 << 22; + return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); + case SLJIT_MOV_UH: + case SLJIT_MOVU_UH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); + case SLJIT_MOV_SH: + case SLJIT_MOVU_SH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (!(flags & INT_OP)) + inv_bits |= 1 << 22; + return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); + case SLJIT_MOV_UI: + case SLJIT_MOVU_UI: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if ((flags & INT_OP) && dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_MOV_SI: + case SLJIT_MOVU_SI: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if ((flags & INT_OP) && dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); + case SLJIT_NOT: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); + goto set_flags; + case SLJIT_NEG: + SLJIT_ASSERT(arg1 == TMP_REG1); + if (flags & SET_FLAGS) + inv_bits |= 1 << 29; + return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_CLZ: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2))); + goto set_flags; + case SLJIT_ADD: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_ADDC: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_SUB: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_SUBC: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_MUL: + if (!(flags & SET_FLAGS)) + return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)); + if (flags & INT_OP) { + FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10))); + FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10))); + return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); + } + FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2))); + FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO))); + return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); + case SLJIT_AND: + CHECK_FLAGS(3 << 29); + return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_OR: + FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_XOR: + FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_SHL: + FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_LSHR: + FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_ASHR: + FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + +set_flags: + if (flags & SET_FLAGS) + return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO)); + return SLJIT_SUCCESS; +} + +#define STORE 0x01 +#define SIGNED 0x02 + +#define UPDATE 0x04 +#define ARG_TEST 0x08 + +#define BYTE_SIZE 0x000 +#define HALF_SIZE 0x100 +#define INT_SIZE 0x200 +#define WORD_SIZE 0x300 + +#define MEM_SIZE_SHIFT(flags) ((flags) >> 8) + +static SLJIT_CONST sljit_ins sljit_mem_imm[4] = { +/* u l */ 0x39400000 /* ldrb [reg,imm] */, +/* u s */ 0x39000000 /* strb [reg,imm] */, +/* s l */ 0x39800000 /* ldrsb [reg,imm] */, +/* s s */ 0x39000000 /* strb [reg,imm] */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_simm[4] = { +/* u l */ 0x38400000 /* ldurb [reg,imm] */, +/* u s */ 0x38000000 /* sturb [reg,imm] */, +/* s l */ 0x38800000 /* ldursb [reg,imm] */, +/* s s */ 0x38000000 /* sturb [reg,imm] */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = { +/* u l */ 0x38400c00 /* ldrb [reg,imm]! */, +/* u s */ 0x38000c00 /* strb [reg,imm]! */, +/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, +/* s s */ 0x38000c00 /* strb [reg,imm]! */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { +/* u l */ 0x38606800 /* ldrb [reg,reg] */, +/* u s */ 0x38206800 /* strb [reg,reg] */, +/* s l */ 0x38a06800 /* ldrsb [reg,reg] */, +/* s s */ 0x38206800 /* strb [reg,reg] */, +}; + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + if (value <= 0xfff) + return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10)); + if (value <= 0xffffff && !(value & 0xfff)) + return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); + } + else { + value = -value; + if (value <= 0xfff) + return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10)); + if (value <= 0xffffff && !(value & 0xfff)) + return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + arg &= REG_MASK; + argw &= 0x1ff; + FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3] + | (shift << 30) | RT(reg) | RN(arg) | (argw << 12))); + return -1; + } + return 0; + } + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + if (argw && argw != shift) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) + | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0))); + return -1; + } + + arg &= REG_MASK; + if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(arg) | (argw << (10 - shift)))); + return -1; + } + + if (argw > 255 || argw < -256) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12))); + return -1; +} + +/* see getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_sw diff; + if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) + return 0; + + if (!(arg & REG_MASK)) { + diff = argw - next_argw; + if (diff <= 0xfff && diff >= -0xfff) + return 1; + return 0; + } + + if (argw == next_argw) + return 1; + + diff = argw - next_argw; + if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) + return 1; + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, + sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_si tmp_r, other_r; + sljit_sw diff; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + tmp_r = (flags & STORE) ? TMP_REG3 : reg; + + if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) { + /* Update only applies if a base register exists. */ + other_r = OFFS_REG(arg); + if (!other_r) { + other_r = arg & REG_MASK; + if (other_r != reg && argw >= 0 && argw <= 0xffffff) { + if ((argw & 0xfff) != 0) + FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); + if (argw >> 12) + FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); + } + else if (other_r != reg && argw < 0 && argw >= -0xffffff) { + argw = -argw; + if ((argw & 0xfff) != 0) + FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); + if (argw >> 12) + FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); + } + + if (compiler->cache_arg == SLJIT_MEM) { + if (argw == compiler->cache_argw) { + other_r = TMP_REG3; + argw = 0; + } + else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + if (argw) { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + /* No caching here. */ + arg &= REG_MASK; + argw &= 0x3; + if (!argw || argw == shift) { + FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0))); + return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)); + } + if (arg != reg) { + FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); + } + FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10))); + FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR))); + return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR)); + } + + if (arg & OFFS_REG_MASK) { + other_r = OFFS_REG(arg); + arg &= REG_MASK; + FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r)); + } + + if (compiler->cache_arg == arg) { + diff = argw - compiler->cache_argw; + if (diff <= 255 && diff >= -256) + return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); + } + } + + if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) { + FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift))); + } + + diff = argw - next_argw; + next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0; + arg &= REG_MASK; + + if (arg && compiler->cache_arg == SLJIT_MEM) { + if (compiler->cache_argw == argw) + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); + } + } + + compiler->cache_argw = argw; + if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + + if (next_arg) { + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg))); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + } + + if (arg) + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si i, tmp, offs, prev, saved_regs_size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); + local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; + local_size = (local_size + 15) & ~0xf; + compiler->local_size = local_size; + + if (local_size <= (63 * sizeof(sljit_sw))) { + FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) + | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); + offs = (local_size - saved_regs_size) << (15 - 3); + } else { + offs = 0 << 15; + if (saved_regs_size & 0x8) { + offs = 1 << 15; + saved_regs_size += sizeof(sljit_sw); + } + local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; + if (saved_regs_size > 0) + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); + } + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + prev = -1; + for (i = SLJIT_S0; i >= tmp; i--) { + if (prev == -1) { + if (!(offs & (1 << 15))) { + prev = i; + continue; + } + FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); + offs += 1 << 15; + continue; + } + FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + offs += 2 << 15; + prev = -1; + } + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + if (prev == -1) { + if (!(offs & (1 << 15))) { + prev = i; + continue; + } + FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); + offs += 1 << 15; + continue; + } + FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + offs += 2 << 15; + prev = -1; + } + + SLJIT_ASSERT(prev == -1); + + if (compiler->local_size > (63 * sizeof(sljit_sw))) { + /* The local_size is already adjusted by the saved registers. */ + if (local_size > 0xfff) { + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); + local_size &= 0xfff; + } + if (local_size) + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) + | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); + } + + if (args >= 1) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0))); + if (args >= 2) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1))); + if (args >= 3) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET; + local_size = (local_size + 15) & ~0xf; + compiler->local_size = local_size; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si local_size; + sljit_si i, tmp, offs, prev, saved_regs_size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + local_size = compiler->local_size; + + saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); + if (local_size <= (63 * sizeof(sljit_sw))) + offs = (local_size - saved_regs_size) << (15 - 3); + else { + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) + | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); + offs = 0 << 15; + if (saved_regs_size & 0x8) { + offs = 1 << 15; + saved_regs_size += sizeof(sljit_sw); + } + local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; + if (local_size > 0xfff) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); + local_size &= 0xfff; + } + if (local_size) + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + } + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + prev = -1; + for (i = SLJIT_S0; i >= tmp; i--) { + if (prev == -1) { + if (!(offs & (1 << 15))) { + prev = i; + continue; + } + FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); + offs += 1 << 15; + continue; + } + FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + offs += 2 << 15; + prev = -1; + } + + for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + if (prev == -1) { + if (!(offs & (1 << 15))) { + prev = i; + continue; + } + FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); + offs += 1 << 15; + continue; + } + FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + offs += 2 << 15; + prev = -1; + } + + SLJIT_ASSERT(prev == -1); + + if (compiler->local_size <= (63 * sizeof(sljit_sw))) { + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) + | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); + } else if (saved_regs_size > 0) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); + } + + FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, BRK); + case SLJIT_NOP: + return push_inst(compiler, NOP); + case SLJIT_LUMUL: + case SLJIT_LSMUL: + FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); + return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); + return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); + case SLJIT_UDIVI: + case SLJIT_SDIVI: + return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, flags, mem_flags; + sljit_si op_flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOV_UI: + flags = INT_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOV_SI: + flags = INT_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_P: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOVU_UI: + flags = INT_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOVU_SI: + flags = INT_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + break; + default: + SLJIT_ASSERT_STOP(); + flags = 0; + break; + } + + if (src & SLJIT_IMM) + FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); + } else { + if (dst_r != TMP_REG1) + return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); + dst_r = src; + } + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; + } + + flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op_flags & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + } + + if (src & SLJIT_IMM) { + flags |= ARG2_IMM; + if (op_flags & SLJIT_INT_OP) + srcw = (sljit_si)srcw; + } else + srcw = src; + + emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags, mem_flags; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + flags = GET_FLAGS(op) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + } + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); + + if (src1 & SLJIT_MEM) + src1 = TMP_REG1; + if (src2 & SLJIT_MEM) + src2 = TMP_REG2; + + if (src1 & SLJIT_IMM) + flags |= ARG1_IMM; + else + src1w = src1; + if (src2 & SLJIT_IMM) + flags |= ARG2_IMM; + else + src2w = src2; + + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + return push_inst(compiler, *(sljit_ins*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_ins ins_bits = (shift << 30); + sljit_si other_r; + sljit_sw diff; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (!(flags & STORE)) + ins_bits |= 1 << 22; + + if (arg & OFFS_REG_MASK) { + argw &= 3; + if (!argw || argw == shift) + return push_inst(compiler, STR_FR | ins_bits | VT(reg) + | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)); + other_r = OFFS_REG(arg); + arg &= REG_MASK; + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10))); + arg = TMP_REG1; + argw = 0; + } + + arg &= REG_MASK; + if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0) + return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift))); + + if (arg && argw <= 255 && argw >= -256) + return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12)); + + /* Slow cases */ + if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) { + diff = argw - compiler->cache_argw; + if (!arg && diff <= 255 && diff >= -256) + return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + } + } + + if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + } + + if (arg & REG_MASK) + return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3)); + return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONVI_FROMD) + inv_bits |= (1 << 31); + + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); + src = TMP_FREG1; + } + + FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src))); + + if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) + return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + inv_bits |= (1 << 31); + + if (src & SLJIT_MEM) { + emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); + src = TMP_REG1; + } else if (src & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + srcw = (sljit_si)srcw; +#endif + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) + FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); + break; + case SLJIT_DABS: + FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); + break; + case SLJIT_CONVD_FROMS: + FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_DSUB: + FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_DMUL: + FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_DDIV: + FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_LR, srcw)); + + return push_inst(compiler, RET | RN(TMP_LR)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + case SLJIT_MUL_NOT_OVERFLOW: + case SLJIT_D_EQUAL: + return 0x1; + + case SLJIT_NOT_EQUAL: + case SLJIT_MUL_OVERFLOW: + case SLJIT_D_NOT_EQUAL: + return 0x0; + + case SLJIT_LESS: + case SLJIT_D_LESS: + return 0x2; + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + return 0x3; + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + return 0x9; + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + return 0x8; + + case SLJIT_SIG_LESS: + return 0xa; + + case SLJIT_SIG_GREATER_EQUAL: + return 0xb; + + case SLJIT_SIG_GREATER: + return 0xd; + + case SLJIT_SIG_LESS_EQUAL: + return 0xc; + + case SLJIT_OVERFLOW: + case SLJIT_D_UNORDERED: + return 0x7; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_D_ORDERED: + return 0x6; + + default: + SLJIT_ASSERT_STOP(); + return 0xe; + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type < SLJIT_JUMP) { + jump->flags |= IS_COND; + PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type))); + } + else if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_BL; + + PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1))); + + return jump; +} + +static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type, + sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump; + sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0; + + SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); + ADJUST_LOCAL_OFFSET(src, srcw); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + jump->flags |= IS_CBZ | IS_COND; + + if (src & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw)); + src = TMP_REG1; + } + else if (src & SLJIT_IMM) { + PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + SLJIT_ASSERT(FAST_IS_REG(src)); + + if ((type & 0xff) == SLJIT_EQUAL) + inv_bits |= 1 << 24; + + PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src))); + PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1))); + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + /* In ARM, we don't need to touch the arguments. */ + if (!(src & SLJIT_IMM)) { + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw)); + src = TMP_REG1; + } + return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src)); + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); + jump->u.target = srcw; + + FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags, mem_flags; + sljit_ins cc; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + cc = get_cc(type & 0xff); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (GET_OPCODE(op) < SLJIT_ADD) { + FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO))); + if (dst_r != TMP_REG1) + return SLJIT_SUCCESS; + return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw); + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + flags = GET_FLAGS(op) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) + flags |= ARG1_IMM; + + FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO))); + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2); + + if (dst_r != TMP_REG1) + return SLJIT_SUCCESS; + return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins* inst = (sljit_ins*)addr; + modify_imm64_const(inst, new_addr); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins* inst = (sljit_ins*)addr; + modify_imm64_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} diff --git a/pcre2/src/sljit/sljitNativeARM_T2_32.c b/pcre2/src/sljit/sljitNativeARM_T2_32.c new file mode 100644 index 000000000..f9803f5d4 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -0,0 +1,2090 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "ARM-Thumb2" SLJIT_CPUINFO; +} + +/* Length of an instruction word. */ +typedef sljit_ui sljit_ins; + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5) + +#define TMP_FREG1 (0) +#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { + 0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15 +}; + +#define COPY_BITS(src, from, to, bits) \ + ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to)) + +/* Thumb16 encodings. */ +#define RD3(rd) (reg_map[rd]) +#define RN3(rn) (reg_map[rn] << 3) +#define RM3(rm) (reg_map[rm] << 6) +#define RDN3(rdn) (reg_map[rdn] << 8) +#define IMM3(imm) (imm << 6) +#define IMM8(imm) (imm) + +/* Thumb16 helpers. */ +#define SET_REGS44(rd, rn) \ + ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4)) +#define IS_2_LO_REGS(reg1, reg2) \ + (reg_map[reg1] <= 7 && reg_map[reg2] <= 7) +#define IS_3_LO_REGS(reg1, reg2, reg3) \ + (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) + +/* Thumb32 encodings. */ +#define RD4(rd) (reg_map[rd] << 8) +#define RN4(rn) (reg_map[rn] << 16) +#define RM4(rm) (reg_map[rm]) +#define RT4(rt) (reg_map[rt] << 12) +#define DD4(dd) ((dd) << 12) +#define DN4(dn) ((dn) << 16) +#define DM4(dm) (dm) +#define IMM5(imm) \ + (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6)) +#define IMM12(imm) \ + (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +/* dot '.' changed to _ + I immediate form (possibly followed by number of immediate bits). */ +#define ADCI 0xf1400000 +#define ADCS 0x4140 +#define ADC_W 0xeb400000 +#define ADD 0x4400 +#define ADDS 0x1800 +#define ADDSI3 0x1c00 +#define ADDSI8 0x3000 +#define ADD_W 0xeb000000 +#define ADDWI 0xf2000000 +#define ADD_SP 0xb000 +#define ADD_W 0xeb000000 +#define ADD_WI 0xf1000000 +#define ANDI 0xf0000000 +#define ANDS 0x4000 +#define AND_W 0xea000000 +#define ASRS 0x4100 +#define ASRSI 0x1000 +#define ASR_W 0xfa40f000 +#define ASR_WI 0xea4f0020 +#define BICI 0xf0200000 +#define BKPT 0xbe00 +#define BLX 0x4780 +#define BX 0x4700 +#define CLZ 0xfab0f080 +#define CMPI 0x2800 +#define CMP_W 0xebb00f00 +#define EORI 0xf0800000 +#define EORS 0x4040 +#define EOR_W 0xea800000 +#define IT 0xbf00 +#define LSLS 0x4080 +#define LSLSI 0x0000 +#define LSL_W 0xfa00f000 +#define LSL_WI 0xea4f0000 +#define LSRS 0x40c0 +#define LSRSI 0x0800 +#define LSR_W 0xfa20f000 +#define LSR_WI 0xea4f0010 +#define MOV 0x4600 +#define MOVS 0x0000 +#define MOVSI 0x2000 +#define MOVT 0xf2c00000 +#define MOVW 0xf2400000 +#define MOV_W 0xea4f0000 +#define MOV_WI 0xf04f0000 +#define MUL 0xfb00f000 +#define MVNS 0x43c0 +#define MVN_W 0xea6f0000 +#define MVN_WI 0xf06f0000 +#define NOP 0xbf00 +#define ORNI 0xf0600000 +#define ORRI 0xf0400000 +#define ORRS 0x4300 +#define ORR_W 0xea400000 +#define POP 0xbc00 +#define POP_W 0xe8bd0000 +#define PUSH 0xb400 +#define PUSH_W 0xe92d0000 +#define RSB_WI 0xf1c00000 +#define RSBSI 0x4240 +#define SBCI 0xf1600000 +#define SBCS 0x4180 +#define SBC_W 0xeb600000 +#define SMULL 0xfb800000 +#define STR_SP 0x9000 +#define SUBS 0x1a00 +#define SUBSI3 0x1e00 +#define SUBSI8 0x3800 +#define SUB_W 0xeba00000 +#define SUBWI 0xf2a00000 +#define SUB_SP 0xb080 +#define SUB_WI 0xf1a00000 +#define SXTB 0xb240 +#define SXTB_W 0xfa4ff080 +#define SXTH 0xb200 +#define SXTH_W 0xfa0ff080 +#define TST 0x4200 +#define UMULL 0xfba00000 +#define UXTB 0xb2c0 +#define UXTB_W 0xfa5ff080 +#define UXTH 0xb280 +#define UXTH_W 0xfa1ff080 +#define VABS_F32 0xeeb00ac0 +#define VADD_F32 0xee300a00 +#define VCMP_F32 0xeeb40a40 +#define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F64_F32 0xeeb70ac0 +#define VCVT_S32_F32 0xeebd0ac0 +#define VDIV_F32 0xee800a00 +#define VMOV_F32 0xeeb00a40 +#define VMOV 0xee000a10 +#define VMRS 0xeef1fa10 +#define VMUL_F32 0xee200a00 +#define VNEG_F32 0xeeb10a40 +#define VSTR_F32 0xed000a00 +#define VSUB_F32 0xee300a40 + +static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) +{ + sljit_uh *ptr; + SLJIT_ASSERT(!(inst & 0xffff0000)); + + ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); + FAIL_IF(!ptr); + *ptr = inst; + compiler->size++; + return SLJIT_SUCCESS; +} + +static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) +{ + sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr++ = inst >> 16; + *ptr = inst; + compiler->size += 2; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +{ + FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | + COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); + return push_inst32(compiler, MOVT | RD4(dst) | + COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); +} + +static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) +{ + sljit_si dst = inst[1] & 0x0f00; + SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); + inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); + inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); + inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1); + inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); +} + +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +{ + sljit_sw diff; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; + + if (jump->flags & JUMP_ADDR) { + /* Branch to ARM code is not optimized yet. */ + if (!(jump->u.target & 0x1)) + return 0; + diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; + } + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1; + } + + if (jump->flags & IS_COND) { + SLJIT_ASSERT(!(jump->flags & IS_BL)); + if (diff <= 127 && diff >= -128) { + jump->flags |= PATCH_TYPE1; + return 5; + } + if (diff <= 524287 && diff >= -524288) { + jump->flags |= PATCH_TYPE2; + return 4; + } + /* +1 comes from the prefix IT instruction. */ + diff--; + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_TYPE3; + return 3; + } + } + else if (jump->flags & IS_BL) { + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_BL; + return 3; + } + } + else { + if (diff <= 1023 && diff >= -1024) { + jump->flags |= PATCH_TYPE4; + return 4; + } + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_TYPE5; + return 3; + } + } + + return 0; +} + +static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) +{ + sljit_si type = (jump->flags >> 4) & 0xf; + sljit_sw diff; + sljit_uh *jump_inst; + sljit_si s, j1, j2; + + if (SLJIT_UNLIKELY(type == 0)) { + modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); + return; + } + + if (jump->flags & JUMP_ADDR) { + SLJIT_ASSERT(jump->u.target & 0x1); + diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; + } + else + diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; + jump_inst = (sljit_uh*)jump->addr; + + switch (type) { + case 1: + /* Encoding T1 of 'B' instruction */ + SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND)); + jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff); + return; + case 2: + /* Encoding T3 of 'B' instruction */ + SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND)); + jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1); + jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff); + return; + case 3: + SLJIT_ASSERT(jump->flags & IS_COND); + *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8; + diff--; + type = 5; + break; + case 4: + /* Encoding T2 of 'B' instruction */ + SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND)); + jump_inst[0] = 0xe000 | (diff & 0x7ff); + return; + } + + SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608); + + /* Really complex instruction form for branches. */ + s = (diff >> 23) & 0x1; + j1 = (~(diff >> 21) ^ s) & 0x1; + j2 = (~(diff >> 22) ^ s) & 0x1; + jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10); + jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff); + + /* The others have a common form. */ + if (type == 5) /* Encoding T4 of 'B' instruction */ + jump_inst[1] |= 0x9000; + else if (type == 6) /* Encoding T1 of 'BL' instruction */ + jump_inst[1] |= 0xd000; + else + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_uh *code; + sljit_uh *code_ptr; + sljit_uh *buf_ptr; + sljit_uh *buf_end; + sljit_uw half_count; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + half_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + + do { + buf_ptr = (sljit_uh*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 1); + do { + *code_ptr = *buf_ptr++; + /* These structures are ordered by their address. */ + SLJIT_ASSERT(!label || label->size >= half_count); + SLJIT_ASSERT(!jump || jump->addr >= half_count); + SLJIT_ASSERT(!const_ || const_->addr >= half_count); + if (label && label->size == half_count) { + label->addr = ((sljit_uw)code_ptr) | 0x1; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == half_count) { + jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); + code_ptr -= detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == half_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + half_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == half_count) { + label->addr = ((sljit_uw)code_ptr) | 0x1; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + + jump = compiler->jumps; + while (jump) { + set_jump_instruction(jump); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh); + SLJIT_CACHE_FLUSH(code, code_ptr); + /* Set thumb mode flag. */ + return (void*)((sljit_uw)code | 0x1); +} + +/* --------------------------------------------------------------------- */ +/* Core code generator functions. */ +/* --------------------------------------------------------------------- */ + +#define INVALID_IMM 0x80000000 +static sljit_uw get_imm(sljit_uw imm) +{ + /* Thumb immediate form. */ + sljit_si counter; + + if (imm <= 0xff) + return imm; + + if ((imm & 0xffff) == (imm >> 16)) { + /* Some special cases. */ + if (!(imm & 0xff00)) + return (1 << 12) | (imm & 0xff); + if (!(imm & 0xff)) + return (2 << 12) | ((imm >> 8) & 0xff); + if ((imm & 0xff00) == ((imm & 0xff) << 8)) + return (3 << 12) | (imm & 0xff); + } + + /* Assembly optimization: count leading zeroes? */ + counter = 8; + if (!(imm & 0xffff0000)) { + counter += 16; + imm <<= 16; + } + if (!(imm & 0xff000000)) { + counter += 8; + imm <<= 8; + } + if (!(imm & 0xf0000000)) { + counter += 4; + imm <<= 4; + } + if (!(imm & 0xc0000000)) { + counter += 2; + imm <<= 2; + } + if (!(imm & 0x80000000)) { + counter += 1; + imm <<= 1; + } + /* Since imm >= 128, this must be true. */ + SLJIT_ASSERT(counter <= 31); + + if (imm & 0x00ffffff) + return INVALID_IMM; /* Cannot be encoded. */ + + return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); +} + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +{ + sljit_uw tmp; + + if (imm >= 0x10000) { + tmp = get_imm(imm); + if (tmp != INVALID_IMM) + return push_inst32(compiler, MOV_WI | RD4(dst) | tmp); + tmp = get_imm(~imm); + if (tmp != INVALID_IMM) + return push_inst32(compiler, MVN_WI | RD4(dst) | tmp); + } + + /* set low 16 bits, set hi 16 bits to 0. */ + FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | + COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); + + /* set hi 16 bit if needed. */ + if (imm >= 0x10000) + return push_inst32(compiler, MOVT | RD4(dst) | + COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); + return SLJIT_SUCCESS; +} + +#define ARG1_IMM 0x0010000 +#define ARG2_IMM 0x0020000 +#define KEEP_FLAGS 0x0040000 +/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */ +#define SET_FLAGS 0x0100000 +#define UNUSED_RETURN 0x0200000 +#define SLOW_DEST 0x0400000 +#define SLOW_SRC1 0x0800000 +#define SLOW_SRC2 0x1000000 + +static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2) +{ + /* dst must be register, TMP_REG1 + arg1 must be register, TMP_REG1, imm + arg2 must be register, TMP_REG2, imm */ + sljit_si reg; + sljit_uw imm, nimm; + + if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { + /* Both are immediates. */ + flags &= ~ARG1_IMM; + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + + if (flags & (ARG1_IMM | ARG2_IMM)) { + reg = (flags & ARG2_IMM) ? arg1 : arg2; + imm = (flags & ARG2_IMM) ? arg2 : arg1; + + switch (flags & 0xffff) { + case SLJIT_CLZ: + case SLJIT_MUL: + /* No form with immediate operand. */ + break; + case SLJIT_MOV: + SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); + return load_immediate(compiler, dst, imm); + case SLJIT_NOT: + if (!(flags & SET_FLAGS)) + return load_immediate(compiler, dst, ~imm); + /* Since the flags should be set, we just fallback to the register mode. + Although some clever things could be done here, "NOT IMM" does not worth the efforts. */ + break; + case SLJIT_ADD: + nimm = -imm; + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { + if (imm <= 0x7) + return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); + if (nimm <= 0x7) + return push_inst16(compiler, SUBSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst)); + if (nimm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(nimm) | RDN3(dst)); + } + } + if (!(flags & SET_FLAGS)) { + if (imm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm)); + if (nimm <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm)); + } + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_ADDC: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SUB: + if (flags & ARG1_IMM) { + if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst)) + return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg)); + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + } + nimm = -imm; + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { + if (imm <= 0x7) + return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); + if (nimm <= 0x7) + return push_inst16(compiler, ADDSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst)); + if (nimm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(nimm) | RDN3(dst)); + } + if (imm <= 0xff && (flags & UNUSED_RETURN)) + return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg)); + } + if (!(flags & SET_FLAGS)) { + if (imm <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm)); + if (nimm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm)); + } + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SUBC: + if (flags & ARG1_IMM) + break; + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_AND: + nimm = get_imm(imm); + if (nimm != INVALID_IMM) + return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_OR: + nimm = get_imm(imm); + if (nimm != INVALID_IMM) + return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_XOR: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (flags & ARG1_IMM) + break; + imm &= 0x1f; + if (imm == 0) { + if (!(flags & SET_FLAGS)) + return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); + } + switch (flags & 0xffff) { + case SLJIT_SHL: + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + case SLJIT_LSHR: + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + default: /* SLJIT_ASHR */ + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + } + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (flags & ARG2_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); + arg2 = TMP_REG2; + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + } + + /* Both arguments are registers. */ + switch (flags & 0xffff) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (dst == arg2) + return SLJIT_SUCCESS; + return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); + case SLJIT_MOV_UB: + case SLJIT_MOVU_UB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_SB: + case SLJIT_MOVU_SB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_UH: + case SLJIT_MOVU_UH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_SH: + case SLJIT_MOVU_SH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); + case SLJIT_NOT: + SLJIT_ASSERT(arg1 == TMP_REG1); + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); + case SLJIT_CLZ: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2))); + if (flags & SET_FLAGS) { + if (reg_map[dst] <= 7) + return push_inst16(compiler, CMPI | RDN3(dst)); + return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst)); + } + return SLJIT_SUCCESS; + case SLJIT_ADD: + if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) + return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2)); + if (dst == arg1 && !(flags & SET_FLAGS)) + return push_inst16(compiler, ADD | SET_REGS44(dst, arg2)); + return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_ADDC: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SUB: + if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) + return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2)); + return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SUBC: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_MUL: + if (!(flags & SET_FLAGS)) + return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2)); + SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2); + FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2))); + /* cmp TMP_REG2, dst asr #31. */ + return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst)); + case SLJIT_AND: + if (!(flags & KEEP_FLAGS)) { + if (dst == arg1 && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2)); + if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2)) + return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2)); + } + return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_OR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_XOR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SHL: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_LSHR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_ASHR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +#define STORE 0x01 +#define SIGNED 0x02 + +#define WORD_SIZE 0x00 +#define BYTE_SIZE 0x04 +#define HALF_SIZE 0x08 + +#define UPDATE 0x10 +#define ARG_TEST 0x20 + +#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE))) +#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift))) + +/* + 1st letter: + w = word + b = byte + h = half + + 2nd letter: + s = signed + u = unsigned + + 3rd letter: + l = load + s = store +*/ + +static SLJIT_CONST sljit_ins sljit_mem16[12] = { +/* w u l */ 0x5800 /* ldr */, +/* w u s */ 0x5000 /* str */, +/* w s l */ 0x5800 /* ldr */, +/* w s s */ 0x5000 /* str */, + +/* b u l */ 0x5c00 /* ldrb */, +/* b u s */ 0x5400 /* strb */, +/* b s l */ 0x5600 /* ldrsb */, +/* b s s */ 0x5400 /* strb */, + +/* h u l */ 0x5a00 /* ldrh */, +/* h u s */ 0x5200 /* strh */, +/* h s l */ 0x5e00 /* ldrsh */, +/* h s s */ 0x5200 /* strh */, +}; + +static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { +/* w u l */ 0x6800 /* ldr imm5 */, +/* w u s */ 0x6000 /* str imm5 */, +/* w s l */ 0x6800 /* ldr imm5 */, +/* w s s */ 0x6000 /* str imm5 */, + +/* b u l */ 0x7800 /* ldrb imm5 */, +/* b u s */ 0x7000 /* strb imm5 */, +/* b s l */ 0x0000 /* not allowed */, +/* b s s */ 0x7000 /* strb imm5 */, + +/* h u l */ 0x8800 /* ldrh imm5 */, +/* h u s */ 0x8000 /* strh imm5 */, +/* h s l */ 0x0000 /* not allowed */, +/* h s s */ 0x8000 /* strh imm5 */, +}; + +#define MEM_IMM8 0xc00 +#define MEM_IMM12 0x800000 +static SLJIT_CONST sljit_ins sljit_mem32[12] = { +/* w u l */ 0xf8500000 /* ldr.w */, +/* w u s */ 0xf8400000 /* str.w */, +/* w s l */ 0xf8500000 /* ldr.w */, +/* w s s */ 0xf8400000 /* str.w */, + +/* b u l */ 0xf8100000 /* ldrb.w */, +/* b u s */ 0xf8000000 /* strb.w */, +/* b s l */ 0xf9100000 /* ldrsb.w */, +/* b s s */ 0xf8000000 /* strb.w */, + +/* h u l */ 0xf8300000 /* ldrh.w */, +/* h u s */ 0xf8200000 /* strsh.w */, +/* h s l */ 0xf9300000 /* ldrsh.w */, +/* h s s */ 0xf8200000 /* strsh.w */, +}; + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + if (value <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value)); + value = get_imm(value); + if (value != INVALID_IMM) + return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value); + } + else { + value = -value; + if (value <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value)); + value = get_imm(value); + if (value != INVALID_IMM) + return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_si other_r, shift; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 0xff && argw >= -0xff) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + flags &= ~UPDATE; + arg &= 0xf; + if (argw >= 0) + argw |= 0x200; + else { + argw = -argw; + } + + SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff); + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw)); + return -1; + } + return 0; + } + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + argw &= 0x3; + other_r = OFFS_REG(arg); + arg &= 0xf; + + if (!argw && IS_3_LO_REGS(reg, arg, other_r)) + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); + else + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); + return -1; + } + + if (!(arg & REG_MASK) || argw > 0xfff || argw < -0xff) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + arg &= 0xf; + if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) { + shift = 3; + if (IS_WORD_SIZE(flags)) { + if (OFFSET_CHECK(0x1f, 2)) + shift = 2; + } + else if (flags & BYTE_SIZE) + { + if (OFFSET_CHECK(0x1f, 0)) + shift = 0; + } + else { + SLJIT_ASSERT(flags & HALF_SIZE); + if (OFFSET_CHECK(0x1f, 1)) + shift = 1; + } + + if (shift != 3) { + FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift)))); + return -1; + } + } + + /* SP based immediate. */ + if (SLJIT_UNLIKELY(arg == SLJIT_SP) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) { + FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2))); + return -1; + } + + if (argw >= 0) + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); + else + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw)); + return -1; +} + +/* see getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_sw diff; + if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) + return 0; + + if (!(arg & REG_MASK)) { + diff = argw - next_argw; + if (diff <= 0xfff && diff >= -0xfff) + return 1; + return 0; + } + + if (argw == next_argw) + return 1; + + diff = argw - next_argw; + if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) + return 1; + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, + sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r, other_r; + sljit_sw diff; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + tmp_r = (flags & STORE) ? TMP_REG3 : reg; + + if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) { + /* Update only applies if a base register exists. */ + /* There is no caching here. */ + other_r = OFFS_REG(arg); + arg &= 0xf; + flags &= ~UPDATE; + + if (!other_r) { + if (!(argw & ~0xfff)) { + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); + return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw)); + } + + if (compiler->cache_arg == SLJIT_MEM) { + if (argw == compiler->cache_argw) { + other_r = TMP_REG3; + argw = 0; + } + else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + if (argw) { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + argw &= 0x3; + if (!argw && IS_3_LO_REGS(reg, arg, other_r)) { + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); + return push_inst16(compiler, ADD | SET_REGS44(arg, other_r)); + } + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); + return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(other_r) | (argw << 6)); + } + flags &= ~UPDATE; + + SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); + + if (compiler->cache_arg == arg) { + diff = argw - compiler->cache_argw; + if (!(diff & ~0xfff)) + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | diff); + if (!((compiler->cache_argw - argw) & ~0xff)) + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); + } + } + + next_arg = (arg & REG_MASK) && (arg == next_arg) && (argw != next_argw); + arg &= 0xf; + if (arg && compiler->cache_arg == SLJIT_MEM) { + if (compiler->cache_argw == argw) + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + } + } + + compiler->cache_argw = argw; + if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + + diff = argw - next_argw; + if (next_arg && diff <= 0xfff && diff >= -0xfff) { + FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg))); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + } + + if (arg) + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si size, i, tmp; + sljit_ins push; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + push = (1 << 4); + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) + push |= 1 << reg_map[i]; + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) + push |= 1 << reg_map[i]; + + FAIL_IF((push & 0xff00) + ? push_inst32(compiler, PUSH_W | (1 << 14) | push) + : push_inst16(compiler, PUSH | (1 << 8) | push)); + + /* Stack must be aligned to 8 bytes: (LR, R4) */ + size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); + local_size = ((size + local_size + 7) & ~7) - size; + compiler->local_size = local_size; + if (local_size > 0) { + if (local_size <= (127 << 2)) + FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2))); + else + FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size)); + } + + if (args >= 1) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0))); + if (args >= 2) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S1, SLJIT_R1))); + if (args >= 3) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); + compiler->local_size = ((size + local_size + 7) & ~7) - size; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si i, tmp; + sljit_ins pop; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size > 0) { + if (compiler->local_size <= (127 << 2)) + FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2))); + else + FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size)); + } + + pop = (1 << 4); + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) + pop |= 1 << reg_map[i]; + + for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) + pop |= 1 << reg_map[i]; + + return (pop & 0xff00) + ? push_inst32(compiler, POP_W | (1 << 15) | pop) + : push_inst16(compiler, POP | (1 << 8) | pop); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + sljit_sw saved_reg_list[3]; + sljit_sw saved_reg_count; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst16(compiler, BKPT); + case SLJIT_NOP: + return push_inst16(compiler, NOP); + case SLJIT_LUMUL: + case SLJIT_LSMUL: + return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + | (reg_map[SLJIT_R1] << 8) + | (reg_map[SLJIT_R0] << 12) + | (reg_map[SLJIT_R0] << 16) + | reg_map[SLJIT_R1]); + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping); + + saved_reg_count = 0; + if (compiler->scratches >= 4) + saved_reg_list[saved_reg_count++] = 12; + if (compiler->scratches >= 3) + saved_reg_list[saved_reg_count++] = 2; + if (op >= SLJIT_UDIVI) + saved_reg_list[saved_reg_count++] = 1; + + if (saved_reg_count > 0) { + FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8) + | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */)); + if (saved_reg_count >= 2) { + SLJIT_ASSERT(saved_reg_list[1] < 8); + FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */)); + } + if (saved_reg_count >= 3) { + SLJIT_ASSERT(saved_reg_list[2] < 8); + FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */)); + } + } + +#if defined(__GNUC__) + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, + ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); +#else +#error "Software divmod functions are needed" +#endif + + if (saved_reg_count > 0) { + if (saved_reg_count >= 3) { + SLJIT_ASSERT(saved_reg_list[2] < 8); + FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */)); + } + if (saved_reg_count >= 2) { + SLJIT_ASSERT(saved_reg_list[1] < 8); + FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */)); + } + return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8) + | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); + } + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, flags; + sljit_si op_flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + default: + SLJIT_ASSERT_STOP(); + flags = 0; + break; + } + + if (src & SLJIT_IMM) + FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); + } else { + if (dst_r != TMP_REG1) + return emit_op_imm(compiler, op, dst_r, TMP_REG1, src); + dst_r = src; + } + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; + } + + if (op == SLJIT_NEG) { +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); + if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + } + + if (src & SLJIT_IMM) + flags |= ARG2_IMM; + else + srcw = src; + + emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); + + if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + } + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); + + if (src1 & SLJIT_MEM) + src1 = TMP_REG1; + if (src2 & SLJIT_MEM) + src2 = TMP_REG2; + + if (src1 & SLJIT_IMM) + flags |= ARG1_IMM; + else + src1w = src1; + if (src2 & SLJIT_IMM) + flags |= ARG2_IMM; + else + src2w = src2; + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg << 1; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + if (size == 2) + return push_inst16(compiler, *(sljit_uh*)instruction); + return push_inst32(compiler, *(sljit_ins*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +#define FPU_LOAD (1 << 20) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6))); + arg = SLJIT_MEM | TMP_REG2; + argw = 0; + } + + if ((arg & REG_MASK) && (argw & 0x3) == 0) { + if (!(argw & ~0x3fc)) + return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2)); + } + + /* Slow cases */ + SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); + if (compiler->cache_arg == arg) { + tmp = argw - compiler->cache_argw; + if (!(tmp & ~0x3fc)) + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2)); + if (!(-tmp & ~0x3fc)) + return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); + } + } + + if (arg & REG_MASK) { + if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + } + imm = get_imm(argw & ~0x3fc); + if (imm != INVALID_IMM) { + FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm != INVALID_IMM) { + argw = -argw; + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); + return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + if (arg & REG_MASK) + FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & REG_MASK)))); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + src = TMP_FREG1; + } + + FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src))); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1)); + + /* Store the integer value from a VFP register. */ + return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); + else if (src & SLJIT_MEM) { + /* Load the integer value into a VFP register. */ + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); + } + + FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1))); + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2))); + return push_inst32(compiler, VMRS); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) + op ^= SLJIT_SINGLE_OP; + + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_DABS: + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_CONVD_FROMS: + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + op ^= SLJIT_SINGLE_OP; + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_DSUB: + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_DMUL: + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_DDIV: + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); +} + +#undef FPU_LOAD + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) + FAIL_IF(compiler->error); + else { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0)); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2))); + } + } + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); + return push_inst16(compiler, BLX | RN3(TMP_REG3)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + case SLJIT_MUL_NOT_OVERFLOW: + case SLJIT_D_EQUAL: + return 0x0; + + case SLJIT_NOT_EQUAL: + case SLJIT_MUL_OVERFLOW: + case SLJIT_D_NOT_EQUAL: + return 0x1; + + case SLJIT_LESS: + case SLJIT_D_LESS: + return 0x3; + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + return 0x2; + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + return 0x8; + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + return 0x9; + + case SLJIT_SIG_LESS: + return 0xb; + + case SLJIT_SIG_GREATER_EQUAL: + return 0xa; + + case SLJIT_SIG_GREATER: + return 0xc; + + case SLJIT_SIG_LESS_EQUAL: + return 0xd; + + case SLJIT_OVERFLOW: + case SLJIT_D_UNORDERED: + return 0x6; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_D_ORDERED: + return 0x7; + + default: /* SLJIT_JUMP */ + SLJIT_ASSERT_STOP(); + return 0xe; + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins cc; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In ARM, we don't need to touch the arguments. */ + PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); + if (type < SLJIT_JUMP) { + jump->flags |= IS_COND; + cc = get_cc(type); + jump->flags |= cc << 8; + PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + } + + jump->addr = compiler->size; + if (type <= SLJIT_JUMP) + PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1))); + else { + jump->flags |= IS_BL; + PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1))); + } + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + /* In ARM, we don't need to touch the arguments. */ + if (!(src & SLJIT_IMM)) { + if (FAST_IS_REG(src)) + return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); + + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw)); + if (type >= SLJIT_FAST_CALL) + return push_inst16(compiler, BLX | RN3(TMP_REG1)); + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); + jump->u.target = srcw; + + FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_ins cc, ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type & 0xff); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + if (reg_map[dst_r] > 7) { + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); + } else { + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); + } + if (dst_r != TMP_REG2) + return SLJIT_SUCCESS; + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); + } + + ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { + /* Does not change the other bits. */ + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORRI/EORI is not executed above. */ + if (reg_map[dst] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); + } + return SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); + src = TMP_REG2; + srcw = 0; + } + + if (op == SLJIT_AND || src != dst_r) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); + } + else { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + } + + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); + + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORR/EORI is not executed above. */ + if (reg_map[dst_r] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_uh *inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_addr); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_uh *inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} diff --git a/pcre2/src/sljit/sljitNativeMIPS_32.c b/pcre2/src/sljit/sljitNativeMIPS_32.c new file mode 100644 index 000000000..b2b60d7a4 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -0,0 +1,366 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* mips 32-bit arch dependent functions. */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +{ + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + if (imm < 0 && imm >= SIMM_MIN) + return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); + return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; +} + +#define EMIT_LOGICAL(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ + } \ + else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ + } + +#define EMIT_SHIFT(op_imm, op_v) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ + } \ + else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \ + } + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) { +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) { +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); +#else + if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { + FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); + return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); + } + /* Nearly all instructions are unmovable in the following sequence. */ + FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + /* Check zero. */ + FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst))); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); + if (op & SLJIT_SET_E) + return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); +#endif + return SLJIT_SUCCESS; + + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + else { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + } + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); + } + else { + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + case SLJIT_ADDC: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + else { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + } + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); + } else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); + } + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + + FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + /* Set carry flag. */ + return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + if (op & SLJIT_SET_U) + FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); + if (op & SLJIT_SET_S) { + FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); + FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + case SLJIT_SUBC: + if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); + + FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; + + case SLJIT_MUL: + SLJIT_ASSERT(!(flags & SRC2_IMM)); + if (!(op & SLJIT_SET_O)) { +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#endif + } + FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); + return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); + + case SLJIT_AND: + EMIT_LOGICAL(ANDI, AND); + return SLJIT_SUCCESS; + + case SLJIT_OR: + EMIT_LOGICAL(ORI, OR); + return SLJIT_SUCCESS; + + case SLJIT_XOR: + EMIT_LOGICAL(XORI, XOR); + return SLJIT_SUCCESS; + + case SLJIT_SHL: + EMIT_SHIFT(SLL, SLLV); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(SRL, SRLV); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(SRA, SRAV); + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); + return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff --git a/pcre2/src/sljit/sljitNativeMIPS_64.c b/pcre2/src/sljit/sljitNativeMIPS_64.c new file mode 100644 index 000000000..185fb5768 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -0,0 +1,469 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* mips 64-bit arch dependent functions. */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +{ + sljit_si shift = 32; + sljit_si shift2; + sljit_si inv = 0; + sljit_ins ins; + sljit_uw uimm; + + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + if (imm < 0 && imm >= SIMM_MIN) + return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + if (imm <= 0x7fffffffl && imm >= -0x80000000l) { + FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); + return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; + } + + /* Zero extended number. */ + uimm = imm; + if (imm < 0) { + uimm = ~imm; + inv = 1; + } + + while (!(uimm & 0xff00000000000000l)) { + shift -= 8; + uimm <<= 8; + } + + if (!(uimm & 0xf000000000000000l)) { + shift -= 4; + uimm <<= 4; + } + + if (!(uimm & 0xc000000000000000l)) { + shift -= 2; + uimm <<= 2; + } + + if ((sljit_sw)uimm < 0) { + uimm >>= 1; + shift += 1; + } + SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32)); + + if (inv) + uimm = ~uimm; + + FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); + if (uimm & 0x0000ffff00000000l) + FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar)); + + imm &= (1l << shift) - 1; + if (!(imm & ~0xffff)) { + ins = (shift == 32) ? DSLL32 : DSLL; + if (shift < 32) + ins |= SH_IMM(shift); + FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar)); + return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); + } + + /* Double shifts needs to be performed. */ + uimm <<= 32; + shift2 = shift - 16; + + while (!(uimm & 0xf000000000000000l)) { + shift2 -= 4; + uimm <<= 4; + } + + if (!(uimm & 0xc000000000000000l)) { + shift2 -= 2; + uimm <<= 2; + } + + if (!(uimm & 0x8000000000000000l)) { + shift2--; + uimm <<= 1; + } + + SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16)); + + FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar)); + FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); + FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar)); + + imm &= (1l << shift2) - 1; + return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); +} + +#define SELECT_OP(a, b) \ + (!(op & SLJIT_INT_OP) ? a : b) + +#define EMIT_LOGICAL(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ + } \ + else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ + } + +#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ + if (flags & SRC2_IMM) { \ + if (src2 >= 32) { \ + SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ + ins = op_dimm32; \ + src2 -= 32; \ + } \ + else \ + ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ + } \ + else { \ + ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ + } + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + sljit_ins ins; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); + return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + SLJIT_ASSERT(!(op & SLJIT_INT_OP)); + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); + return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); + + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); +#else + if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); + return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); + } + /* Nearly all instructions are unmovable in the following sequence. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + /* Check zero. */ + FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); + if (op & SLJIT_SET_E) + return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); +#endif + return SLJIT_SUCCESS; + + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + else { + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + } + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); + } + else { + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + case SLJIT_ADDC: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + else { + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + } + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); + } else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + /* Set carry flag. */ + return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + if (op & SLJIT_SET_U) + FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); + if (op & SLJIT_SET_S) { + FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); + FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + case SLJIT_SUBC: + if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); + + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; + + case SLJIT_MUL: + SLJIT_ASSERT(!(flags & SRC2_IMM)); + if (!(op & SLJIT_SET_O)) { +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + if (op & SLJIT_INT_OP) + return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); + FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#endif + } + FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); + return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); + + case SLJIT_AND: + EMIT_LOGICAL(ANDI, AND); + return SLJIT_SUCCESS; + + case SLJIT_OR: + EMIT_LOGICAL(ORI, OR); + return SLJIT_SUCCESS; + + case SLJIT_XOR: + EMIT_LOGICAL(XORI, XOR); + return SLJIT_SUCCESS; + + case SLJIT_SHL: + EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV); + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 6); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 6); +} diff --git a/pcre2/src/sljit/sljitNativeMIPS_common.c b/pcre2/src/sljit/sljitNativeMIPS_common.c new file mode 100644 index 000000000..cf3535f81 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -0,0 +1,2138 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Latest MIPS architecture. */ +/* Automatically detect SLJIT_MIPS_R1 */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return "MIPS32-R1" SLJIT_CPUINFO; +#else + return "MIPS64-R1" SLJIT_CPUINFO; +#endif +#else /* SLJIT_MIPS_R1 */ + return "MIPS III" SLJIT_CPUINFO; +#endif +} + +/* Length of an instruction word + Both for mips-32 and mips-64 */ +typedef sljit_ui sljit_ins; + +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) + +/* For position independent code, t9 must contain the function address. */ +#define PIC_ADDR_REG TMP_REG2 + +/* Floating point status register. */ +#define FCSR_REG 31 +/* Return address register. */ +#define RETURN_ADDR_REG 31 + +/* Flags are kept in volatile registers. */ +#define EQUAL_FLAG 12 +/* And carry flag as well. */ +#define ULESS_FLAG 13 +#define UGREATER_FLAG 14 +#define LESS_FLAG 15 +#define GREATER_FLAG 31 +#define OVERFLOW_FLAG 1 + +#define TMP_FREG1 (0) +#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4 +}; + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define S(s) (reg_map[s] << 21) +#define T(t) (reg_map[t] << 16) +#define D(d) (reg_map[d] << 11) +/* Absolute registers. */ +#define SA(s) ((s) << 21) +#define TA(t) ((t) << 16) +#define DA(d) ((d) << 11) +#define FT(t) ((t) << 16) +#define FS(s) ((s) << 11) +#define FD(d) ((d) << 6) +#define IMM(imm) ((imm) & 0xffff) +#define SH_IMM(imm) ((imm) << 6) + +#define DR(dr) (reg_map[dr]) +#define HI(opcode) ((opcode) << 26) +#define LO(opcode) (opcode) +/* S = (16 << 21) D = (17 << 21) */ +#define FMT_S (16 << 21) + +#define ABS_S (HI(17) | FMT_S | LO(5)) +#define ADD_S (HI(17) | FMT_S | LO(0)) +#define ADDIU (HI(9)) +#define ADDU (HI(0) | LO(33)) +#define AND (HI(0) | LO(36)) +#define ANDI (HI(12)) +#define B (HI(4)) +#define BAL (HI(1) | (17 << 16)) +#define BC1F (HI(17) | (8 << 21)) +#define BC1T (HI(17) | (8 << 21) | (1 << 16)) +#define BEQ (HI(4)) +#define BGEZ (HI(1) | (1 << 16)) +#define BGTZ (HI(7)) +#define BLEZ (HI(6)) +#define BLTZ (HI(1) | (0 << 16)) +#define BNE (HI(5)) +#define BREAK (HI(0) | LO(13)) +#define CFC1 (HI(17) | (2 << 21)) +#define C_UN_S (HI(17) | FMT_S | LO(49)) +#define C_UEQ_S (HI(17) | FMT_S | LO(51)) +#define C_ULE_S (HI(17) | FMT_S | LO(55)) +#define C_ULT_S (HI(17) | FMT_S | LO(53)) +#define CVT_S_S (HI(17) | FMT_S | LO(32)) +#define DADDIU (HI(25)) +#define DADDU (HI(0) | LO(45)) +#define DDIV (HI(0) | LO(30)) +#define DDIVU (HI(0) | LO(31)) +#define DIV (HI(0) | LO(26)) +#define DIVU (HI(0) | LO(27)) +#define DIV_S (HI(17) | FMT_S | LO(3)) +#define DMULT (HI(0) | LO(28)) +#define DMULTU (HI(0) | LO(29)) +#define DSLL (HI(0) | LO(56)) +#define DSLL32 (HI(0) | LO(60)) +#define DSLLV (HI(0) | LO(20)) +#define DSRA (HI(0) | LO(59)) +#define DSRA32 (HI(0) | LO(63)) +#define DSRAV (HI(0) | LO(23)) +#define DSRL (HI(0) | LO(58)) +#define DSRL32 (HI(0) | LO(62)) +#define DSRLV (HI(0) | LO(22)) +#define DSUBU (HI(0) | LO(47)) +#define J (HI(2)) +#define JAL (HI(3)) +#define JALR (HI(0) | LO(9)) +#define JR (HI(0) | LO(8)) +#define LD (HI(55)) +#define LUI (HI(15)) +#define LW (HI(35)) +#define MFC1 (HI(17)) +#define MFHI (HI(0) | LO(16)) +#define MFLO (HI(0) | LO(18)) +#define MOV_S (HI(17) | FMT_S | LO(6)) +#define MTC1 (HI(17) | (4 << 21)) +#define MUL_S (HI(17) | FMT_S | LO(2)) +#define MULT (HI(0) | LO(24)) +#define MULTU (HI(0) | LO(25)) +#define NEG_S (HI(17) | FMT_S | LO(7)) +#define NOP (HI(0) | LO(0)) +#define NOR (HI(0) | LO(39)) +#define OR (HI(0) | LO(37)) +#define ORI (HI(13)) +#define SD (HI(63)) +#define SLT (HI(0) | LO(42)) +#define SLTI (HI(10)) +#define SLTIU (HI(11)) +#define SLTU (HI(0) | LO(43)) +#define SLL (HI(0) | LO(0)) +#define SLLV (HI(0) | LO(4)) +#define SRL (HI(0) | LO(2)) +#define SRLV (HI(0) | LO(6)) +#define SRA (HI(0) | LO(3)) +#define SRAV (HI(0) | LO(7)) +#define SUB_S (HI(17) | FMT_S | LO(1)) +#define SUBU (HI(0) | LO(35)) +#define SW (HI(43)) +#define TRUNC_W_S (HI(17) | FMT_S | LO(13)) +#define XOR (HI(0) | LO(38)) +#define XORI (HI(14)) + +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#define CLZ (HI(28) | LO(32)) +#define DCLZ (HI(28) | LO(36)) +#define MUL (HI(28) | LO(2)) +#define SEB (HI(31) | (16 << 6) | LO(32)) +#define SEH (HI(31) | (24 << 6) | LO(32)) +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define ADDU_W ADDU +#define ADDIU_W ADDIU +#define SLL_W SLL +#define SUBU_W SUBU +#else +#define ADDU_W DADDU +#define ADDIU_W DADDIU +#define SLL_W DSLL +#define SUBU_W DSUBU +#endif + +#define SIMM_MAX (0x7fff) +#define SIMM_MIN (-0x8000) +#define UIMM_MAX (0xffff) + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +{ + SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS + || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + compiler->delay_slot = delay_slot; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_ins invert_branch(sljit_si flags) +{ + return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); +} + +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + sljit_ins *inst; + sljit_ins saved_inst; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) + return code_ptr; +#else + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return code_ptr; +#endif + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + inst = (sljit_ins*)jump->addr; + if (jump->flags & IS_COND) + inst--; + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (jump->flags & IS_CALL) + goto keep_address; +#endif + + /* B instructions. */ + if (jump->flags & IS_MOVABLE) { + diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + if (diff <= SIMM_MAX && diff >= SIMM_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + inst[0] = inst[-1]; + inst[-1] = (jump->flags & IS_JAL) ? BAL : B; + jump->addr -= sizeof(sljit_ins); + return inst; + } + saved_inst = inst[0]; + inst[0] = inst[-1]; + inst[-1] = saved_inst ^ invert_branch(jump->flags); + jump->addr -= 2 * sizeof(sljit_ins); + return inst; + } + } + else { + diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2; + if (diff <= SIMM_MAX && diff >= SIMM_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + inst[0] = (jump->flags & IS_JAL) ? BAL : B; + inst[1] = NOP; + return inst + 1; + } + inst[0] = inst[0] ^ invert_branch(jump->flags); + inst[1] = NOP; + jump->addr -= sizeof(sljit_ins); + return inst + 1; + } + } + + if (jump->flags & IS_COND) { + if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + saved_inst = inst[0]; + inst[0] = inst[-1]; + inst[-1] = (saved_inst & 0xffff0000) | 3; + inst[1] = J; + inst[2] = NOP; + return inst + 2; + } + else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = (inst[0] & 0xffff0000) | 3; + inst[1] = NOP; + inst[2] = J; + inst[3] = NOP; + jump->addr += sizeof(sljit_ins); + return inst + 3; + } + } + else { + /* J instuctions. */ + if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = inst[-1]; + inst[-1] = (jump->flags & IS_JAL) ? JAL : J; + jump->addr -= sizeof(sljit_ins); + return inst; + } + + if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = (jump->flags & IS_JAL) ? JAL : J; + inst[1] = NOP; + return inst + 1; + } + } + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +keep_address: + if (target_addr <= 0x7fffffff) { + jump->flags |= PATCH_ABS32; + if (jump->flags & IS_COND) { + inst[0] -= 4; + inst++; + } + inst[2] = inst[6]; + inst[3] = inst[7]; + return inst + 3; + } + if (target_addr <= 0x7fffffffffffl) { + jump->flags |= PATCH_ABS48; + if (jump->flags & IS_COND) { + inst[0] -= 2; + inst++; + } + inst[4] = inst[6]; + inst[5] = inst[7]; + return inst + 5; + } +#endif + + return code_ptr; +} + +#ifdef __GNUC__ +static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr) +{ + SLJIT_CACHE_FLUSH(code, code_ptr); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + jump->addr = (sljit_uw)(code_ptr - 3); +#else + jump->addr = (sljit_uw)(code_ptr - 7); +#endif + code_ptr = detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + + if (jump->flags & PATCH_B) { + addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); + break; + } + if (jump->flags & PATCH_J) { + SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); + buf_ptr[0] |= (addr >> 2) & 0x03ffffff; + break; + } + + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); +#else + if (jump->flags & PATCH_ABS32) { + SLJIT_ASSERT(addr <= 0x7fffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); + } + else if (jump->flags & PATCH_ABS48) { + SLJIT_ASSERT(addr <= 0x7fffffffffffl); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); + } + else { + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff); + } +#endif + } while (0); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); +#ifndef __GNUC__ + SLJIT_CACHE_FLUSH(code, code_ptr); +#else + /* GCC workaround for invalid code generation with -O2. */ + sljit_cache_flush(code, code_ptr); +#endif + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +/* Separates integer and floating point registers */ +#define GPR_REG 0x0f +#define DOUBLE_DATA 0x10 +#define SINGLE_DATA 0x12 + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define LOGICAL_OP 0x00200 +#define IMM_OP 0x00400 +#define SRC2_IMM 0x00800 + +#define UNUSED_DEST 0x01000 +#define REG_DEST 0x02000 +#define REG1_SOURCE 0x04000 +#define REG2_SOURCE 0x08000 +#define SLOW_SRC1 0x10000 +#define SLOW_SRC2 0x20000 +#define SLOW_DEST 0x40000 + +/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ +#define CHECK_FLAGS(list) \ + (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define STACK_STORE SW +#define STACK_LOAD LW +#else +#define STACK_STORE SD +#define STACK_LOAD LD +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#include "sljitNativeMIPS_32.c" +#else +#include "sljitNativeMIPS_64.c" +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_ins base; + sljit_si i, tmp, offs; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + local_size = (local_size + 15) & ~0xf; +#else + local_size = (local_size + 31) & ~0x1f; +#endif + compiler->local_size = local_size; + + if (local_size <= SIMM_MAX) { + /* Frequent case. */ + FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP))); + base = S(SLJIT_SP); + } + else { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP))); + base = S(TMP_REG2); + local_size = 0; + } + + offs = local_size - (sljit_sw)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS)); + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) { + offs -= (sljit_si)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); + } + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + offs -= (sljit_si)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); + } + + if (args >= 1) + FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0))); + if (args >= 2) + FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_S1), DR(SLJIT_S1))); + if (args >= 3) + FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_S2), DR(SLJIT_S2))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + compiler->local_size = (local_size + 15) & ~0xf; +#else + compiler->local_size = (local_size + 31) & ~0x1f; +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si local_size, i, tmp, offs; + sljit_ins base; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + local_size = compiler->local_size; + if (local_size <= SIMM_MAX) + base = S(SLJIT_SP); + else { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1))); + base = S(TMP_REG1); + local_size = 0; + } + + FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); + offs = local_size - (sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + + tmp = compiler->scratches; + for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); + offs += (sljit_si)(sizeof(sljit_sw)); + } + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + for (i = tmp; i <= SLJIT_S0; i++) { + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); + offs += (sljit_si)(sizeof(sljit_sw)); + } + + SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw))); + + FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); + if (compiler->local_size <= SIMM_MAX) + return push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(compiler->local_size), UNMOVABLE_INS); + else + return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_SP), UNMOVABLE_INS); +} + +#undef STACK_STORE +#undef STACK_LOAD + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define ARCH_32_64(a, b) a +#else +#define ARCH_32_64(a, b) b +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), +/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), +/* u b s */ HI(40) /* sb */, +/* u b l */ HI(36) /* lbu */, +/* u h s */ HI(41) /* sh */, +/* u h l */ HI(37) /* lhu */, +/* u i s */ HI(43) /* sw */, +/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */), + +/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), +/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), +/* s b s */ HI(40) /* sb */, +/* s b l */ HI(32) /* lb */, +/* s h s */ HI(41) /* sh */, +/* s h l */ HI(33) /* lh */, +/* s i s */ HI(43) /* sw */, +/* s i l */ HI(35) /* lw */, + +/* d s */ HI(61) /* sdc1 */, +/* d l */ HI(53) /* ldc1 */, +/* s s */ HI(57) /* swc1 */, +/* s l */ HI(49) /* lwc1 */, +}; + +#undef ARCH_32_64 + +/* reg_ar is an absoulute register! */ + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) { + /* Works for both absoulte and relative addresses. */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK) + | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); + return -1; + } + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* Simple operation except for updates. */ + if (arg & OFFS_REG_MASK) { + argw &= 0x3; + next_argw &= 0x3; + if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) + return 1; + return 0; + } + + if (arg == next_arg) { + if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) + return 1; + return 0; + } + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_ar, base, delay_slot; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { + tmp_ar = reg_ar; + delay_slot = reg_ar; + } else { + tmp_ar = DR(TMP_REG1); + delay_slot = MOVABLE_INS; + } + base = arg & REG_MASK; + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + if ((flags & WRITE_BACK) && reg_ar == DR(base)) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); + FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + reg_ar = DR(TMP_REG1); + } + + /* Using the cache. */ + if (argw == compiler->cache_argw) { + if (!(flags & WRITE_BACK)) { + if (arg == compiler->cache_arg) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + } + } + else { + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); + } + } + } + + if (SLJIT_UNLIKELY(argw)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); + } + + if (!(flags & WRITE_BACK)) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); + tmp_ar = DR(TMP_REG3); + } + else + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(base), DR(base))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); + } + + if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { + /* Update only applies if a base register exists. */ + if (reg_ar == DR(base)) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS)); + if (argw) + return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)); + return SLJIT_SUCCESS; + } + FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + reg_ar = DR(TMP_REG1); + } + + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (argw) + FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base))); + } + else { + if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + } + else { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + } + } + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); + } + + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + } + + if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + } + else { + compiler->cache_arg = SLJIT_MEM; + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + } + compiler->cache_argw = argw; + + if (!base) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + + if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { + compiler->cache_arg = arg; + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + } + + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + if (GET_FLAGS(op)) + flags |= UNUSED_DEST; + } + else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN)) + || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) + || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) { + src1_r = src1; + flags |= REG1_SOURCE; + } + else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); + src1_r = TMP_REG1; + } + else + src1_r = 0; + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (FAST_IS_REG(src2)) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else if (src2 & SLJIT_IMM) { + if (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); + src2_r = sugg_src2_r; + } + else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } + } + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + src2_r = sugg_src2_r; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + SLJIT_ASSERT(src2_r == TMP_REG2); + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw)); + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw); + return compiler->error; + } + return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + sljit_si int_op = op & SLJIT_INT_OP; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, BREAK, UNMOVABLE_INS); + case SLJIT_NOP: + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_LUMUL: + case SLJIT_LSMUL: +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); +#else + FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); +#endif + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); + return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); +#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (int_op) + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); +#else + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); +#endif + + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); + return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define flags 0 +#else + sljit_si flags = 0; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) { + flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + } +#endif + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); +#endif + + case SLJIT_MOV_SI: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); +#endif + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); +#endif + + case SLJIT_MOVU_SI: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); +#endif + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define flags 0 +#else + sljit_si flags = 0; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op & SLJIT_INT_OP) { + flags |= INT_DATA | SIGNED_DATA; + if (src1 & SLJIT_IMM) + src1w = (sljit_si)src1w; + if (src2 & SLJIT_IMM) + src2w = (sljit_si)src2w; + } +#endif + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (src2 & SLJIT_IMM) + src2w &= 0x1f; +#else + if (src2 & SLJIT_IMM) { + if (op & SLJIT_INT_OP) + src2w &= 0x1f; + else + src2w &= 0x3f; + } +#endif + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg << 1; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#elif defined(__GNUC__) + sljit_sw fir; + asm ("cfc1 %0, $0" : "=r"(fir)); + return (fir >> 22) & 0x1; +#else +#error "FIR check is not implemented for this architecture" +#endif +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) +#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define flags 0 +#else + sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVW_FROMD) << 21; +#endif + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + src = TMP_FREG1; + } + else + src <<= 1; + + FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS)); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS); + + /* Store the integer value from a VFP register. */ + return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef is_long +#endif +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define flags 0 +#else + sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVD_FROMW) << 21; +#endif + + sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); + else if (src & SLJIT_MEM) { + /* Load the integer value into a VFP register. */ + FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + } + else { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + srcw = (sljit_si)srcw; +#endif + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); + } + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef flags +#endif +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + src1 = TMP_FREG1; + } + else + src1 <<= 1; + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + src2 = TMP_FREG2; + } + else + src2 <<= 1; + + /* src2 and src1 are swapped. */ + if (op & SLJIT_SET_E) { + FAIL_IF(push_inst(compiler, C_UEQ_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); + } + if (op & SLJIT_SET_S) { + /* Mixing the instructions for the two checks. */ + FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src1) | FS(src2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); + } + return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) + op ^= SLJIT_SINGLE_OP; + + dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); + src = dst_r; + } + else + src <<= 1; + + switch (GET_OPCODE(op)) { + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) + FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); + break; + case SLJIT_DABS: + FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); + break; + case SLJIT_CONVD_FROMS: + FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_SINGLE_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); + op ^= SLJIT_SINGLE_OP; + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= SLOW_SRC1; + } + else + src1 <<= 1; + + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= SLOW_SRC2; + } + else + src2 <<= 1; + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & SLOW_SRC1) + src1 = TMP_FREG1; + if (flags & SLOW_SRC2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); + break; + + case SLJIT_DSUB: + FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); + break; + + case SLJIT_DMUL: + FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); + break; + + case SLJIT_DDIV: + FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); + break; + } + + if (dst_r == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); + + FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); + return push_inst(compiler, NOP, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + compiler->delay_slot = UNMOVABLE_INS; + return label; +} + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define JUMP_LENGTH 4 +#else +#define JUMP_LENGTH 8 +#endif + +#define BR_Z(src) \ + inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \ + flags = IS_BIT26_COND; \ + delay_check = src; + +#define BR_NZ(src) \ + inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \ + flags = IS_BIT26_COND; \ + delay_check = src; + +#define BR_T() \ + inst = BC1T | JUMP_LENGTH; \ + flags = IS_BIT16_COND; \ + delay_check = FCSR_FCC; + +#define BR_F() \ + inst = BC1F | JUMP_LENGTH; \ + flags = IS_BIT16_COND; \ + delay_check = FCSR_FCC; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si flags = 0; + sljit_si delay_check = UNMOVABLE_INS; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + switch (type) { + case SLJIT_EQUAL: + case SLJIT_D_NOT_EQUAL: + BR_NZ(EQUAL_FLAG); + break; + case SLJIT_NOT_EQUAL: + case SLJIT_D_EQUAL: + BR_Z(EQUAL_FLAG); + break; + case SLJIT_LESS: + case SLJIT_D_LESS: + BR_Z(ULESS_FLAG); + break; + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + BR_NZ(ULESS_FLAG); + break; + case SLJIT_GREATER: + case SLJIT_D_GREATER: + BR_Z(UGREATER_FLAG); + break; + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + BR_NZ(UGREATER_FLAG); + break; + case SLJIT_SIG_LESS: + BR_Z(LESS_FLAG); + break; + case SLJIT_SIG_GREATER_EQUAL: + BR_NZ(LESS_FLAG); + break; + case SLJIT_SIG_GREATER: + BR_Z(GREATER_FLAG); + break; + case SLJIT_SIG_LESS_EQUAL: + BR_NZ(GREATER_FLAG); + break; + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + BR_Z(OVERFLOW_FLAG); + break; + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + BR_NZ(OVERFLOW_FLAG); + break; + case SLJIT_D_UNORDERED: + BR_F(); + break; + case SLJIT_D_ORDERED: + BR_T(); + break; + default: + /* Not conditional branch. */ + inst = 0; + break; + } + + jump->flags |= flags; + if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check)) + jump->flags |= IS_MOVABLE; + + if (inst) + PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + if (type <= SLJIT_JUMP) { + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + } else { + SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); + /* Cannot be optimized out if type is >= CALL0. */ + jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 0); + PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + jump->addr = compiler->size; + /* A NOP if type < CALL1. */ + PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS)); + } + return jump; +} + +#define RESOLVE_IMM1() \ + if (src1 & SLJIT_IMM) { \ + if (src1w) { \ + PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ + src1 = TMP_REG1; \ + } \ + else \ + src1 = 0; \ + } + +#define RESOLVE_IMM2() \ + if (src2 & SLJIT_IMM) { \ + if (src2w) { \ + PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ + src2 = TMP_REG2; \ + } \ + else \ + src2 = 0; \ + } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + struct sljit_jump *jump; + sljit_si flags; + sljit_ins inst; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; + if (src1 & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); + src1 = TMP_REG1; + } + if (src2 & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); + src2 = TMP_REG2; + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type <= SLJIT_NOT_EQUAL) { + RESOLVE_IMM1(); + RESOLVE_IMM2(); + jump->flags |= IS_BIT26_COND; + if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) + jump->flags |= IS_MOVABLE; + PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS)); + } + else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { + inst = NOP; + if ((src1 & SLJIT_IMM) && (src1w == 0)) { + RESOLVE_IMM2(); + switch (type) { + case SLJIT_SIG_LESS: + inst = BLEZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_SIG_GREATER_EQUAL: + inst = BGTZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_SIG_GREATER: + inst = BGEZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_SIG_LESS_EQUAL: + inst = BLTZ; + jump->flags |= IS_BIT16_COND; + break; + } + src1 = src2; + } + else { + RESOLVE_IMM1(); + switch (type) { + case SLJIT_SIG_LESS: + inst = BGEZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_SIG_GREATER_EQUAL: + inst = BLTZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_SIG_GREATER: + inst = BLEZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_SIG_LESS_EQUAL: + inst = BGTZ; + jump->flags |= IS_BIT26_COND; + break; + } + } + PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS)); + } + else { + if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) { + RESOLVE_IMM1(); + if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); + else { + RESOLVE_IMM2(); + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1))); + } + type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL; + } + else { + RESOLVE_IMM2(); + if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); + else { + RESOLVE_IMM1(); + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); + } + type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL; + } + + jump->flags |= IS_BIT26_COND; + PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS)); + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return jump; +} + +#undef RESOLVE_IMM1 +#undef RESOLVE_IMM2 + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si if_true; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (src1 & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + src1 = TMP_FREG1; + } + else + src1 <<= 1; + + if (src2 & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + src2 = TMP_FREG2; + } + else + src2 <<= 1; + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + jump->flags |= IS_BIT16_COND; + + switch (type & 0xff) { + case SLJIT_D_EQUAL: + inst = C_UEQ_S; + if_true = 1; + break; + case SLJIT_D_NOT_EQUAL: + inst = C_UEQ_S; + if_true = 0; + break; + case SLJIT_D_LESS: + inst = C_ULT_S; + if_true = 1; + break; + case SLJIT_D_GREATER_EQUAL: + inst = C_ULT_S; + if_true = 0; + break; + case SLJIT_D_GREATER: + inst = C_ULE_S; + if_true = 0; + break; + case SLJIT_D_LESS_EQUAL: + inst = C_ULE_S; + if_true = 1; + break; + case SLJIT_D_UNORDERED: + inst = C_UN_S; + if_true = 1; + break; + default: /* Make compilers happy. */ + SLJIT_ASSERT_STOP(); + case SLJIT_D_ORDERED: + inst = C_UN_S; + if_true = 0; + break; + } + + PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | FT(src2) | FS(src1), UNMOVABLE_INS)); + /* Intentionally the other opcode. */ + PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return jump; +} + +#undef JUMP_LENGTH +#undef BR_Z +#undef BR_NZ +#undef BR_T +#undef BR_F + +#undef FLOAT_DATA +#undef FMT + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_si src_r = TMP_REG2; + struct sljit_jump *jump = NULL; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) { + if (DR(src) != 4) + src_r = src; + else + FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + } + + if (type >= SLJIT_CALL0) { + SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); + if (src & (SLJIT_IMM | SLJIT_MEM)) { + if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); + else { + SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + } + FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + /* We need an extra instruction in any case. */ + return push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS); + } + + /* Register input. */ + if (type >= SLJIT_CALL1) + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), 4)); + FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); + } + + if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); + jump->u.target = srcw; + + if (compiler->delay_slot != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + + FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + } + else if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + + FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); + if (jump) + jump->addr = compiler->size; + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si sugg_dst_ar, dst_ar; + sljit_si flags = GET_ALL_FLAGS(op); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define mem_type WORD_DATA +#else + sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + mem_type = INT_DATA | SIGNED_DATA; +#endif + sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + switch (type & 0xff) { + case SLJIT_EQUAL: + case SLJIT_NOT_EQUAL: + FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + break; + case SLJIT_LESS: + case SLJIT_GREATER_EQUAL: + case SLJIT_D_LESS: + case SLJIT_D_GREATER_EQUAL: + dst_ar = ULESS_FLAG; + break; + case SLJIT_GREATER: + case SLJIT_LESS_EQUAL: + case SLJIT_D_GREATER: + case SLJIT_D_LESS_EQUAL: + dst_ar = UGREATER_FLAG; + break; + case SLJIT_SIG_LESS: + case SLJIT_SIG_GREATER_EQUAL: + dst_ar = LESS_FLAG; + break; + case SLJIT_SIG_GREATER: + case SLJIT_SIG_LESS_EQUAL: + dst_ar = GREATER_FLAG; + break; + case SLJIT_OVERFLOW: + case SLJIT_NOT_OVERFLOW: + dst_ar = OVERFLOW_FLAG; + break; + case SLJIT_MUL_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + type ^= 0x1; /* Flip type bit for the XORI below. */ + break; + case SLJIT_D_EQUAL: + case SLJIT_D_NOT_EQUAL: + dst_ar = EQUAL_FLAG; + break; + + case SLJIT_D_UNORDERED: + case SLJIT_D_ORDERED: + FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); + FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); + FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + break; + + default: + SLJIT_ASSERT_STOP(); + dst_ar = sugg_dst_ar; + break; + } + + if (type & 0x1) { + FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + } + + if (op >= SLJIT_ADD) { + if (DR(TMP_REG2) != dst_ar) + FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw); + + if (sugg_dst_ar != dst_ar) + return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar); + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef mem_type +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si reg; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} diff --git a/pcre2/src/sljit/sljitNativePPC_32.c b/pcre2/src/sljit/sljitNativePPC_32.c new file mode 100644 index 000000000..b14b75ceb --- /dev/null +++ b/pcre2/src/sljit/sljitNativePPC_32.c @@ -0,0 +1,269 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ppc 32-bit arch dependent functions. */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +{ + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); + + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); + + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; +} + +#define INS_CLEAR_LEFT(dst, src, from) \ + (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else { + SLJIT_ASSERT(dst == src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else { + SLJIT_ASSERT(dst == src2); + } + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); + + case SLJIT_ADD: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM2) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM4) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); + return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); + return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); + + case SLJIT_ADDC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); + return push_inst(compiler, MTXER | S(0)); + } + return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); + + case SLJIT_SUB: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & (ALT_FORM2 | ALT_FORM3)) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) + FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm)); + if (flags & ALT_FORM3) + return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm); + return SLJIT_SUCCESS; + } + if (flags & (ALT_FORM4 | ALT_FORM5)) { + if (flags & ALT_FORM4) + FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); + if (flags & ALT_FORM5) + FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2))); + return SLJIT_SUCCESS; + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); + if (flags & ALT_FORM6) + FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); + return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); + + case SLJIT_SUBC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); + return push_inst(compiler, MTXER | S(0)); + } + return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); + + case SLJIT_MUL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); + } + return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); + + case SLJIT_AND: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); + } + return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_OR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_XOR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_SHL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); + } + return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_LSHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); + } + return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_ASHR: + if (flags & ALT_FORM3) + FAIL_IF(push_inst(compiler, MFXER | D(0))); + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + } + else + FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2))); + return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff --git a/pcre2/src/sljit/sljitNativePPC_64.c b/pcre2/src/sljit/sljitNativePPC_64.c new file mode 100644 index 000000000..182ac7b3d --- /dev/null +++ b/pcre2/src/sljit/sljitNativePPC_64.c @@ -0,0 +1,421 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ppc 64-bit arch dependent functions. */ + +#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) +#define ASM_SLJIT_CLZ(src, dst) \ + __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) +#elif defined(__xlc__) +#error "Please enable GCC syntax for inline assembly statements" +#else +#error "Must implement count leading zeroes" +#endif + +#define RLDI(dst, src, sh, mb, type) \ + (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) + +#define PUSH_RLDICR(reg, shift) \ + push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +{ + sljit_uw tmp; + sljit_uw shift; + sljit_uw tmp2; + sljit_uw shift2; + + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); + + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); + + if (imm <= 0x7fffffffl && imm >= -0x80000000l) { + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; + } + + /* Count leading zeroes. */ + tmp = (imm >= 0) ? imm : ~imm; + ASM_SLJIT_CLZ(tmp, shift); + SLJIT_ASSERT(shift > 0); + shift--; + tmp = (imm << shift); + + if ((tmp & ~0xffff000000000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + shift += 15; + return PUSH_RLDICR(reg, shift); + } + + if ((tmp & ~0xffffffff00000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32))); + shift += 31; + return PUSH_RLDICR(reg, shift); + } + + /* Cut out the 16 bit from immediate. */ + shift += 15; + tmp2 = imm & ((1ul << (63 - shift)) - 1); + + if (tmp2 <= 0xffff) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(PUSH_RLDICR(reg, shift)); + return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2); + } + + if (tmp2 <= 0xffffffff) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(PUSH_RLDICR(reg, shift)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS; + } + + ASM_SLJIT_CLZ(tmp2, shift2); + tmp2 <<= shift2; + + if ((tmp2 & ~0xffff000000000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + shift2 += 15; + shift += (63 - shift2); + FAIL_IF(PUSH_RLDICR(reg, shift)); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48))); + return PUSH_RLDICR(reg, shift2); + } + + /* The general version. */ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32))); + FAIL_IF(PUSH_RLDICR(reg, 31)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)); +} + +/* Simplified mnemonics: clrldi. */ +#define INS_CLEAR_LEFT(dst, src, from) \ + (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5)) + +/* Sign extension for integer operations. */ +#define UN_EXTS() \ + if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ + src2 = TMP_REG2; \ + } + +#define BIN_EXTS() \ + if (flags & ALT_SIGN_EXT) { \ + if (flags & REG1_SOURCE) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ + src1 = TMP_REG1; \ + } \ + if (flags & REG2_SOURCE) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ + src2 = TMP_REG2; \ + } \ + } + +#define BIN_IMM_EXTS() \ + if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ + src1 = TMP_REG1; \ + } + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SI) + return push_inst(compiler, EXTSW | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); + } + else { + SLJIT_ASSERT(dst == src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else { + SLJIT_ASSERT(dst == src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else { + SLJIT_ASSERT(dst == src2); + } + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + if (flags & ALT_FORM1) + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); + return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); + + case SLJIT_ADD: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM2) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + BIN_IMM_EXTS(); + return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM4) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); + return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); + BIN_EXTS(); + return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); + + case SLJIT_ADDC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); + return push_inst(compiler, MTXER | S(0)); + } + BIN_EXTS(); + return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); + + case SLJIT_SUB: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & (ALT_FORM2 | ALT_FORM3)) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm)); + if (flags & ALT_FORM3) + return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm); + return SLJIT_SUCCESS; + } + if (flags & (ALT_FORM4 | ALT_FORM5)) { + if (flags & ALT_FORM4) + FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); + if (flags & ALT_FORM5) + return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)); + return SLJIT_SUCCESS; + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); + BIN_EXTS(); + if (flags & ALT_FORM6) + FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); + return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); + + case SLJIT_SUBC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); + return push_inst(compiler, MTXER | S(0)); + } + BIN_EXTS(); + return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); + + case SLJIT_MUL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); + } + BIN_EXTS(); + if (flags & ALT_FORM2) + return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); + return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1)); + + case SLJIT_AND: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); + } + return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_OR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_XOR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_SHL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); + } + else { + compiler->imm &= 0x3f; + return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags)); + } + } + return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_LSHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); + } + else { + compiler->imm &= 0x3f; + return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags)); + } + } + return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_ASHR: + if (flags & ALT_FORM3) + FAIL_IF(push_inst(compiler, MFXER | D(0))); + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + } + else { + compiler->imm &= 0x3f; + FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4))); + } + } + else + FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2))); + return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); + FAIL_IF(PUSH_RLDICR(reg, 31)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 5); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 5); +} diff --git a/pcre2/src/sljit/sljitNativePPC_common.c b/pcre2/src/sljit/sljitNativePPC_common.c new file mode 100644 index 000000000..b6a043f4e --- /dev/null +++ b/pcre2/src/sljit/sljitNativePPC_common.c @@ -0,0 +1,2375 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "PowerPC" SLJIT_CPUINFO; +} + +/* Length of an instruction word. + Both for ppc-32 and ppc-64. */ +typedef sljit_ui sljit_ins; + +#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_PPC_STACK_FRAME_V2 1 +#endif + +#ifdef _AIX +#include +#endif + +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 +#endif + +static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) +{ +#ifdef _AIX + _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from)); +#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) +# if defined(_ARCH_PWR) || defined(_ARCH_PWR2) + /* Cache flush for POWER architecture. */ + while (from < to) { + __asm__ volatile ( + "clf 0, %0\n" + "dcs\n" + : : "r"(from) + ); + from++; + } + __asm__ volatile ( "ics" ); +# elif defined(_ARCH_COM) && !defined(_ARCH_PPC) +# error "Cache flush is not implemented for PowerPC/POWER common mode." +# else + /* Cache flush for PowerPC architecture. */ + while (from < to) { + __asm__ volatile ( + "dcbf 0, %0\n" + "sync\n" + "icbi 0, %0\n" + : : "r"(from) + ); + from++; + } + __asm__ volatile ( "isync" ); +# endif +# ifdef __xlc__ +# warning "This file may fail to compile if -qfuncsect is used" +# endif +#elif defined(__xlc__) +#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc" +#else +#error "This platform requires a cache flush implementation." +#endif /* _AIX */ +} + +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5) + +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) +#define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6) +#else +#define TMP_CALL_REG TMP_REG2 +#endif + +#define TMP_FREG1 (0) +#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { + 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12 +}; + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ +#define D(d) (reg_map[d] << 21) +#define S(s) (reg_map[s] << 21) +#define A(a) (reg_map[a] << 16) +#define B(b) (reg_map[b] << 11) +#define C(c) (reg_map[c] << 6) +#define FD(fd) ((fd) << 21) +#define FS(fs) ((fs) << 21) +#define FA(fa) ((fa) << 16) +#define FB(fb) ((fb) << 11) +#define FC(fc) ((fc) << 6) +#define IMM(imm) ((imm) & 0xffff) +#define CRD(d) ((d) << 21) + +/* Instruction bit sections. + OE and Rc flag (see ALT_SET_FLAGS). */ +#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS)) +/* Rc flag (see ALT_SET_FLAGS). */ +#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10) +#define HI(opcode) ((opcode) << 26) +#define LO(opcode) ((opcode) << 1) + +#define ADD (HI(31) | LO(266)) +#define ADDC (HI(31) | LO(10)) +#define ADDE (HI(31) | LO(138)) +#define ADDI (HI(14)) +#define ADDIC (HI(13)) +#define ADDIS (HI(15)) +#define ADDME (HI(31) | LO(234)) +#define AND (HI(31) | LO(28)) +#define ANDI (HI(28)) +#define ANDIS (HI(29)) +#define Bx (HI(18)) +#define BCx (HI(16)) +#define BCCTR (HI(19) | LO(528) | (3 << 11)) +#define BLR (HI(19) | LO(16) | (0x14 << 21)) +#define CNTLZD (HI(31) | LO(58)) +#define CNTLZW (HI(31) | LO(26)) +#define CMP (HI(31) | LO(0)) +#define CMPI (HI(11)) +#define CMPL (HI(31) | LO(32)) +#define CMPLI (HI(10)) +#define CROR (HI(19) | LO(449)) +#define DIVD (HI(31) | LO(489)) +#define DIVDU (HI(31) | LO(457)) +#define DIVW (HI(31) | LO(491)) +#define DIVWU (HI(31) | LO(459)) +#define EXTSB (HI(31) | LO(954)) +#define EXTSH (HI(31) | LO(922)) +#define EXTSW (HI(31) | LO(986)) +#define FABS (HI(63) | LO(264)) +#define FADD (HI(63) | LO(21)) +#define FADDS (HI(59) | LO(21)) +#define FCFID (HI(63) | LO(846)) +#define FCMPU (HI(63) | LO(0)) +#define FCTIDZ (HI(63) | LO(815)) +#define FCTIWZ (HI(63) | LO(15)) +#define FDIV (HI(63) | LO(18)) +#define FDIVS (HI(59) | LO(18)) +#define FMR (HI(63) | LO(72)) +#define FMUL (HI(63) | LO(25)) +#define FMULS (HI(59) | LO(25)) +#define FNEG (HI(63) | LO(40)) +#define FRSP (HI(63) | LO(12)) +#define FSUB (HI(63) | LO(20)) +#define FSUBS (HI(59) | LO(20)) +#define LD (HI(58) | 0) +#define LWZ (HI(32)) +#define MFCR (HI(31) | LO(19)) +#define MFLR (HI(31) | LO(339) | 0x80000) +#define MFXER (HI(31) | LO(339) | 0x10000) +#define MTCTR (HI(31) | LO(467) | 0x90000) +#define MTLR (HI(31) | LO(467) | 0x80000) +#define MTXER (HI(31) | LO(467) | 0x10000) +#define MULHD (HI(31) | LO(73)) +#define MULHDU (HI(31) | LO(9)) +#define MULHW (HI(31) | LO(75)) +#define MULHWU (HI(31) | LO(11)) +#define MULLD (HI(31) | LO(233)) +#define MULLI (HI(7)) +#define MULLW (HI(31) | LO(235)) +#define NEG (HI(31) | LO(104)) +#define NOP (HI(24)) +#define NOR (HI(31) | LO(124)) +#define OR (HI(31) | LO(444)) +#define ORI (HI(24)) +#define ORIS (HI(25)) +#define RLDICL (HI(30)) +#define RLWINM (HI(21)) +#define SLD (HI(31) | LO(27)) +#define SLW (HI(31) | LO(24)) +#define SRAD (HI(31) | LO(794)) +#define SRADI (HI(31) | LO(413 << 1)) +#define SRAW (HI(31) | LO(792)) +#define SRAWI (HI(31) | LO(824)) +#define SRD (HI(31) | LO(539)) +#define SRW (HI(31) | LO(536)) +#define STD (HI(62) | 0) +#define STDU (HI(62) | 1) +#define STDUX (HI(31) | LO(181)) +#define STFIWX (HI(31) | LO(983)) +#define STW (HI(36)) +#define STWU (HI(37)) +#define STWUX (HI(31) | LO(183)) +#define SUBF (HI(31) | LO(40)) +#define SUBFC (HI(31) | LO(8)) +#define SUBFE (HI(31) | LO(136)) +#define SUBFIC (HI(8)) +#define XOR (HI(31) | LO(316)) +#define XORI (HI(26)) +#define XORIS (HI(27)) + +#define SIMM_MAX (0x7fff) +#define SIMM_MIN (-0x8000) +#define UIMM_MAX (0xffff) + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) +{ + sljit_sw* ptrs; + if (func_ptr) + *func_ptr = (void*)context; + ptrs = (sljit_sw*)func; + context->addr = addr ? addr : ptrs[0]; + context->r2 = ptrs[1]; + context->r11 = ptrs[2]; +} +#endif + +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + sljit_sw extra_jump_flags; + +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) + return 0; +#else + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; +#endif + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (jump->flags & IS_CALL) + goto keep_address; +#endif + + diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l; + + extra_jump_flags = 0; + if (jump->flags & IS_COND) { + if (diff <= 0x7fff && diff >= -0x8000) { + jump->flags |= PATCH_B; + return 1; + } + if (target_addr <= 0xffff) { + jump->flags |= PATCH_B | PATCH_ABS_B; + return 1; + } + extra_jump_flags = REMOVE_COND; + + diff -= sizeof(sljit_ins); + } + + if (diff <= 0x01ffffff && diff >= -0x02000000) { + jump->flags |= PATCH_B | extra_jump_flags; + return 1; + } + if (target_addr <= 0x03ffffff) { + jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags; + return 1; + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) +keep_address: +#endif + if (target_addr <= 0x7fffffff) { + jump->flags |= PATCH_ABS32; + return 1; + } + if (target_addr <= 0x7fffffffffffl) { + jump->flags |= PATCH_ABS48; + return 1; + } +#endif + + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); +#else + compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); +#endif +#endif + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + jump->addr = (sljit_uw)(code_ptr - 3); +#else + jump->addr = (sljit_uw)(code_ptr - 6); +#endif + if (detect_jump_type(jump, code_ptr, code)) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + code_ptr[-3] = code_ptr[0]; + code_ptr -= 3; +#else + if (jump->flags & PATCH_ABS32) { + code_ptr -= 3; + code_ptr[-1] = code_ptr[2]; + code_ptr[0] = code_ptr[3]; + } + else if (jump->flags & PATCH_ABS48) { + code_ptr--; + code_ptr[-1] = code_ptr[0]; + code_ptr[0] = code_ptr[1]; + /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ + SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); + code_ptr[-3] ^= 0x8422; + /* oris -> ori */ + code_ptr[-2] ^= 0x4000000; + } + else { + code_ptr[-6] = code_ptr[0]; + code_ptr -= 6; + } +#endif + if (jump->flags & REMOVE_COND) { + code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); + code_ptr++; + jump->addr += sizeof(sljit_ins); + code_ptr[0] = Bx; + jump->flags -= IS_COND; + } + } + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); +#else + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); +#endif + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + if (jump->flags & PATCH_B) { + if (jump->flags & IS_COND) { + if (!(jump->flags & PATCH_ABS_B)) { + addr = addr - jump->addr; + SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); + *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); + } + else { + SLJIT_ASSERT(addr <= 0xffff); + *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); + } + } + else { + if (!(jump->flags & PATCH_ABS_B)) { + addr = addr - jump->addr; + SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); + *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); + } + else { + SLJIT_ASSERT(addr <= 0x03ffffff); + *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); + } + } + break; + } + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); +#else + if (jump->flags & PATCH_ABS32) { + SLJIT_ASSERT(addr <= 0x7fffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); + break; + } + if (jump->flags & PATCH_ABS48) { + SLJIT_ASSERT(addr <= 0x7fffffffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); + break; + } + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); +#endif + } while (0); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (((sljit_sw)code_ptr) & 0x4) + code_ptr++; + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); + return code_ptr; +#else + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); + return code_ptr; +#endif +#else + return code; +#endif +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* inp_flags: */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define INDEXED 0x02 +#define WRITE_BACK 0x04 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x08 +#define HALF_DATA 0x10 +#define INT_DATA 0x18 +#define SIGNED_DATA 0x20 +/* Separates integer and floating point registers */ +#define GPR_REG 0x3f +#define DOUBLE_DATA 0x40 + +#define MEM_MASK 0x7f + +/* Other inp_flags. */ + +#define ARG_TEST 0x000100 +/* Integer opertion and set flags -> requires exts on 64 bit systems. */ +#define ALT_SIGN_EXT 0x000200 +/* This flag affects the RC() and OERC() macros. */ +#define ALT_SET_FLAGS 0x000400 +#define ALT_KEEP_CACHE 0x000800 +#define ALT_FORM1 0x010000 +#define ALT_FORM2 0x020000 +#define ALT_FORM3 0x040000 +#define ALT_FORM4 0x080000 +#define ALT_FORM5 0x100000 +#define ALT_FORM6 0x200000 + +/* Source and destination is register. */ +#define REG_DEST 0x000001 +#define REG1_SOURCE 0x000002 +#define REG2_SOURCE 0x000004 +/* getput_arg_fast returned true. */ +#define FAST_DEST 0x000008 +/* Multiple instructions are required. */ +#define SLOW_DEST 0x000010 +/* +ALT_SIGN_EXT 0x000200 +ALT_SET_FLAGS 0x000400 +ALT_FORM1 0x010000 +... +ALT_FORM6 0x200000 */ + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#include "sljitNativePPC_32.c" +#else +#include "sljitNativePPC_64.c" +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define STACK_STORE STW +#define STACK_LOAD LWZ +#else +#define STACK_STORE STD +#define STACK_LOAD LD +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si i, tmp, offs; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + FAIL_IF(push_inst(compiler, MFLR | D(0))); + offs = -(sljit_si)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) { + offs -= (sljit_si)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); + } + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + offs -= (sljit_si)(sizeof(sljit_sw)); + FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); + } + + SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); + +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); +#else + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); +#endif + + FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0)); + if (args >= 1) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0))); + if (args >= 2) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1))); + if (args >= 3) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2))); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; + local_size = (local_size + 15) & ~0xf; + compiler->local_size = local_size; + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, -local_size)); + FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); + } +#else + if (local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, -local_size)); + FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); + } +#endif + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; + compiler->local_size = (local_size + 15) & ~0xf; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si i, tmp, offs; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, compiler->local_size)); + FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0))); + } + +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); +#else + FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); +#endif + + offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + + tmp = compiler->scratches; + for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { + FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); + offs += (sljit_si)(sizeof(sljit_sw)); + } + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + for (i = tmp; i <= SLJIT_S0; i++) { + FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); + offs += (sljit_si)(sizeof(sljit_sw)); + } + + FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); + SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw))); + + FAIL_IF(push_inst(compiler, MTLR | S(0))); + FAIL_IF(push_inst(compiler, BLR)); + + return SLJIT_SUCCESS; +} + +#undef STACK_STORE +#undef STACK_LOAD + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* i/x - immediate/indexed form + n/w - no write-back / write-back (1 bit) + s/l - store/load (1 bit) + u/s - signed/unsigned (1 bit) + w/b/h/i - word/byte/half/int allowed (2 bit) + It contans 32 items, but not all are different. */ + +/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ +#define INT_ALIGNED 0x10000 +/* 64-bit only: there is no lwau instruction. */ +#define UPDATE_REQ 0x20000 + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define ARCH_32_64(a, b) a +#define INST_CODE_AND_DST(inst, flags, reg) \ + ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#else +#define ARCH_32_64(a, b) b +#define INST_CODE_AND_DST(inst, flags, reg) \ + (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { + +/* -------- Unsigned -------- */ + +/* Word. */ + +/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), +/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), +/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), + +/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), +/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), +/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), + +/* Byte. */ + +/* u b n i s */ HI(38) /* stb */, +/* u b n i l */ HI(34) /* lbz */, +/* u b n x s */ HI(31) | LO(215) /* stbx */, +/* u b n x l */ HI(31) | LO(87) /* lbzx */, + +/* u b w i s */ HI(39) /* stbu */, +/* u b w i l */ HI(35) /* lbzu */, +/* u b w x s */ HI(31) | LO(247) /* stbux */, +/* u b w x l */ HI(31) | LO(119) /* lbzux */, + +/* Half. */ + +/* u h n i s */ HI(44) /* sth */, +/* u h n i l */ HI(40) /* lhz */, +/* u h n x s */ HI(31) | LO(407) /* sthx */, +/* u h n x l */ HI(31) | LO(279) /* lhzx */, + +/* u h w i s */ HI(45) /* sthu */, +/* u h w i l */ HI(41) /* lhzu */, +/* u h w x s */ HI(31) | LO(439) /* sthux */, +/* u h w x l */ HI(31) | LO(311) /* lhzux */, + +/* Int. */ + +/* u i n i s */ HI(36) /* stw */, +/* u i n i l */ HI(32) /* lwz */, +/* u i n x s */ HI(31) | LO(151) /* stwx */, +/* u i n x l */ HI(31) | LO(23) /* lwzx */, + +/* u i w i s */ HI(37) /* stwu */, +/* u i w i l */ HI(33) /* lwzu */, +/* u i w x s */ HI(31) | LO(183) /* stwux */, +/* u i w x l */ HI(31) | LO(55) /* lwzux */, + +/* -------- Signed -------- */ + +/* Word. */ + +/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), +/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), +/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), + +/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), +/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), +/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), + +/* Byte. */ + +/* s b n i s */ HI(38) /* stb */, +/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */, +/* s b n x s */ HI(31) | LO(215) /* stbx */, +/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, + +/* s b w i s */ HI(39) /* stbu */, +/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */, +/* s b w x s */ HI(31) | LO(247) /* stbux */, +/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, + +/* Half. */ + +/* s h n i s */ HI(44) /* sth */, +/* s h n i l */ HI(42) /* lha */, +/* s h n x s */ HI(31) | LO(407) /* sthx */, +/* s h n x l */ HI(31) | LO(343) /* lhax */, + +/* s h w i s */ HI(45) /* sthu */, +/* s h w i l */ HI(43) /* lhau */, +/* s h w x s */ HI(31) | LO(439) /* sthux */, +/* s h w x l */ HI(31) | LO(375) /* lhaux */, + +/* Int. */ + +/* s i n i s */ HI(36) /* stw */, +/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */), +/* s i n x s */ HI(31) | LO(151) /* stwx */, +/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), + +/* s i w i s */ HI(37) /* stwu */, +/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */), +/* s i w x s */ HI(31) | LO(183) /* stwux */, +/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), + +/* -------- Double -------- */ + +/* d n i s */ HI(54) /* stfd */, +/* d n i l */ HI(50) /* lfd */, +/* d n x s */ HI(31) | LO(727) /* stfdx */, +/* d n x l */ HI(31) | LO(599) /* lfdx */, + +/* s n i s */ HI(52) /* stfs */, +/* s n i l */ HI(48) /* lfs */, +/* s n x s */ HI(31) | LO(663) /* stfsx */, +/* s n x l */ HI(31) | LO(535) /* lfsx */, + +}; + +#undef ARCH_32_64 + +/* Simple cases, (no caching is required). */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ins inst; + + /* Should work when (arg & REG_MASK) == 0. */ + SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0); + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (arg & OFFS_REG_MASK) { + if (argw & 0x3) + return 0; + if (inp_flags & ARG_TEST) + return 1; + + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg)))); + return -1; + } + + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) + inp_flags &= ~WRITE_BACK; + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); + + if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ)) + return 0; + if (inp_flags & ARG_TEST) + return 1; +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (argw > SIMM_MAX || argw < SIMM_MIN) + return 0; + if (inp_flags & ARG_TEST) + return 1; + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); +#endif + + FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw))); + return -1; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those operator always + uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_sw high_short, next_high_short; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_sw diff; +#endif + + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + if (arg & OFFS_REG_MASK) + return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3)); + + if (next_arg & OFFS_REG_MASK) + return 0; + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + return high_short == next_high_short; +#else + if (argw <= 0x7fffffffl && argw >= -0x80000000l) { + high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + if (high_short == next_high_short) + return 1; + } + + diff = argw - next_argw; + if (!(arg & REG_MASK)) + return diff <= SIMM_MAX && diff >= SIMM_MIN; + + if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN) + return 1; + + return 0; +#endif +} + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define ADJUST_CACHED_IMM(imm) \ + if ((inst & INT_ALIGNED) && (imm & 0x3)) { \ + /* Adjust cached value. Fortunately this is really a rare case */ \ + compiler->cache_argw += imm & 0x3; \ + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \ + imm &= ~0x3; \ + } +#endif + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_ins inst; + sljit_sw high_short, next_high_short; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_sw diff; +#endif + + SLJIT_ASSERT(arg & SLJIT_MEM); + + tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; + /* Special case for "mov reg, [reg, ... ]". */ + if ((arg & REG_MASK) == tmp_r) + tmp_r = TMP_REG1; + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + /* Otherwise getput_arg_fast would capture it. */ + SLJIT_ASSERT(argw); + + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw) + tmp_r = TMP_REG3; + else { + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1))); +#endif + } + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); + } + + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) + inp_flags &= ~WRITE_BACK; + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (argw <= 0x7fff7fffl && argw >= -0x80000000l + && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) { +#endif + + arg &= REG_MASK; + high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff; + /* The getput_arg_fast should handle this otherwise. */ +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); +#else + SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ))); +#endif + + if (inp_flags & WRITE_BACK) { + if (arg == reg) { + FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg))); + reg = tmp_r; + } + tmp_r = arg; + FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16))); + } + else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) { + if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { + next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + if (high_short == next_high_short) { + compiler->cache_arg = SLJIT_MEM | arg; + compiler->cache_argw = high_short; + tmp_r = TMP_REG3; + } + } + FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16))); + } + else + tmp_r = TMP_REG3; + + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + } + + /* Everything else is PPC-64 only. */ + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) { + diff = argw - compiler->cache_argw; + if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + ADJUST_CACHED_IMM(diff); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); + } + + diff = argw - next_argw; + if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); + } + + diff = argw - compiler->cache_argw; + if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ)); + ADJUST_CACHED_IMM(diff); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); + } + + if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + if (compiler->cache_argw != argw) { + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff))); + compiler->cache_argw = argw; + } + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); + } + + if (argw == next_argw && (next_arg & SLJIT_MEM)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); + } + + diff = argw - next_argw; + if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK))); + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3)); + } + + if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + else + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + + /* Get the indexed version instead of the normal one. */ + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); +#endif +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + sljit_si dst_r; + sljit_si src1_r; + sljit_si src2_r; + sljit_si sugg_src2_r = TMP_REG2; + sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + + if (!(input_flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + /* Destination check. */ + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else { + SLJIT_ASSERT(dst & SLJIT_MEM); + if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) { + flags |= FAST_DEST; + dst_r = TMP_REG2; + } + else { + flags |= SLOW_DEST; + dst_r = 0; + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) { + src1_r = src1; + flags |= REG1_SOURCE; + } + else if (src1 & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1_r = TMP_REG1; + } + else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1_r = TMP_REG1; + } + else + src1_r = 0; + + /* Source 2. */ + if (FAST_IS_REG(src2)) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else if (src2 & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); + src2_r = sugg_src2_r; + } + else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { + FAIL_IF(compiler->error); + src2_r = sugg_src2_r; + } + else + src2_r = 0; + + /* src1_r, src2_r and dst_r can be zero (=unprocessed). + All arguments are complex addressing modes, and it is a binary operator. */ + if (src1_r == 0 && src2_r == 0 && dst_r == 0) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + src1_r = TMP_REG1; + src2_r = TMP_REG2; + } + else if (src1_r == 0 && src2_r == 0) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + src1_r = TMP_REG1; + } + else if (src1_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + src1_r = TMP_REG1; + } + else if (src2_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + src2_r = sugg_src2_r; + } + + if (dst_r == 0) + dst_r = TMP_REG2; + + if (src1_r == 0) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + src1_r = TMP_REG1; + } + + if (src2_r == 0) { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); + src2_r = sugg_src2_r; + } + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (flags & (FAST_DEST | SLOW_DEST)) { + if (flags & FAST_DEST) + FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw)); + else + FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_si int_op = op & SLJIT_INT_OP; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + case SLJIT_NOP: + return push_inst(compiler, NOP); + case SLJIT_LUMUL: + case SLJIT_LSMUL: + FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); + return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); +#else + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); + return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); +#endif + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); +#else + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); +#endif + return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); + case SLJIT_UDIVI: + case SLJIT_SDIVI: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); +#else + return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); +#endif + } + + return SLJIT_SUCCESS; +} + +#define EMIT_MOV(type, type_flags, type_cast) \ + emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_si op_flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + op = GET_OPCODE(op); + if ((src & SLJIT_IMM) && srcw == 0) + src = TMP_ZERO; + + if (op_flags & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); + + if (op_flags & SLJIT_INT_OP) { + if (op < SLJIT_NOT) { + if (FAST_IS_REG(src) && src == dst) { + if (!TYPE_CAST_NEEDED(op)) + return SLJIT_SUCCESS; + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) + op = SLJIT_MOV_UI; + if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) + op = SLJIT_MOVU_UI; + if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) + op = SLJIT_MOV_SI; + if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) + op = SLJIT_MOVU_SI; +#endif + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + else { + /* Most operations expect sign extended arguments. */ + flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + } +#endif + } + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: +#endif + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + case SLJIT_MOV_UI: + return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); + + case SLJIT_MOV_SI: + return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); +#endif + + case SLJIT_MOV_UB: + return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); + + case SLJIT_MOV_SB: + return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); + + case SLJIT_MOV_UH: + return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); + + case SLJIT_MOV_SH: + return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: +#endif + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + case SLJIT_MOVU_UI: + return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); + + case SLJIT_MOVU_SI: + return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); +#endif + + case SLJIT_MOVU_UB: + return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); + + case SLJIT_MOVU_SB: + return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); + + case SLJIT_MOVU_UH: + return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); + + case SLJIT_MOVU_SH: + return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); + + case SLJIT_NOT: + return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_CLZ: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); +#endif + } + + return SLJIT_SUCCESS; +} + +#undef EMIT_MOV + +#define TEST_SL_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) + +#define TEST_UL_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_SH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) +#else +#define TEST_SH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) +#endif + +#define TEST_UH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000)) + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_ADD_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) +#else +#define TEST_ADD_IMM(src, srcw) \ + ((src) & SLJIT_IMM) +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_UI_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) +#else +#define TEST_UI_IMM(src, srcw) \ + ((src) & SLJIT_IMM) +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + if ((src1 & SLJIT_IMM) && src1w == 0) + src1 = TMP_ZERO; + if ((src2 & SLJIT_IMM) && src2w == 0) + src2 = TMP_ZERO; + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) { + /* Most operations expect sign extended arguments. */ + flags |= INT_DATA | SIGNED_DATA; + if (src1 & SLJIT_IMM) + src1w = (sljit_si)(src1w); + if (src2 & SLJIT_IMM) + src2w = (sljit_si)(src2w); + if (GET_FLAGS(op)) + flags |= ALT_SIGN_EXT; + } +#endif + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); + if (src2 == TMP_REG2) + flags |= ALT_KEEP_CACHE; + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src2, src2w)) { + compiler->imm = (src2w >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src1, src1w)) { + compiler->imm = (src1w >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + /* Range between -1 and -32768 is covered above. */ + if (TEST_ADD_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_ADD_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_ADDC: + return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (TEST_SL_IMM(src2, -src2w)) { + compiler->imm = (-src2w) & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src2, -src2w)) { + compiler->imm = ((-src2w) >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + /* Range between -1 and -32768 is covered above. */ + if (TEST_ADD_IMM(src2, -src2w)) { + compiler->imm = -src2w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + } + } + if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { + if (!(op & SLJIT_SET_U)) { + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + if (TEST_UL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); + } + if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) { + compiler->imm = src2w; + return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + } + if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) { + if (TEST_SL_IMM(src2, -src2w)) { + compiler->imm = (-src2w) & 0xffff; + return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + } + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUBC: + return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) + flags |= ALT_FORM2; +#endif + if (!GET_FLAGS(op)) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + /* Commutative unsigned operations. */ + if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { + if (TEST_UL_IMM(src2, src2w)) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UL_IMM(src1, src1w)) { + compiler->imm = src1w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_UH_IMM(src2, src2w)) { + compiler->imm = (src2w >> 16) & 0xffff; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UH_IMM(src1, src1w)) { + compiler->imm = (src1w >> 16) & 0xffff; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) { + if (TEST_UI_IMM(src2, src2w)) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UI_IMM(src1, src1w)) { + compiler->imm = src1w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_ASHR: + if (op & SLJIT_KEEP_FLAGS) + flags |= ALT_FORM3; + /* Fall through. */ + case SLJIT_SHL: + case SLJIT_LSHR: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) + flags |= ALT_FORM2; +#endif + if (src2 & SLJIT_IMM) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + return push_inst(compiler, *(sljit_ins*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) +#else +#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) + +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw)) +#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw)) +#else +#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw)) +#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw)) +#endif + +#endif /* SLJIT_CONFIG_PPC_64 */ + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (src & SLJIT_MEM) { + /* We can ignore the temporary data store on the stack from caching point of view. */ + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + src = TMP_FREG1; + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + op = GET_OPCODE(op); + FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (op == SLJIT_CONVW_FROMD) { + if (FAST_IS_REG(dst)) { + FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0)); + return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); + } + return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0); + } + +#else + FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src))); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; +#endif + + if (FAST_IS_REG(dst)) { + FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1))); + return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); + } + + SLJIT_ASSERT(dst & SLJIT_MEM); + + if (dst & OFFS_REG_MASK) { + dstw &= 0x3; + if (dstw) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1))); +#endif + dstw = TMP_REG1; + } + else + dstw = OFFS_REG(dst); + } + else { + if ((dst & REG_MASK) && !dstw) { + dstw = dst & REG_MASK; + dst = 0; + } + else { + /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */ + FAIL_IF(load_immediate(compiler, TMP_REG1, dstw)); + dstw = TMP_REG1; + } + } + + return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_IMM) { + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + srcw = (sljit_si)srcw; + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) { + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); + else + FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + src = TMP_REG1; + } + + if (FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw)); + } + else + FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); + if (op & SLJIT_SINGLE_OP) + return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); + return SLJIT_SUCCESS; + +#else + + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_si invert_sign = 1; + + if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000)); + src = TMP_REG1; + invert_sign = 0; + } + else if (!FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); + src = TMP_REG1; + } + + /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31))) + The double precision format has exactly 53 bit precision, so the lower 32 bit represents + the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000 + to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating + point value, we need to substract 2^53 + 2^31 from the constructed value. */ + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); + if (invert_sign) + FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI)); + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); + FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); + + FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); + if (op & SLJIT_SINGLE_OP) + return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); + return SLJIT_SUCCESS; + +#endif +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + src1 = TMP_FREG1; + } + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + src2 = TMP_FREG2; + } + + return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) + op ^= SLJIT_SINGLE_OP; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_CONVD_FROMS: + op ^= SLJIT_SINGLE_OP; + if (op & SLJIT_SINGLE_OP) { + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src))); + break; + } + /* Fall through. */ + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) + FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src))); + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src))); + break; + case SLJIT_DABS: + FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src))); + break; + } + + if (dst & SLJIT_MEM) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= ALT_FORM1; + } + + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= ALT_FORM2; + } + + if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & ALT_FORM1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & ALT_FORM2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & ALT_FORM1) + src1 = TMP_FREG1; + if (flags & ALT_FORM2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); + break; + + case SLJIT_DSUB: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); + break; + + case SLJIT_DMUL: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); + break; + + case SLJIT_DDIV: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); + break; + } + + if (dst_r == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef SELECT_FOP + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, MFLR | D(dst)); + + /* Memory. */ + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, MTLR | S(src))); + else { + if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); + FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); + } + return push_inst(compiler, BLR); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +static sljit_ins get_bo_bi_flags(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + return (12 << 21) | (2 << 16); + + case SLJIT_NOT_EQUAL: + return (4 << 21) | (2 << 16); + + case SLJIT_LESS: + case SLJIT_D_LESS: + return (12 << 21) | ((4 + 0) << 16); + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + return (4 << 21) | ((4 + 0) << 16); + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + return (12 << 21) | ((4 + 1) << 16); + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + return (4 << 21) | ((4 + 1) << 16); + + case SLJIT_SIG_LESS: + return (12 << 21) | (0 << 16); + + case SLJIT_SIG_GREATER_EQUAL: + return (4 << 21) | (0 << 16); + + case SLJIT_SIG_GREATER: + return (12 << 21) | (1 << 16); + + case SLJIT_SIG_LESS_EQUAL: + return (4 << 21) | (1 << 16); + + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + return (12 << 21) | (3 << 16); + + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + return (4 << 21) | (3 << 16); + + case SLJIT_D_EQUAL: + return (12 << 21) | ((4 + 2) << 16); + + case SLJIT_D_NOT_EQUAL: + return (4 << 21) | ((4 + 2) << 16); + + case SLJIT_D_UNORDERED: + return (12 << 21) | ((4 + 3) << 16); + + case SLJIT_D_ORDERED: + return (4 << 21) | ((4 + 3) << 16); + + default: + SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); + return (20 << 21); + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins bo_bi_flags; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + bo_bi_flags = get_bo_bi_flags(type & 0xff); + if (!bo_bi_flags) + return NULL; + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In PPC, we don't need to touch the arguments. */ + if (type < SLJIT_JUMP) + jump->flags |= IS_COND; +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) + jump->flags |= IS_CALL; +#endif + + PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); + PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG))); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump = NULL; + sljit_si src_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) { +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) { + FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src))); + src_r = TMP_CALL_REG; + } + else + src_r = src; +#else + src_r = src; +#endif + } else if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR); + jump->u.target = srcw; +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) + jump->flags |= IS_CALL; +#endif + FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); + src_r = TMP_CALL_REG; + } + else { + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw)); + src_r = TMP_CALL_REG; + } + + FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); + if (jump) + jump->addr = compiler->size; + return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)); +} + +/* Get a bit from CR, all other bits are zeroed. */ +#define GET_CR_BIT(bit, dst) \ + FAIL_IF(push_inst(compiler, MFCR | D(dst))); \ + FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1))); + +#define INVERT_BIT(dst) \ + FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si reg, input_flags; + sljit_si flags = GET_ALL_FLAGS(op); + sljit_sw original_dstw = dstw; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; +#else + input_flags = WORD_DATA; +#endif + FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + switch (type & 0xff) { + case SLJIT_EQUAL: + GET_CR_BIT(2, reg); + break; + + case SLJIT_NOT_EQUAL: + GET_CR_BIT(2, reg); + INVERT_BIT(reg); + break; + + case SLJIT_LESS: + case SLJIT_D_LESS: + GET_CR_BIT(4 + 0, reg); + break; + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + GET_CR_BIT(4 + 0, reg); + INVERT_BIT(reg); + break; + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + GET_CR_BIT(4 + 1, reg); + break; + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + GET_CR_BIT(4 + 1, reg); + INVERT_BIT(reg); + break; + + case SLJIT_SIG_LESS: + GET_CR_BIT(0, reg); + break; + + case SLJIT_SIG_GREATER_EQUAL: + GET_CR_BIT(0, reg); + INVERT_BIT(reg); + break; + + case SLJIT_SIG_GREATER: + GET_CR_BIT(1, reg); + break; + + case SLJIT_SIG_LESS_EQUAL: + GET_CR_BIT(1, reg); + INVERT_BIT(reg); + break; + + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + GET_CR_BIT(3, reg); + break; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + GET_CR_BIT(3, reg); + INVERT_BIT(reg); + break; + + case SLJIT_D_EQUAL: + GET_CR_BIT(4 + 2, reg); + break; + + case SLJIT_D_NOT_EQUAL: + GET_CR_BIT(4 + 2, reg); + INVERT_BIT(reg); + break; + + case SLJIT_D_UNORDERED: + GET_CR_BIT(4 + 3, reg); + break; + + case SLJIT_D_ORDERED: + GET_CR_BIT(4 + 3, reg); + INVERT_BIT(reg); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (op < SLJIT_ADD) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_MOV) + input_flags = WORD_DATA; + else { + op = SLJIT_MOV_UI; + input_flags = INT_DATA; + } +#else + op = SLJIT_MOV; + input_flags = WORD_DATA; +#endif + if (reg != TMP_REG2) + return SLJIT_SUCCESS; + return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + } + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si reg; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} diff --git a/pcre2/src/sljit/sljitNativeSPARC_32.c b/pcre2/src/sljit/sljitNativeSPARC_32.c new file mode 100644 index 000000000..4a2e6293d --- /dev/null +++ b/pcre2/src/sljit/sljitNativeSPARC_32.c @@ -0,0 +1,164 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm) +{ + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst)); + + FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst))); + return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS; +} + +#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2)) + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same); + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_UB) + return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst)); + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst))); + return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst))); + return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + /* sparc 32 does not support SLJIT_KEEP_FLAGS. Not sure I can fix this. */ + FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS)); + FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS | (flags & SET_FLAGS))); + FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst))); + + /* Loop. */ + FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS)); + FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS)); + return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS | (flags & SET_FLAGS)); + + case SLJIT_ADD: + return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_ADDC: + return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SUB: + return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SUBC: + return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_MUL: + FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + if (!(flags & SET_FLAGS)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK))); + return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS); + + case SLJIT_AND: + return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_OR: + return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_XOR: + return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SHL: + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + + case SLJIT_LSHR: + FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + + case SLJIT_ASHR: + FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst))); + return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff); + inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); + inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff --git a/pcre2/src/sljit/sljitNativeSPARC_common.c b/pcre2/src/sljit/sljitNativeSPARC_common.c new file mode 100644 index 000000000..327c4267b --- /dev/null +++ b/pcre2/src/sljit/sljitNativeSPARC_common.c @@ -0,0 +1,1435 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "SPARC" SLJIT_CPUINFO; +} + +/* Length of an instruction word + Both for sparc-32 and sparc-64 */ +typedef sljit_ui sljit_ins; + +static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) +{ +#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590 + __asm ( + /* if (from == to) return */ + "cmp %i0, %i1\n" + "be .leave\n" + "nop\n" + + /* loop until from >= to */ + ".mainloop:\n" + "flush %i0\n" + "add %i0, 8, %i0\n" + "cmp %i0, %i1\n" + "bcs .mainloop\n" + "nop\n" + + /* The comparison was done above. */ + "bne .leave\n" + /* nop is not necessary here, since the + sub operation has no side effect. */ + "sub %i0, 4, %i0\n" + "flush %i0\n" + ".leave:" + ); +#else + if (SLJIT_UNLIKELY(from == to)) + return; + + do { + __asm__ volatile ( + "flush %0\n" + : : "r"(from) + ); + /* Operates at least on doubleword. */ + from += 2; + } while (from < to); + + if (from == to) { + /* Flush the last word. */ + from --; + __asm__ volatile ( + "flush %0\n" + : : "r"(from) + ); + } +#endif +} + +/* TMP_REG2 is not used by getput_arg */ +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5) + +#define TMP_FREG1 (0) +#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { + 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15 +}; + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define D(d) (reg_map[d] << 25) +#define DA(d) ((d) << 25) +#define S1(s1) (reg_map[s1] << 14) +#define S2(s2) (reg_map[s2]) +#define S1A(s1) ((s1) << 14) +#define S2A(s2) (s2) +#define IMM_ARG 0x2000 +#define DOP(op) ((op) << 5) +#define IMM(imm) (((imm) & 0x1fff) | IMM_ARG) + +#define DR(dr) (reg_map[dr]) +#define OPC1(opcode) ((opcode) << 30) +#define OPC2(opcode) ((opcode) << 22) +#define OPC3(opcode) ((opcode) << 19) +#define SET_FLAGS OPC3(0x10) + +#define ADD (OPC1(0x2) | OPC3(0x00)) +#define ADDC (OPC1(0x2) | OPC3(0x08)) +#define AND (OPC1(0x2) | OPC3(0x01)) +#define ANDN (OPC1(0x2) | OPC3(0x05)) +#define CALL (OPC1(0x1)) +#define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09)) +#define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42)) +#define FADDS (OPC1(0x2) | OPC3(0x34) | DOP(0x41)) +#define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52)) +#define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51)) +#define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e)) +#define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d)) +#define FDTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd2)) +#define FDTOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc6)) +#define FITOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc8)) +#define FITOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc4)) +#define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01)) +#define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a)) +#define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49)) +#define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05)) +#define FSTOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc9)) +#define FSTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd1)) +#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46)) +#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45)) +#define JMPL (OPC1(0x2) | OPC3(0x38)) +#define NOP (OPC1(0x0) | OPC2(0x04)) +#define OR (OPC1(0x2) | OPC3(0x02)) +#define ORN (OPC1(0x2) | OPC3(0x06)) +#define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0)) +#define RESTORE (OPC1(0x2) | OPC3(0x3d)) +#define SAVE (OPC1(0x2) | OPC3(0x3c)) +#define SETHI (OPC1(0x0) | OPC2(0x04)) +#define SLL (OPC1(0x2) | OPC3(0x25)) +#define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12)) +#define SRA (OPC1(0x2) | OPC3(0x27)) +#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12)) +#define SRL (OPC1(0x2) | OPC3(0x26)) +#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12)) +#define SUB (OPC1(0x2) | OPC3(0x04)) +#define SUBC (OPC1(0x2) | OPC3(0x0c)) +#define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25)) +#define WRY (OPC1(0x2) | OPC3(0x30) | DA(0)) +#define XOR (OPC1(0x2) | OPC3(0x03)) +#define XNOR (OPC1(0x2) | OPC3(0x07)) + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define MAX_DISP (0x1fffff) +#define MIN_DISP (-0x200000) +#define DISP_MASK (0x3fffff) + +#define BICC (OPC1(0x0) | OPC2(0x2)) +#define FBFCC (OPC1(0x0) | OPC2(0x6)) +#define SLL_W SLL +#define SDIV (OPC1(0x2) | OPC3(0x0f)) +#define SMUL (OPC1(0x2) | OPC3(0x0b)) +#define UDIV (OPC1(0x2) | OPC3(0x0e)) +#define UMUL (OPC1(0x2) | OPC3(0x0a)) +#else +#define SLL_W SLLX +#endif + +#define SIMM_MAX (0x0fff) +#define SIMM_MIN (-0x1000) + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +{ + sljit_ins *ptr; + SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS + || (delay_slot & DST_INS_MASK) == MOVABLE_INS + || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + compiler->delay_slot = delay_slot; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + sljit_ins *inst; + sljit_ins saved_inst; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return code_ptr; + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + inst = (sljit_ins*)jump->addr; + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if (jump->flags & IS_CALL) { + /* Call is always patchable on sparc 32. */ + jump->flags |= PATCH_CALL; + if (jump->flags & IS_MOVABLE) { + inst[0] = inst[-1]; + inst[-1] = CALL; + jump->addr -= sizeof(sljit_ins); + return inst; + } + inst[0] = CALL; + inst[1] = NOP; + return inst + 1; + } +#else + /* Both calls and BPr instructions shall not pass this point. */ +#error "Implementation required" +#endif + + if (jump->flags & IS_COND) + inst--; + + if (jump->flags & IS_MOVABLE) { + diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2; + if (diff <= MAX_DISP && diff >= MIN_DISP) { + jump->flags |= PATCH_B; + inst--; + if (jump->flags & IS_COND) { + saved_inst = inst[0]; + inst[0] = inst[1] ^ (1 << 28); + inst[1] = saved_inst; + } else { + inst[1] = inst[0]; + inst[0] = BICC | DA(0x8); + } + jump->addr = (sljit_uw)inst; + return inst + 1; + } + } + + diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + if (diff <= MAX_DISP && diff >= MIN_DISP) { + jump->flags |= PATCH_B; + if (jump->flags & IS_COND) + inst[0] ^= (1 << 28); + else + inst[0] = BICC | DA(0x8); + inst[1] = NOP; + jump->addr = (sljit_uw)inst; + return inst + 1; + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + jump->addr = (sljit_uw)(code_ptr - 3); +#else + jump->addr = (sljit_uw)(code_ptr - 6); +#endif + code_ptr = detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size); + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + + if (jump->flags & PATCH_CALL) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000); + buf_ptr[0] = CALL | (addr & 0x3fffffff); + break; + } + if (jump->flags & PATCH_B) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP); + buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK); + break; + } + + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); + buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); +#else +#error "Implementation required" +#endif + } while (0); + jump = jump->next; + } + + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +/* Separates integer and floating point registers */ +#define GPR_REG 0x0f +#define DOUBLE_DATA 0x10 +#define SINGLE_DATA 0x12 + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define IMM_OP 0x00200 +#define SRC2_IMM 0x00400 + +#define REG_DEST 0x00800 +#define REG2_SOURCE 0x01000 +#define SLOW_SRC1 0x02000 +#define SLOW_SRC2 0x04000 +#define SLOW_DEST 0x08000 + +/* SET_FLAGS (0x10 << 19) also belong here! */ + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#include "sljitNativeSPARC_32.c" +#else +#include "sljitNativeSPARC_64.c" +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7; + compiler->local_size = local_size; + + if (local_size <= SIMM_MAX) { + FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS)); + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size)); + FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS)); + } + + /* Arguments are in their appropriate registers. */ + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + if (op != SLJIT_MOV || !FAST_IS_REG(src)) { + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + src = SLJIT_R0; + } + + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS)); + return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define ARCH_32_64(a, b) a +#else +#define ARCH_32_64(a, b) b +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), +/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), +/* u b s */ OPC1(3) | OPC3(0x05) /* stb */, +/* u b l */ OPC1(3) | OPC3(0x01) /* ldub */, +/* u h s */ OPC1(3) | OPC3(0x06) /* sth */, +/* u h l */ OPC1(3) | OPC3(0x02) /* lduh */, +/* u i s */ OPC1(3) | OPC3(0x04) /* stw */, +/* u i l */ OPC1(3) | OPC3(0x00) /* lduw */, + +/* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), +/* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), +/* s b s */ OPC1(3) | OPC3(0x05) /* stb */, +/* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */, +/* s h s */ OPC1(3) | OPC3(0x06) /* sth */, +/* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */, +/* s i s */ OPC1(3) | OPC3(0x04) /* stw */, +/* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */), + +/* d s */ OPC1(3) | OPC3(0x27), +/* d l */ OPC1(3) | OPC3(0x23), +/* s s */ OPC1(3) | OPC3(0x24), +/* s l */ OPC1(3) | OPC3(0x20), +}; + +#undef ARCH_32_64 + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) { + if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) + || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) { + /* Works for both absoulte and relative addresses (immediate case). */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] + | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)) + | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)), + ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS)); + return -1; + } + } + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* Simple operation except for updates. */ + if (arg & OFFS_REG_MASK) { + argw &= 0x3; + SLJIT_ASSERT(argw); + next_argw &= 0x3; + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw) + return 1; + return 0; + } + + if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) + return 1; + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si base, arg2, delay_slot; + sljit_ins dest; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + base = arg & REG_MASK; + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + SLJIT_ASSERT(argw != 0); + + /* Using the cache. */ + if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw)) + arg2 = TMP_REG3; + else { + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + arg2 = TMP_REG3; + } + else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg)) + arg2 = reg; + else /* It must be a mov operation, so tmp1 must be free to use. */ + arg2 = TMP_REG1; + FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2))); + } + } + else { + /* Using the cache. */ + if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + arg2 = TMP_REG3; + } else { + if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + arg2 = TMP_REG3; + } + else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base) + arg2 = reg; + else /* It must be a mov operation, so tmp1 must be free to use. */ + arg2 = TMP_REG1; + FAIL_IF(load_immediate(compiler, arg2, argw)); + } + } + + dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)); + delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS; + if (!base) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot); + if (!(flags & WRITE_BACK)) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot); + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot)); + return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + } + else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) + src1_r = src1; + else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1_r = TMP_REG1; + } + else + src1_r = 0; + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (FAST_IS_REG(src2)) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else if (src2 & SLJIT_IMM) { + if (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); + src2_r = sugg_src2_r; + } + else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } + } + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + src2_r = sugg_src2_r; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + SLJIT_ASSERT(src2_r == TMP_REG2); + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, flags, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, TA, UNMOVABLE_INS); + case SLJIT_NOP: + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_LUMUL: + case SLJIT_LSMUL: +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1)); +#else +#error "Implementation required" +#endif + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if ((op | 0x2) == SLJIT_UDIVI) + FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); + else { + FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); + } + if (op <= SLJIT_SDIVMOD) + FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + if (op >= SLJIT_UDIVI) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1))); + return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)); +#else +#error "Implementation required" +#endif + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_NOT: + case SLJIT_CLZ: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_ADD: + case SLJIT_ADDC: + case SLJIT_MUL: + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if (src2 & SLJIT_IMM) + src2w &= 0x1f; +#else + SLJIT_ASSERT_STOP(); +#endif + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg << 1; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) +#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw)) + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + src = TMP_FREG1; + } + else + src <<= 1; + + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS)); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) { + FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET); + } + + /* Store the integer value from a VFP register. */ + return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + + if (src & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + srcw = (sljit_si)srcw; +#endif + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + if (FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); + src = SLJIT_MEM1(SLJIT_SP); + srcw = FLOAT_TMP_MEM_OFFSET; + } + + FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + src1 = TMP_FREG1; + } + else + src1 <<= 1; + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + src2 = TMP_FREG2; + } + else + src2 <<= 1; + + return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) + op ^= SLJIT_SINGLE_OP; + + dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); + src = dst_r; + } + else + src <<= 1; + + switch (GET_OPCODE(op)) { + case SLJIT_DMOV: + if (src != dst_r) { + if (dst_r != TMP_FREG1) { + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS)); + if (!(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); + } + else + dst_r = src; + } + break; + case SLJIT_DNEG: + FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS)); + if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); + break; + case SLJIT_DABS: + FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS)); + if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); + break; + case SLJIT_CONVD_FROMS: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS)); + op ^= SLJIT_SINGLE_OP; + break; + } + + if (dst & SLJIT_MEM) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= SLOW_SRC1; + } + else + src1 <<= 1; + + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= SLOW_SRC2; + } + else + src2 <<= 1; + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & SLOW_SRC1) + src1 = TMP_FREG1; + if (flags & SLOW_SRC2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_DSUB: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_DMUL: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_DDIV: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + } + + if (dst_r == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef SELECT_FOP + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK))); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_LINK, srcw)); + + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS)); + return push_inst(compiler, NOP, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + compiler->delay_slot = UNMOVABLE_INS; + return label; +} + +static sljit_ins get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + case SLJIT_MUL_NOT_OVERFLOW: + case SLJIT_D_NOT_EQUAL: /* Unordered. */ + return DA(0x1); + + case SLJIT_NOT_EQUAL: + case SLJIT_MUL_OVERFLOW: + case SLJIT_D_EQUAL: + return DA(0x9); + + case SLJIT_LESS: + case SLJIT_D_GREATER: /* Unordered. */ + return DA(0x5); + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_LESS_EQUAL: + return DA(0xd); + + case SLJIT_GREATER: + case SLJIT_D_GREATER_EQUAL: /* Unordered. */ + return DA(0xc); + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS: + return DA(0x4); + + case SLJIT_SIG_LESS: + return DA(0x3); + + case SLJIT_SIG_GREATER_EQUAL: + return DA(0xb); + + case SLJIT_SIG_GREATER: + return DA(0xa); + + case SLJIT_SIG_LESS_EQUAL: + return DA(0x2); + + case SLJIT_OVERFLOW: + case SLJIT_D_UNORDERED: + return DA(0x7); + + case SLJIT_NOT_OVERFLOW: + case SLJIT_D_ORDERED: + return DA(0xf); + + default: + SLJIT_ASSERT_STOP(); + return DA(0x8); + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type < SLJIT_D_EQUAL) { + jump->flags |= IS_COND; + if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) + jump->flags |= IS_MOVABLE; +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); +#else +#error "Implementation required" +#endif + } + else if (type < SLJIT_JUMP) { + jump->flags |= IS_COND; + if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET)) + jump->flags |= IS_MOVABLE; +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); +#else +#error "Implementation required" +#endif + } else { + if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_CALL; + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump = NULL; + sljit_si src_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + src_r = src; + else if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR); + jump->u.target = srcw; + if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_CALL; + + FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + src_r = TMP_REG2; + } + else { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + src_r = TMP_REG2; + } + + FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); + if (jump) + jump->addr = compiler->size; + return push_inst(compiler, NOP, UNMOVABLE_INS); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + op = GET_OPCODE(op); + reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + type &= 0xff; + if (type < SLJIT_D_EQUAL) + FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); + + FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS)); + + if (op >= SLJIT_ADD) + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + + return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; +#else +#error "Implementation required" +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + sljit_si reg; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); + return const_; +} diff --git a/pcre2/src/sljit/sljitNativeTILEGX-encoder.c b/pcre2/src/sljit/sljitNativeTILEGX-encoder.c new file mode 100644 index 000000000..719632908 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeTILEGX-encoder.c @@ -0,0 +1,10159 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* This code is owned by Tilera Corporation, and distributed as part + of multiple projects. In sljit, the code is under BSD licence. */ + +#include +#include +#include +#define BFD_RELOC(x) R_##x + +/* Special registers. */ +#define TREG_LR 55 +#define TREG_SN 56 +#define TREG_ZERO 63 + +/* Canonical name of each register. */ +const char *const tilegx_register_names[] = +{ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", + "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", + "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero" +}; + +enum +{ + R_NONE = 0, + R_TILEGX_NONE = 0, + R_TILEGX_64 = 1, + R_TILEGX_32 = 2, + R_TILEGX_16 = 3, + R_TILEGX_8 = 4, + R_TILEGX_64_PCREL = 5, + R_TILEGX_32_PCREL = 6, + R_TILEGX_16_PCREL = 7, + R_TILEGX_8_PCREL = 8, + R_TILEGX_HW0 = 9, + R_TILEGX_HW1 = 10, + R_TILEGX_HW2 = 11, + R_TILEGX_HW3 = 12, + R_TILEGX_HW0_LAST = 13, + R_TILEGX_HW1_LAST = 14, + R_TILEGX_HW2_LAST = 15, + R_TILEGX_COPY = 16, + R_TILEGX_GLOB_DAT = 17, + R_TILEGX_JMP_SLOT = 18, + R_TILEGX_RELATIVE = 19, + R_TILEGX_BROFF_X1 = 20, + R_TILEGX_JUMPOFF_X1 = 21, + R_TILEGX_JUMPOFF_X1_PLT = 22, + R_TILEGX_IMM8_X0 = 23, + R_TILEGX_IMM8_Y0 = 24, + R_TILEGX_IMM8_X1 = 25, + R_TILEGX_IMM8_Y1 = 26, + R_TILEGX_DEST_IMM8_X1 = 27, + R_TILEGX_MT_IMM14_X1 = 28, + R_TILEGX_MF_IMM14_X1 = 29, + R_TILEGX_MMSTART_X0 = 30, + R_TILEGX_MMEND_X0 = 31, + R_TILEGX_SHAMT_X0 = 32, + R_TILEGX_SHAMT_X1 = 33, + R_TILEGX_SHAMT_Y0 = 34, + R_TILEGX_SHAMT_Y1 = 35, + R_TILEGX_IMM16_X0_HW0 = 36, + R_TILEGX_IMM16_X1_HW0 = 37, + R_TILEGX_IMM16_X0_HW1 = 38, + R_TILEGX_IMM16_X1_HW1 = 39, + R_TILEGX_IMM16_X0_HW2 = 40, + R_TILEGX_IMM16_X1_HW2 = 41, + R_TILEGX_IMM16_X0_HW3 = 42, + R_TILEGX_IMM16_X1_HW3 = 43, + R_TILEGX_IMM16_X0_HW0_LAST = 44, + R_TILEGX_IMM16_X1_HW0_LAST = 45, + R_TILEGX_IMM16_X0_HW1_LAST = 46, + R_TILEGX_IMM16_X1_HW1_LAST = 47, + R_TILEGX_IMM16_X0_HW2_LAST = 48, + R_TILEGX_IMM16_X1_HW2_LAST = 49, + R_TILEGX_IMM16_X0_HW0_PCREL = 50, + R_TILEGX_IMM16_X1_HW0_PCREL = 51, + R_TILEGX_IMM16_X0_HW1_PCREL = 52, + R_TILEGX_IMM16_X1_HW1_PCREL = 53, + R_TILEGX_IMM16_X0_HW2_PCREL = 54, + R_TILEGX_IMM16_X1_HW2_PCREL = 55, + R_TILEGX_IMM16_X0_HW3_PCREL = 56, + R_TILEGX_IMM16_X1_HW3_PCREL = 57, + R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58, + R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59, + R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60, + R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61, + R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62, + R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63, + R_TILEGX_IMM16_X0_HW0_GOT = 64, + R_TILEGX_IMM16_X1_HW0_GOT = 65, + + R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66, + R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67, + R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68, + R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69, + R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70, + R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71, + + R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72, + R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73, + R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74, + R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75, + R_TILEGX_IMM16_X0_HW0_TLS_GD = 78, + R_TILEGX_IMM16_X1_HW0_TLS_GD = 79, + R_TILEGX_IMM16_X0_HW0_TLS_LE = 80, + R_TILEGX_IMM16_X1_HW0_TLS_LE = 81, + R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85, + R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89, + R_TILEGX_IMM16_X0_HW0_TLS_IE = 92, + R_TILEGX_IMM16_X1_HW0_TLS_IE = 93, + + R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94, + R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95, + R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96, + R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97, + R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98, + R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99, + + R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103, + R_TILEGX_TLS_DTPMOD64 = 106, + R_TILEGX_TLS_DTPOFF64 = 107, + R_TILEGX_TLS_TPOFF64 = 108, + R_TILEGX_TLS_DTPMOD32 = 109, + R_TILEGX_TLS_DTPOFF32 = 110, + R_TILEGX_TLS_TPOFF32 = 111, + R_TILEGX_TLS_GD_CALL = 112, + R_TILEGX_IMM8_X0_TLS_GD_ADD = 113, + R_TILEGX_IMM8_X1_TLS_GD_ADD = 114, + R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115, + R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116, + R_TILEGX_TLS_IE_LOAD = 117, + R_TILEGX_IMM8_X0_TLS_ADD = 118, + R_TILEGX_IMM8_X1_TLS_ADD = 119, + R_TILEGX_IMM8_Y0_TLS_ADD = 120, + R_TILEGX_IMM8_Y1_TLS_ADD = 121, + R_TILEGX_GNU_VTINHERIT = 128, + R_TILEGX_GNU_VTENTRY = 129, + R_TILEGX_IRELATIVE = 130, + R_TILEGX_NUM = 131 +}; + +typedef enum +{ + TILEGX_PIPELINE_X0, + TILEGX_PIPELINE_X1, + TILEGX_PIPELINE_Y0, + TILEGX_PIPELINE_Y1, + TILEGX_PIPELINE_Y2, +} tilegx_pipeline; + +typedef unsigned long long tilegx_bundle_bits; + +/* These are the bits that determine if a bundle is in the X encoding. */ +#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62) + +enum +{ + /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */ + TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3, + + /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */ + TILEGX_NUM_PIPELINE_ENCODINGS = 5, + + /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */ + TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3, + + /* Instructions take this many bytes. */ + TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES, + + /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */ + TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3, + + /* Bundles should be aligned modulo this number of bytes. */ + TILEGX_BUNDLE_ALIGNMENT_IN_BYTES = + (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES), + + /* Number of registers (some are magic, such as network I/O). */ + TILEGX_NUM_REGISTERS = 64, +}; + +/* Make a few "tile_" variables to simplify common code between + architectures. */ + +typedef tilegx_bundle_bits tile_bundle_bits; +#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES +#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES +#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ + TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES + +/* 64-bit pattern for a { bpt ; nop } bundle. */ +#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL + +typedef enum +{ + TILEGX_OP_TYPE_REGISTER, + TILEGX_OP_TYPE_IMMEDIATE, + TILEGX_OP_TYPE_ADDRESS, + TILEGX_OP_TYPE_SPR +} tilegx_operand_type; + +struct tilegx_operand +{ + /* Is this operand a register, immediate or address? */ + tilegx_operand_type type; + + /* The default relocation type for this operand. */ + signed int default_reloc : 16; + + /* How many bits is this value? (used for range checking) */ + unsigned int num_bits : 5; + + /* Is the value signed? (used for range checking) */ + unsigned int is_signed : 1; + + /* Is this operand a source register? */ + unsigned int is_src_reg : 1; + + /* Is this operand written? (i.e. is it a destination register) */ + unsigned int is_dest_reg : 1; + + /* Is this operand PC-relative? */ + unsigned int is_pc_relative : 1; + + /* By how many bits do we right shift the value before inserting? */ + unsigned int rightshift : 2; + + /* Return the bits for this operand to be ORed into an existing bundle. */ + tilegx_bundle_bits (*insert) (int op); + + /* Extract this operand and return it. */ + unsigned int (*extract) (tilegx_bundle_bits bundle); +}; + +typedef enum +{ + TILEGX_OPC_BPT, + TILEGX_OPC_INFO, + TILEGX_OPC_INFOL, + TILEGX_OPC_LD4S_TLS, + TILEGX_OPC_LD_TLS, + TILEGX_OPC_MOVE, + TILEGX_OPC_MOVEI, + TILEGX_OPC_MOVELI, + TILEGX_OPC_PREFETCH, + TILEGX_OPC_PREFETCH_ADD_L1, + TILEGX_OPC_PREFETCH_ADD_L1_FAULT, + TILEGX_OPC_PREFETCH_ADD_L2, + TILEGX_OPC_PREFETCH_ADD_L2_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_L1, + TILEGX_OPC_PREFETCH_L1_FAULT, + TILEGX_OPC_PREFETCH_L2, + TILEGX_OPC_PREFETCH_L2_FAULT, + TILEGX_OPC_PREFETCH_L3, + TILEGX_OPC_PREFETCH_L3_FAULT, + TILEGX_OPC_RAISE, + TILEGX_OPC_ADD, + TILEGX_OPC_ADDI, + TILEGX_OPC_ADDLI, + TILEGX_OPC_ADDX, + TILEGX_OPC_ADDXI, + TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXSC, + TILEGX_OPC_AND, + TILEGX_OPC_ANDI, + TILEGX_OPC_BEQZ, + TILEGX_OPC_BEQZT, + TILEGX_OPC_BFEXTS, + TILEGX_OPC_BFEXTU, + TILEGX_OPC_BFINS, + TILEGX_OPC_BGEZ, + TILEGX_OPC_BGEZT, + TILEGX_OPC_BGTZ, + TILEGX_OPC_BGTZT, + TILEGX_OPC_BLBC, + TILEGX_OPC_BLBCT, + TILEGX_OPC_BLBS, + TILEGX_OPC_BLBST, + TILEGX_OPC_BLEZ, + TILEGX_OPC_BLEZT, + TILEGX_OPC_BLTZ, + TILEGX_OPC_BLTZT, + TILEGX_OPC_BNEZ, + TILEGX_OPC_BNEZT, + TILEGX_OPC_CLZ, + TILEGX_OPC_CMOVEQZ, + TILEGX_OPC_CMOVNEZ, + TILEGX_OPC_CMPEQ, + TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPEXCH, + TILEGX_OPC_CMPEXCH4, + TILEGX_OPC_CMPLES, + TILEGX_OPC_CMPLEU, + TILEGX_OPC_CMPLTS, + TILEGX_OPC_CMPLTSI, + TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPLTUI, + TILEGX_OPC_CMPNE, + TILEGX_OPC_CMUL, + TILEGX_OPC_CMULA, + TILEGX_OPC_CMULAF, + TILEGX_OPC_CMULF, + TILEGX_OPC_CMULFR, + TILEGX_OPC_CMULH, + TILEGX_OPC_CMULHR, + TILEGX_OPC_CRC32_32, + TILEGX_OPC_CRC32_8, + TILEGX_OPC_CTZ, + TILEGX_OPC_DBLALIGN, + TILEGX_OPC_DBLALIGN2, + TILEGX_OPC_DBLALIGN4, + TILEGX_OPC_DBLALIGN6, + TILEGX_OPC_DRAIN, + TILEGX_OPC_DTLBPR, + TILEGX_OPC_EXCH, + TILEGX_OPC_EXCH4, + TILEGX_OPC_FDOUBLE_ADD_FLAGS, + TILEGX_OPC_FDOUBLE_ADDSUB, + TILEGX_OPC_FDOUBLE_MUL_FLAGS, + TILEGX_OPC_FDOUBLE_PACK1, + TILEGX_OPC_FDOUBLE_PACK2, + TILEGX_OPC_FDOUBLE_SUB_FLAGS, + TILEGX_OPC_FDOUBLE_UNPACK_MAX, + TILEGX_OPC_FDOUBLE_UNPACK_MIN, + TILEGX_OPC_FETCHADD, + TILEGX_OPC_FETCHADD4, + TILEGX_OPC_FETCHADDGEZ, + TILEGX_OPC_FETCHADDGEZ4, + TILEGX_OPC_FETCHAND, + TILEGX_OPC_FETCHAND4, + TILEGX_OPC_FETCHOR, + TILEGX_OPC_FETCHOR4, + TILEGX_OPC_FINV, + TILEGX_OPC_FLUSH, + TILEGX_OPC_FLUSHWB, + TILEGX_OPC_FNOP, + TILEGX_OPC_FSINGLE_ADD1, + TILEGX_OPC_FSINGLE_ADDSUB2, + TILEGX_OPC_FSINGLE_MUL1, + TILEGX_OPC_FSINGLE_MUL2, + TILEGX_OPC_FSINGLE_PACK1, + TILEGX_OPC_FSINGLE_PACK2, + TILEGX_OPC_FSINGLE_SUB1, + TILEGX_OPC_ICOH, + TILEGX_OPC_ILL, + TILEGX_OPC_INV, + TILEGX_OPC_IRET, + TILEGX_OPC_J, + TILEGX_OPC_JAL, + TILEGX_OPC_JALR, + TILEGX_OPC_JALRP, + TILEGX_OPC_JR, + TILEGX_OPC_JRP, + TILEGX_OPC_LD, + TILEGX_OPC_LD1S, + TILEGX_OPC_LD1S_ADD, + TILEGX_OPC_LD1U, + TILEGX_OPC_LD1U_ADD, + TILEGX_OPC_LD2S, + TILEGX_OPC_LD2S_ADD, + TILEGX_OPC_LD2U, + TILEGX_OPC_LD2U_ADD, + TILEGX_OPC_LD4S, + TILEGX_OPC_LD4S_ADD, + TILEGX_OPC_LD4U, + TILEGX_OPC_LD4U_ADD, + TILEGX_OPC_LD_ADD, + TILEGX_OPC_LDNA, + TILEGX_OPC_LDNA_ADD, + TILEGX_OPC_LDNT, + TILEGX_OPC_LDNT1S, + TILEGX_OPC_LDNT1S_ADD, + TILEGX_OPC_LDNT1U, + TILEGX_OPC_LDNT1U_ADD, + TILEGX_OPC_LDNT2S, + TILEGX_OPC_LDNT2S_ADD, + TILEGX_OPC_LDNT2U, + TILEGX_OPC_LDNT2U_ADD, + TILEGX_OPC_LDNT4S, + TILEGX_OPC_LDNT4S_ADD, + TILEGX_OPC_LDNT4U, + TILEGX_OPC_LDNT4U_ADD, + TILEGX_OPC_LDNT_ADD, + TILEGX_OPC_LNK, + TILEGX_OPC_MF, + TILEGX_OPC_MFSPR, + TILEGX_OPC_MM, + TILEGX_OPC_MNZ, + TILEGX_OPC_MTSPR, + TILEGX_OPC_MUL_HS_HS, + TILEGX_OPC_MUL_HS_HU, + TILEGX_OPC_MUL_HS_LS, + TILEGX_OPC_MUL_HS_LU, + TILEGX_OPC_MUL_HU_HU, + TILEGX_OPC_MUL_HU_LS, + TILEGX_OPC_MUL_HU_LU, + TILEGX_OPC_MUL_LS_LS, + TILEGX_OPC_MUL_LS_LU, + TILEGX_OPC_MUL_LU_LU, + TILEGX_OPC_MULA_HS_HS, + TILEGX_OPC_MULA_HS_HU, + TILEGX_OPC_MULA_HS_LS, + TILEGX_OPC_MULA_HS_LU, + TILEGX_OPC_MULA_HU_HU, + TILEGX_OPC_MULA_HU_LS, + TILEGX_OPC_MULA_HU_LU, + TILEGX_OPC_MULA_LS_LS, + TILEGX_OPC_MULA_LS_LU, + TILEGX_OPC_MULA_LU_LU, + TILEGX_OPC_MULAX, + TILEGX_OPC_MULX, + TILEGX_OPC_MZ, + TILEGX_OPC_NAP, + TILEGX_OPC_NOP, + TILEGX_OPC_NOR, + TILEGX_OPC_OR, + TILEGX_OPC_ORI, + TILEGX_OPC_PCNT, + TILEGX_OPC_REVBITS, + TILEGX_OPC_REVBYTES, + TILEGX_OPC_ROTL, + TILEGX_OPC_ROTLI, + TILEGX_OPC_SHL, + TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADDX, + TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADDX, + TILEGX_OPC_SHLI, + TILEGX_OPC_SHLX, + TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRS, + TILEGX_OPC_SHRSI, + TILEGX_OPC_SHRU, + TILEGX_OPC_SHRUI, + TILEGX_OPC_SHRUX, + TILEGX_OPC_SHRUXI, + TILEGX_OPC_SHUFFLEBYTES, + TILEGX_OPC_ST, + TILEGX_OPC_ST1, + TILEGX_OPC_ST1_ADD, + TILEGX_OPC_ST2, + TILEGX_OPC_ST2_ADD, + TILEGX_OPC_ST4, + TILEGX_OPC_ST4_ADD, + TILEGX_OPC_ST_ADD, + TILEGX_OPC_STNT, + TILEGX_OPC_STNT1, + TILEGX_OPC_STNT1_ADD, + TILEGX_OPC_STNT2, + TILEGX_OPC_STNT2_ADD, + TILEGX_OPC_STNT4, + TILEGX_OPC_STNT4_ADD, + TILEGX_OPC_STNT_ADD, + TILEGX_OPC_SUB, + TILEGX_OPC_SUBX, + TILEGX_OPC_SUBXSC, + TILEGX_OPC_SWINT0, + TILEGX_OPC_SWINT1, + TILEGX_OPC_SWINT2, + TILEGX_OPC_SWINT3, + TILEGX_OPC_TBLIDXB0, + TILEGX_OPC_TBLIDXB1, + TILEGX_OPC_TBLIDXB2, + TILEGX_OPC_TBLIDXB3, + TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADDI, + TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADIFFU, + TILEGX_OPC_V1AVGU, + TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQI, + TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTSI, + TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTUI, + TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1DDOTPU, + TILEGX_OPC_V1DDOTPUA, + TILEGX_OPC_V1DDOTPUS, + TILEGX_OPC_V1DDOTPUSA, + TILEGX_OPC_V1DOTP, + TILEGX_OPC_V1DOTPA, + TILEGX_OPC_V1DOTPU, + TILEGX_OPC_V1DOTPUA, + TILEGX_OPC_V1DOTPUS, + TILEGX_OPC_V1DOTPUSA, + TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1MAXU, + TILEGX_OPC_V1MAXUI, + TILEGX_OPC_V1MINU, + TILEGX_OPC_V1MINUI, + TILEGX_OPC_V1MNZ, + TILEGX_OPC_V1MULTU, + TILEGX_OPC_V1MULU, + TILEGX_OPC_V1MULUS, + TILEGX_OPC_V1MZ, + TILEGX_OPC_V1SADAU, + TILEGX_OPC_V1SADU, + TILEGX_OPC_V1SHL, + TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRS, + TILEGX_OPC_V1SHRSI, + TILEGX_OPC_V1SHRU, + TILEGX_OPC_V1SHRUI, + TILEGX_OPC_V1SUB, + TILEGX_OPC_V1SUBUC, + TILEGX_OPC_V2ADD, + TILEGX_OPC_V2ADDI, + TILEGX_OPC_V2ADDSC, + TILEGX_OPC_V2ADIFFS, + TILEGX_OPC_V2AVGS, + TILEGX_OPC_V2CMPEQ, + TILEGX_OPC_V2CMPEQI, + TILEGX_OPC_V2CMPLES, + TILEGX_OPC_V2CMPLEU, + TILEGX_OPC_V2CMPLTS, + TILEGX_OPC_V2CMPLTSI, + TILEGX_OPC_V2CMPLTU, + TILEGX_OPC_V2CMPLTUI, + TILEGX_OPC_V2CMPNE, + TILEGX_OPC_V2DOTP, + TILEGX_OPC_V2DOTPA, + TILEGX_OPC_V2INT_H, + TILEGX_OPC_V2INT_L, + TILEGX_OPC_V2MAXS, + TILEGX_OPC_V2MAXSI, + TILEGX_OPC_V2MINS, + TILEGX_OPC_V2MINSI, + TILEGX_OPC_V2MNZ, + TILEGX_OPC_V2MULFSC, + TILEGX_OPC_V2MULS, + TILEGX_OPC_V2MULTS, + TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, + TILEGX_OPC_V2PACKL, + TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SADAS, + TILEGX_OPC_V2SADAU, + TILEGX_OPC_V2SADS, + TILEGX_OPC_V2SADU, + TILEGX_OPC_V2SHL, + TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHLSC, + TILEGX_OPC_V2SHRS, + TILEGX_OPC_V2SHRSI, + TILEGX_OPC_V2SHRU, + TILEGX_OPC_V2SHRUI, + TILEGX_OPC_V2SUB, + TILEGX_OPC_V2SUBSC, + TILEGX_OPC_V4ADD, + TILEGX_OPC_V4ADDSC, + TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, + TILEGX_OPC_V4PACKSC, + TILEGX_OPC_V4SHL, + TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHRS, + TILEGX_OPC_V4SHRU, + TILEGX_OPC_V4SUB, + TILEGX_OPC_V4SUBSC, + TILEGX_OPC_WH64, + TILEGX_OPC_XOR, + TILEGX_OPC_XORI, + TILEGX_OPC_NONE +} tilegx_mnemonic; + +enum +{ + TILEGX_MAX_OPERANDS = 4 /* bfexts */ +}; + +struct tilegx_opcode +{ + /* The opcode mnemonic, e.g. "add" */ + const char *name; + + /* The enum value for this mnemonic. */ + tilegx_mnemonic mnemonic; + + /* A bit mask of which of the five pipes this instruction + is compatible with: + X0 0x01 + X1 0x02 + Y0 0x04 + Y1 0x08 + Y2 0x10 */ + unsigned char pipes; + + /* How many operands are there? */ + unsigned char num_operands; + + /* Which register does this write implicitly, or TREG_ZERO if none? */ + unsigned char implicitly_written_register; + + /* Can this be bundled with other instructions (almost always true). */ + unsigned char can_bundle; + + /* The description of the operands. Each of these is an + * index into the tilegx_operands[] table. */ + unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS]; + + /* A mask of which bits have predefined values for each pipeline. + * This is useful for disassembly. */ + tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS]; + + /* For each bit set in fixed_bit_masks, what the value is for this + * instruction. */ + tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS]; +}; + +/* Used for non-textual disassembly into structs. */ +struct tilegx_decoded_instruction +{ + const struct tilegx_opcode *opcode; + const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS]; + long long operand_values[TILEGX_MAX_OPERANDS]; +}; + +enum +{ + ADDI_IMM8_OPCODE_X0 = 1, + ADDI_IMM8_OPCODE_X1 = 1, + ADDI_OPCODE_Y0 = 0, + ADDI_OPCODE_Y1 = 1, + ADDLI_OPCODE_X0 = 1, + ADDLI_OPCODE_X1 = 0, + ADDXI_IMM8_OPCODE_X0 = 2, + ADDXI_IMM8_OPCODE_X1 = 2, + ADDXI_OPCODE_Y0 = 1, + ADDXI_OPCODE_Y1 = 2, + ADDXLI_OPCODE_X0 = 2, + ADDXLI_OPCODE_X1 = 1, + ADDXSC_RRR_0_OPCODE_X0 = 1, + ADDXSC_RRR_0_OPCODE_X1 = 1, + ADDX_RRR_0_OPCODE_X0 = 2, + ADDX_RRR_0_OPCODE_X1 = 2, + ADDX_RRR_0_OPCODE_Y0 = 0, + ADDX_SPECIAL_0_OPCODE_Y1 = 0, + ADD_RRR_0_OPCODE_X0 = 3, + ADD_RRR_0_OPCODE_X1 = 3, + ADD_RRR_0_OPCODE_Y0 = 1, + ADD_SPECIAL_0_OPCODE_Y1 = 1, + ANDI_IMM8_OPCODE_X0 = 3, + ANDI_IMM8_OPCODE_X1 = 3, + ANDI_OPCODE_Y0 = 2, + ANDI_OPCODE_Y1 = 3, + AND_RRR_0_OPCODE_X0 = 4, + AND_RRR_0_OPCODE_X1 = 4, + AND_RRR_5_OPCODE_Y0 = 0, + AND_RRR_5_OPCODE_Y1 = 0, + BEQZT_BRANCH_OPCODE_X1 = 16, + BEQZ_BRANCH_OPCODE_X1 = 17, + BFEXTS_BF_OPCODE_X0 = 4, + BFEXTU_BF_OPCODE_X0 = 5, + BFINS_BF_OPCODE_X0 = 6, + BF_OPCODE_X0 = 3, + BGEZT_BRANCH_OPCODE_X1 = 18, + BGEZ_BRANCH_OPCODE_X1 = 19, + BGTZT_BRANCH_OPCODE_X1 = 20, + BGTZ_BRANCH_OPCODE_X1 = 21, + BLBCT_BRANCH_OPCODE_X1 = 22, + BLBC_BRANCH_OPCODE_X1 = 23, + BLBST_BRANCH_OPCODE_X1 = 24, + BLBS_BRANCH_OPCODE_X1 = 25, + BLEZT_BRANCH_OPCODE_X1 = 26, + BLEZ_BRANCH_OPCODE_X1 = 27, + BLTZT_BRANCH_OPCODE_X1 = 28, + BLTZ_BRANCH_OPCODE_X1 = 29, + BNEZT_BRANCH_OPCODE_X1 = 30, + BNEZ_BRANCH_OPCODE_X1 = 31, + BRANCH_OPCODE_X1 = 2, + CMOVEQZ_RRR_0_OPCODE_X0 = 5, + CMOVEQZ_RRR_4_OPCODE_Y0 = 0, + CMOVNEZ_RRR_0_OPCODE_X0 = 6, + CMOVNEZ_RRR_4_OPCODE_Y0 = 1, + CMPEQI_IMM8_OPCODE_X0 = 4, + CMPEQI_IMM8_OPCODE_X1 = 4, + CMPEQI_OPCODE_Y0 = 3, + CMPEQI_OPCODE_Y1 = 4, + CMPEQ_RRR_0_OPCODE_X0 = 7, + CMPEQ_RRR_0_OPCODE_X1 = 5, + CMPEQ_RRR_3_OPCODE_Y0 = 0, + CMPEQ_RRR_3_OPCODE_Y1 = 2, + CMPEXCH4_RRR_0_OPCODE_X1 = 6, + CMPEXCH_RRR_0_OPCODE_X1 = 7, + CMPLES_RRR_0_OPCODE_X0 = 8, + CMPLES_RRR_0_OPCODE_X1 = 8, + CMPLES_RRR_2_OPCODE_Y0 = 0, + CMPLES_RRR_2_OPCODE_Y1 = 0, + CMPLEU_RRR_0_OPCODE_X0 = 9, + CMPLEU_RRR_0_OPCODE_X1 = 9, + CMPLEU_RRR_2_OPCODE_Y0 = 1, + CMPLEU_RRR_2_OPCODE_Y1 = 1, + CMPLTSI_IMM8_OPCODE_X0 = 5, + CMPLTSI_IMM8_OPCODE_X1 = 5, + CMPLTSI_OPCODE_Y0 = 4, + CMPLTSI_OPCODE_Y1 = 5, + CMPLTS_RRR_0_OPCODE_X0 = 10, + CMPLTS_RRR_0_OPCODE_X1 = 10, + CMPLTS_RRR_2_OPCODE_Y0 = 2, + CMPLTS_RRR_2_OPCODE_Y1 = 2, + CMPLTUI_IMM8_OPCODE_X0 = 6, + CMPLTUI_IMM8_OPCODE_X1 = 6, + CMPLTU_RRR_0_OPCODE_X0 = 11, + CMPLTU_RRR_0_OPCODE_X1 = 11, + CMPLTU_RRR_2_OPCODE_Y0 = 3, + CMPLTU_RRR_2_OPCODE_Y1 = 3, + CMPNE_RRR_0_OPCODE_X0 = 12, + CMPNE_RRR_0_OPCODE_X1 = 12, + CMPNE_RRR_3_OPCODE_Y0 = 1, + CMPNE_RRR_3_OPCODE_Y1 = 3, + CMULAF_RRR_0_OPCODE_X0 = 13, + CMULA_RRR_0_OPCODE_X0 = 14, + CMULFR_RRR_0_OPCODE_X0 = 15, + CMULF_RRR_0_OPCODE_X0 = 16, + CMULHR_RRR_0_OPCODE_X0 = 17, + CMULH_RRR_0_OPCODE_X0 = 18, + CMUL_RRR_0_OPCODE_X0 = 19, + CNTLZ_UNARY_OPCODE_X0 = 1, + CNTLZ_UNARY_OPCODE_Y0 = 1, + CNTTZ_UNARY_OPCODE_X0 = 2, + CNTTZ_UNARY_OPCODE_Y0 = 2, + CRC32_32_RRR_0_OPCODE_X0 = 20, + CRC32_8_RRR_0_OPCODE_X0 = 21, + DBLALIGN2_RRR_0_OPCODE_X0 = 22, + DBLALIGN2_RRR_0_OPCODE_X1 = 13, + DBLALIGN4_RRR_0_OPCODE_X0 = 23, + DBLALIGN4_RRR_0_OPCODE_X1 = 14, + DBLALIGN6_RRR_0_OPCODE_X0 = 24, + DBLALIGN6_RRR_0_OPCODE_X1 = 15, + DBLALIGN_RRR_0_OPCODE_X0 = 25, + DRAIN_UNARY_OPCODE_X1 = 1, + DTLBPR_UNARY_OPCODE_X1 = 2, + EXCH4_RRR_0_OPCODE_X1 = 16, + EXCH_RRR_0_OPCODE_X1 = 17, + FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26, + FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27, + FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28, + FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29, + FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30, + FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31, + FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32, + FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33, + FETCHADD4_RRR_0_OPCODE_X1 = 18, + FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19, + FETCHADDGEZ_RRR_0_OPCODE_X1 = 20, + FETCHADD_RRR_0_OPCODE_X1 = 21, + FETCHAND4_RRR_0_OPCODE_X1 = 22, + FETCHAND_RRR_0_OPCODE_X1 = 23, + FETCHOR4_RRR_0_OPCODE_X1 = 24, + FETCHOR_RRR_0_OPCODE_X1 = 25, + FINV_UNARY_OPCODE_X1 = 3, + FLUSHWB_UNARY_OPCODE_X1 = 4, + FLUSH_UNARY_OPCODE_X1 = 5, + FNOP_UNARY_OPCODE_X0 = 3, + FNOP_UNARY_OPCODE_X1 = 6, + FNOP_UNARY_OPCODE_Y0 = 3, + FNOP_UNARY_OPCODE_Y1 = 8, + FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34, + FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35, + FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36, + FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37, + FSINGLE_PACK1_UNARY_OPCODE_X0 = 4, + FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4, + FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38, + FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39, + ICOH_UNARY_OPCODE_X1 = 7, + ILL_UNARY_OPCODE_X1 = 8, + ILL_UNARY_OPCODE_Y1 = 9, + IMM8_OPCODE_X0 = 4, + IMM8_OPCODE_X1 = 3, + INV_UNARY_OPCODE_X1 = 9, + IRET_UNARY_OPCODE_X1 = 10, + JALRP_UNARY_OPCODE_X1 = 11, + JALRP_UNARY_OPCODE_Y1 = 10, + JALR_UNARY_OPCODE_X1 = 12, + JALR_UNARY_OPCODE_Y1 = 11, + JAL_JUMP_OPCODE_X1 = 0, + JRP_UNARY_OPCODE_X1 = 13, + JRP_UNARY_OPCODE_Y1 = 12, + JR_UNARY_OPCODE_X1 = 14, + JR_UNARY_OPCODE_Y1 = 13, + JUMP_OPCODE_X1 = 4, + J_JUMP_OPCODE_X1 = 1, + LD1S_ADD_IMM8_OPCODE_X1 = 7, + LD1S_OPCODE_Y2 = 0, + LD1S_UNARY_OPCODE_X1 = 15, + LD1U_ADD_IMM8_OPCODE_X1 = 8, + LD1U_OPCODE_Y2 = 1, + LD1U_UNARY_OPCODE_X1 = 16, + LD2S_ADD_IMM8_OPCODE_X1 = 9, + LD2S_OPCODE_Y2 = 2, + LD2S_UNARY_OPCODE_X1 = 17, + LD2U_ADD_IMM8_OPCODE_X1 = 10, + LD2U_OPCODE_Y2 = 3, + LD2U_UNARY_OPCODE_X1 = 18, + LD4S_ADD_IMM8_OPCODE_X1 = 11, + LD4S_OPCODE_Y2 = 1, + LD4S_UNARY_OPCODE_X1 = 19, + LD4U_ADD_IMM8_OPCODE_X1 = 12, + LD4U_OPCODE_Y2 = 2, + LD4U_UNARY_OPCODE_X1 = 20, + LDNA_UNARY_OPCODE_X1 = 21, + LDNT1S_ADD_IMM8_OPCODE_X1 = 13, + LDNT1S_UNARY_OPCODE_X1 = 22, + LDNT1U_ADD_IMM8_OPCODE_X1 = 14, + LDNT1U_UNARY_OPCODE_X1 = 23, + LDNT2S_ADD_IMM8_OPCODE_X1 = 15, + LDNT2S_UNARY_OPCODE_X1 = 24, + LDNT2U_ADD_IMM8_OPCODE_X1 = 16, + LDNT2U_UNARY_OPCODE_X1 = 25, + LDNT4S_ADD_IMM8_OPCODE_X1 = 17, + LDNT4S_UNARY_OPCODE_X1 = 26, + LDNT4U_ADD_IMM8_OPCODE_X1 = 18, + LDNT4U_UNARY_OPCODE_X1 = 27, + LDNT_ADD_IMM8_OPCODE_X1 = 19, + LDNT_UNARY_OPCODE_X1 = 28, + LD_ADD_IMM8_OPCODE_X1 = 20, + LD_OPCODE_Y2 = 3, + LD_UNARY_OPCODE_X1 = 29, + LNK_UNARY_OPCODE_X1 = 30, + LNK_UNARY_OPCODE_Y1 = 14, + LWNA_ADD_IMM8_OPCODE_X1 = 21, + MFSPR_IMM8_OPCODE_X1 = 22, + MF_UNARY_OPCODE_X1 = 31, + MM_BF_OPCODE_X0 = 7, + MNZ_RRR_0_OPCODE_X0 = 40, + MNZ_RRR_0_OPCODE_X1 = 26, + MNZ_RRR_4_OPCODE_Y0 = 2, + MNZ_RRR_4_OPCODE_Y1 = 2, + MODE_OPCODE_YA2 = 1, + MODE_OPCODE_YB2 = 2, + MODE_OPCODE_YC2 = 3, + MTSPR_IMM8_OPCODE_X1 = 23, + MULAX_RRR_0_OPCODE_X0 = 41, + MULAX_RRR_3_OPCODE_Y0 = 2, + MULA_HS_HS_RRR_0_OPCODE_X0 = 42, + MULA_HS_HS_RRR_9_OPCODE_Y0 = 0, + MULA_HS_HU_RRR_0_OPCODE_X0 = 43, + MULA_HS_LS_RRR_0_OPCODE_X0 = 44, + MULA_HS_LU_RRR_0_OPCODE_X0 = 45, + MULA_HU_HU_RRR_0_OPCODE_X0 = 46, + MULA_HU_HU_RRR_9_OPCODE_Y0 = 1, + MULA_HU_LS_RRR_0_OPCODE_X0 = 47, + MULA_HU_LU_RRR_0_OPCODE_X0 = 48, + MULA_LS_LS_RRR_0_OPCODE_X0 = 49, + MULA_LS_LS_RRR_9_OPCODE_Y0 = 2, + MULA_LS_LU_RRR_0_OPCODE_X0 = 50, + MULA_LU_LU_RRR_0_OPCODE_X0 = 51, + MULA_LU_LU_RRR_9_OPCODE_Y0 = 3, + MULX_RRR_0_OPCODE_X0 = 52, + MULX_RRR_3_OPCODE_Y0 = 3, + MUL_HS_HS_RRR_0_OPCODE_X0 = 53, + MUL_HS_HS_RRR_8_OPCODE_Y0 = 0, + MUL_HS_HU_RRR_0_OPCODE_X0 = 54, + MUL_HS_LS_RRR_0_OPCODE_X0 = 55, + MUL_HS_LU_RRR_0_OPCODE_X0 = 56, + MUL_HU_HU_RRR_0_OPCODE_X0 = 57, + MUL_HU_HU_RRR_8_OPCODE_Y0 = 1, + MUL_HU_LS_RRR_0_OPCODE_X0 = 58, + MUL_HU_LU_RRR_0_OPCODE_X0 = 59, + MUL_LS_LS_RRR_0_OPCODE_X0 = 60, + MUL_LS_LS_RRR_8_OPCODE_Y0 = 2, + MUL_LS_LU_RRR_0_OPCODE_X0 = 61, + MUL_LU_LU_RRR_0_OPCODE_X0 = 62, + MUL_LU_LU_RRR_8_OPCODE_Y0 = 3, + MZ_RRR_0_OPCODE_X0 = 63, + MZ_RRR_0_OPCODE_X1 = 27, + MZ_RRR_4_OPCODE_Y0 = 3, + MZ_RRR_4_OPCODE_Y1 = 3, + NAP_UNARY_OPCODE_X1 = 32, + NOP_UNARY_OPCODE_X0 = 5, + NOP_UNARY_OPCODE_X1 = 33, + NOP_UNARY_OPCODE_Y0 = 5, + NOP_UNARY_OPCODE_Y1 = 15, + NOR_RRR_0_OPCODE_X0 = 64, + NOR_RRR_0_OPCODE_X1 = 28, + NOR_RRR_5_OPCODE_Y0 = 1, + NOR_RRR_5_OPCODE_Y1 = 1, + ORI_IMM8_OPCODE_X0 = 7, + ORI_IMM8_OPCODE_X1 = 24, + OR_RRR_0_OPCODE_X0 = 65, + OR_RRR_0_OPCODE_X1 = 29, + OR_RRR_5_OPCODE_Y0 = 2, + OR_RRR_5_OPCODE_Y1 = 2, + PCNT_UNARY_OPCODE_X0 = 6, + PCNT_UNARY_OPCODE_Y0 = 6, + REVBITS_UNARY_OPCODE_X0 = 7, + REVBITS_UNARY_OPCODE_Y0 = 7, + REVBYTES_UNARY_OPCODE_X0 = 8, + REVBYTES_UNARY_OPCODE_Y0 = 8, + ROTLI_SHIFT_OPCODE_X0 = 1, + ROTLI_SHIFT_OPCODE_X1 = 1, + ROTLI_SHIFT_OPCODE_Y0 = 0, + ROTLI_SHIFT_OPCODE_Y1 = 0, + ROTL_RRR_0_OPCODE_X0 = 66, + ROTL_RRR_0_OPCODE_X1 = 30, + ROTL_RRR_6_OPCODE_Y0 = 0, + ROTL_RRR_6_OPCODE_Y1 = 0, + RRR_0_OPCODE_X0 = 5, + RRR_0_OPCODE_X1 = 5, + RRR_0_OPCODE_Y0 = 5, + RRR_0_OPCODE_Y1 = 6, + RRR_1_OPCODE_Y0 = 6, + RRR_1_OPCODE_Y1 = 7, + RRR_2_OPCODE_Y0 = 7, + RRR_2_OPCODE_Y1 = 8, + RRR_3_OPCODE_Y0 = 8, + RRR_3_OPCODE_Y1 = 9, + RRR_4_OPCODE_Y0 = 9, + RRR_4_OPCODE_Y1 = 10, + RRR_5_OPCODE_Y0 = 10, + RRR_5_OPCODE_Y1 = 11, + RRR_6_OPCODE_Y0 = 11, + RRR_6_OPCODE_Y1 = 12, + RRR_7_OPCODE_Y0 = 12, + RRR_7_OPCODE_Y1 = 13, + RRR_8_OPCODE_Y0 = 13, + RRR_9_OPCODE_Y0 = 14, + SHIFT_OPCODE_X0 = 6, + SHIFT_OPCODE_X1 = 6, + SHIFT_OPCODE_Y0 = 15, + SHIFT_OPCODE_Y1 = 14, + SHL16INSLI_OPCODE_X0 = 7, + SHL16INSLI_OPCODE_X1 = 7, + SHL1ADDX_RRR_0_OPCODE_X0 = 67, + SHL1ADDX_RRR_0_OPCODE_X1 = 31, + SHL1ADDX_RRR_7_OPCODE_Y0 = 1, + SHL1ADDX_RRR_7_OPCODE_Y1 = 1, + SHL1ADD_RRR_0_OPCODE_X0 = 68, + SHL1ADD_RRR_0_OPCODE_X1 = 32, + SHL1ADD_RRR_1_OPCODE_Y0 = 0, + SHL1ADD_RRR_1_OPCODE_Y1 = 0, + SHL2ADDX_RRR_0_OPCODE_X0 = 69, + SHL2ADDX_RRR_0_OPCODE_X1 = 33, + SHL2ADDX_RRR_7_OPCODE_Y0 = 2, + SHL2ADDX_RRR_7_OPCODE_Y1 = 2, + SHL2ADD_RRR_0_OPCODE_X0 = 70, + SHL2ADD_RRR_0_OPCODE_X1 = 34, + SHL2ADD_RRR_1_OPCODE_Y0 = 1, + SHL2ADD_RRR_1_OPCODE_Y1 = 1, + SHL3ADDX_RRR_0_OPCODE_X0 = 71, + SHL3ADDX_RRR_0_OPCODE_X1 = 35, + SHL3ADDX_RRR_7_OPCODE_Y0 = 3, + SHL3ADDX_RRR_7_OPCODE_Y1 = 3, + SHL3ADD_RRR_0_OPCODE_X0 = 72, + SHL3ADD_RRR_0_OPCODE_X1 = 36, + SHL3ADD_RRR_1_OPCODE_Y0 = 2, + SHL3ADD_RRR_1_OPCODE_Y1 = 2, + SHLI_SHIFT_OPCODE_X0 = 2, + SHLI_SHIFT_OPCODE_X1 = 2, + SHLI_SHIFT_OPCODE_Y0 = 1, + SHLI_SHIFT_OPCODE_Y1 = 1, + SHLXI_SHIFT_OPCODE_X0 = 3, + SHLXI_SHIFT_OPCODE_X1 = 3, + SHLX_RRR_0_OPCODE_X0 = 73, + SHLX_RRR_0_OPCODE_X1 = 37, + SHL_RRR_0_OPCODE_X0 = 74, + SHL_RRR_0_OPCODE_X1 = 38, + SHL_RRR_6_OPCODE_Y0 = 1, + SHL_RRR_6_OPCODE_Y1 = 1, + SHRSI_SHIFT_OPCODE_X0 = 4, + SHRSI_SHIFT_OPCODE_X1 = 4, + SHRSI_SHIFT_OPCODE_Y0 = 2, + SHRSI_SHIFT_OPCODE_Y1 = 2, + SHRS_RRR_0_OPCODE_X0 = 75, + SHRS_RRR_0_OPCODE_X1 = 39, + SHRS_RRR_6_OPCODE_Y0 = 2, + SHRS_RRR_6_OPCODE_Y1 = 2, + SHRUI_SHIFT_OPCODE_X0 = 5, + SHRUI_SHIFT_OPCODE_X1 = 5, + SHRUI_SHIFT_OPCODE_Y0 = 3, + SHRUI_SHIFT_OPCODE_Y1 = 3, + SHRUXI_SHIFT_OPCODE_X0 = 6, + SHRUXI_SHIFT_OPCODE_X1 = 6, + SHRUX_RRR_0_OPCODE_X0 = 76, + SHRUX_RRR_0_OPCODE_X1 = 40, + SHRU_RRR_0_OPCODE_X0 = 77, + SHRU_RRR_0_OPCODE_X1 = 41, + SHRU_RRR_6_OPCODE_Y0 = 3, + SHRU_RRR_6_OPCODE_Y1 = 3, + SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78, + ST1_ADD_IMM8_OPCODE_X1 = 25, + ST1_OPCODE_Y2 = 0, + ST1_RRR_0_OPCODE_X1 = 42, + ST2_ADD_IMM8_OPCODE_X1 = 26, + ST2_OPCODE_Y2 = 1, + ST2_RRR_0_OPCODE_X1 = 43, + ST4_ADD_IMM8_OPCODE_X1 = 27, + ST4_OPCODE_Y2 = 2, + ST4_RRR_0_OPCODE_X1 = 44, + STNT1_ADD_IMM8_OPCODE_X1 = 28, + STNT1_RRR_0_OPCODE_X1 = 45, + STNT2_ADD_IMM8_OPCODE_X1 = 29, + STNT2_RRR_0_OPCODE_X1 = 46, + STNT4_ADD_IMM8_OPCODE_X1 = 30, + STNT4_RRR_0_OPCODE_X1 = 47, + STNT_ADD_IMM8_OPCODE_X1 = 31, + STNT_RRR_0_OPCODE_X1 = 48, + ST_ADD_IMM8_OPCODE_X1 = 32, + ST_OPCODE_Y2 = 3, + ST_RRR_0_OPCODE_X1 = 49, + SUBXSC_RRR_0_OPCODE_X0 = 79, + SUBXSC_RRR_0_OPCODE_X1 = 50, + SUBX_RRR_0_OPCODE_X0 = 80, + SUBX_RRR_0_OPCODE_X1 = 51, + SUBX_RRR_0_OPCODE_Y0 = 2, + SUBX_RRR_0_OPCODE_Y1 = 2, + SUB_RRR_0_OPCODE_X0 = 81, + SUB_RRR_0_OPCODE_X1 = 52, + SUB_RRR_0_OPCODE_Y0 = 3, + SUB_RRR_0_OPCODE_Y1 = 3, + SWINT0_UNARY_OPCODE_X1 = 34, + SWINT1_UNARY_OPCODE_X1 = 35, + SWINT2_UNARY_OPCODE_X1 = 36, + SWINT3_UNARY_OPCODE_X1 = 37, + TBLIDXB0_UNARY_OPCODE_X0 = 9, + TBLIDXB0_UNARY_OPCODE_Y0 = 9, + TBLIDXB1_UNARY_OPCODE_X0 = 10, + TBLIDXB1_UNARY_OPCODE_Y0 = 10, + TBLIDXB2_UNARY_OPCODE_X0 = 11, + TBLIDXB2_UNARY_OPCODE_Y0 = 11, + TBLIDXB3_UNARY_OPCODE_X0 = 12, + TBLIDXB3_UNARY_OPCODE_Y0 = 12, + UNARY_RRR_0_OPCODE_X0 = 82, + UNARY_RRR_0_OPCODE_X1 = 53, + UNARY_RRR_1_OPCODE_Y0 = 3, + UNARY_RRR_1_OPCODE_Y1 = 3, + V1ADDI_IMM8_OPCODE_X0 = 8, + V1ADDI_IMM8_OPCODE_X1 = 33, + V1ADDUC_RRR_0_OPCODE_X0 = 83, + V1ADDUC_RRR_0_OPCODE_X1 = 54, + V1ADD_RRR_0_OPCODE_X0 = 84, + V1ADD_RRR_0_OPCODE_X1 = 55, + V1ADIFFU_RRR_0_OPCODE_X0 = 85, + V1AVGU_RRR_0_OPCODE_X0 = 86, + V1CMPEQI_IMM8_OPCODE_X0 = 9, + V1CMPEQI_IMM8_OPCODE_X1 = 34, + V1CMPEQ_RRR_0_OPCODE_X0 = 87, + V1CMPEQ_RRR_0_OPCODE_X1 = 56, + V1CMPLES_RRR_0_OPCODE_X0 = 88, + V1CMPLES_RRR_0_OPCODE_X1 = 57, + V1CMPLEU_RRR_0_OPCODE_X0 = 89, + V1CMPLEU_RRR_0_OPCODE_X1 = 58, + V1CMPLTSI_IMM8_OPCODE_X0 = 10, + V1CMPLTSI_IMM8_OPCODE_X1 = 35, + V1CMPLTS_RRR_0_OPCODE_X0 = 90, + V1CMPLTS_RRR_0_OPCODE_X1 = 59, + V1CMPLTUI_IMM8_OPCODE_X0 = 11, + V1CMPLTUI_IMM8_OPCODE_X1 = 36, + V1CMPLTU_RRR_0_OPCODE_X0 = 91, + V1CMPLTU_RRR_0_OPCODE_X1 = 60, + V1CMPNE_RRR_0_OPCODE_X0 = 92, + V1CMPNE_RRR_0_OPCODE_X1 = 61, + V1DDOTPUA_RRR_0_OPCODE_X0 = 161, + V1DDOTPUSA_RRR_0_OPCODE_X0 = 93, + V1DDOTPUS_RRR_0_OPCODE_X0 = 94, + V1DDOTPU_RRR_0_OPCODE_X0 = 162, + V1DOTPA_RRR_0_OPCODE_X0 = 95, + V1DOTPUA_RRR_0_OPCODE_X0 = 163, + V1DOTPUSA_RRR_0_OPCODE_X0 = 96, + V1DOTPUS_RRR_0_OPCODE_X0 = 97, + V1DOTPU_RRR_0_OPCODE_X0 = 164, + V1DOTP_RRR_0_OPCODE_X0 = 98, + V1INT_H_RRR_0_OPCODE_X0 = 99, + V1INT_H_RRR_0_OPCODE_X1 = 62, + V1INT_L_RRR_0_OPCODE_X0 = 100, + V1INT_L_RRR_0_OPCODE_X1 = 63, + V1MAXUI_IMM8_OPCODE_X0 = 12, + V1MAXUI_IMM8_OPCODE_X1 = 37, + V1MAXU_RRR_0_OPCODE_X0 = 101, + V1MAXU_RRR_0_OPCODE_X1 = 64, + V1MINUI_IMM8_OPCODE_X0 = 13, + V1MINUI_IMM8_OPCODE_X1 = 38, + V1MINU_RRR_0_OPCODE_X0 = 102, + V1MINU_RRR_0_OPCODE_X1 = 65, + V1MNZ_RRR_0_OPCODE_X0 = 103, + V1MNZ_RRR_0_OPCODE_X1 = 66, + V1MULTU_RRR_0_OPCODE_X0 = 104, + V1MULUS_RRR_0_OPCODE_X0 = 105, + V1MULU_RRR_0_OPCODE_X0 = 106, + V1MZ_RRR_0_OPCODE_X0 = 107, + V1MZ_RRR_0_OPCODE_X1 = 67, + V1SADAU_RRR_0_OPCODE_X0 = 108, + V1SADU_RRR_0_OPCODE_X0 = 109, + V1SHLI_SHIFT_OPCODE_X0 = 7, + V1SHLI_SHIFT_OPCODE_X1 = 7, + V1SHL_RRR_0_OPCODE_X0 = 110, + V1SHL_RRR_0_OPCODE_X1 = 68, + V1SHRSI_SHIFT_OPCODE_X0 = 8, + V1SHRSI_SHIFT_OPCODE_X1 = 8, + V1SHRS_RRR_0_OPCODE_X0 = 111, + V1SHRS_RRR_0_OPCODE_X1 = 69, + V1SHRUI_SHIFT_OPCODE_X0 = 9, + V1SHRUI_SHIFT_OPCODE_X1 = 9, + V1SHRU_RRR_0_OPCODE_X0 = 112, + V1SHRU_RRR_0_OPCODE_X1 = 70, + V1SUBUC_RRR_0_OPCODE_X0 = 113, + V1SUBUC_RRR_0_OPCODE_X1 = 71, + V1SUB_RRR_0_OPCODE_X0 = 114, + V1SUB_RRR_0_OPCODE_X1 = 72, + V2ADDI_IMM8_OPCODE_X0 = 14, + V2ADDI_IMM8_OPCODE_X1 = 39, + V2ADDSC_RRR_0_OPCODE_X0 = 115, + V2ADDSC_RRR_0_OPCODE_X1 = 73, + V2ADD_RRR_0_OPCODE_X0 = 116, + V2ADD_RRR_0_OPCODE_X1 = 74, + V2ADIFFS_RRR_0_OPCODE_X0 = 117, + V2AVGS_RRR_0_OPCODE_X0 = 118, + V2CMPEQI_IMM8_OPCODE_X0 = 15, + V2CMPEQI_IMM8_OPCODE_X1 = 40, + V2CMPEQ_RRR_0_OPCODE_X0 = 119, + V2CMPEQ_RRR_0_OPCODE_X1 = 75, + V2CMPLES_RRR_0_OPCODE_X0 = 120, + V2CMPLES_RRR_0_OPCODE_X1 = 76, + V2CMPLEU_RRR_0_OPCODE_X0 = 121, + V2CMPLEU_RRR_0_OPCODE_X1 = 77, + V2CMPLTSI_IMM8_OPCODE_X0 = 16, + V2CMPLTSI_IMM8_OPCODE_X1 = 41, + V2CMPLTS_RRR_0_OPCODE_X0 = 122, + V2CMPLTS_RRR_0_OPCODE_X1 = 78, + V2CMPLTUI_IMM8_OPCODE_X0 = 17, + V2CMPLTUI_IMM8_OPCODE_X1 = 42, + V2CMPLTU_RRR_0_OPCODE_X0 = 123, + V2CMPLTU_RRR_0_OPCODE_X1 = 79, + V2CMPNE_RRR_0_OPCODE_X0 = 124, + V2CMPNE_RRR_0_OPCODE_X1 = 80, + V2DOTPA_RRR_0_OPCODE_X0 = 125, + V2DOTP_RRR_0_OPCODE_X0 = 126, + V2INT_H_RRR_0_OPCODE_X0 = 127, + V2INT_H_RRR_0_OPCODE_X1 = 81, + V2INT_L_RRR_0_OPCODE_X0 = 128, + V2INT_L_RRR_0_OPCODE_X1 = 82, + V2MAXSI_IMM8_OPCODE_X0 = 18, + V2MAXSI_IMM8_OPCODE_X1 = 43, + V2MAXS_RRR_0_OPCODE_X0 = 129, + V2MAXS_RRR_0_OPCODE_X1 = 83, + V2MINSI_IMM8_OPCODE_X0 = 19, + V2MINSI_IMM8_OPCODE_X1 = 44, + V2MINS_RRR_0_OPCODE_X0 = 130, + V2MINS_RRR_0_OPCODE_X1 = 84, + V2MNZ_RRR_0_OPCODE_X0 = 131, + V2MNZ_RRR_0_OPCODE_X1 = 85, + V2MULFSC_RRR_0_OPCODE_X0 = 132, + V2MULS_RRR_0_OPCODE_X0 = 133, + V2MULTS_RRR_0_OPCODE_X0 = 134, + V2MZ_RRR_0_OPCODE_X0 = 135, + V2MZ_RRR_0_OPCODE_X1 = 86, + V2PACKH_RRR_0_OPCODE_X0 = 136, + V2PACKH_RRR_0_OPCODE_X1 = 87, + V2PACKL_RRR_0_OPCODE_X0 = 137, + V2PACKL_RRR_0_OPCODE_X1 = 88, + V2PACKUC_RRR_0_OPCODE_X0 = 138, + V2PACKUC_RRR_0_OPCODE_X1 = 89, + V2SADAS_RRR_0_OPCODE_X0 = 139, + V2SADAU_RRR_0_OPCODE_X0 = 140, + V2SADS_RRR_0_OPCODE_X0 = 141, + V2SADU_RRR_0_OPCODE_X0 = 142, + V2SHLI_SHIFT_OPCODE_X0 = 10, + V2SHLI_SHIFT_OPCODE_X1 = 10, + V2SHLSC_RRR_0_OPCODE_X0 = 143, + V2SHLSC_RRR_0_OPCODE_X1 = 90, + V2SHL_RRR_0_OPCODE_X0 = 144, + V2SHL_RRR_0_OPCODE_X1 = 91, + V2SHRSI_SHIFT_OPCODE_X0 = 11, + V2SHRSI_SHIFT_OPCODE_X1 = 11, + V2SHRS_RRR_0_OPCODE_X0 = 145, + V2SHRS_RRR_0_OPCODE_X1 = 92, + V2SHRUI_SHIFT_OPCODE_X0 = 12, + V2SHRUI_SHIFT_OPCODE_X1 = 12, + V2SHRU_RRR_0_OPCODE_X0 = 146, + V2SHRU_RRR_0_OPCODE_X1 = 93, + V2SUBSC_RRR_0_OPCODE_X0 = 147, + V2SUBSC_RRR_0_OPCODE_X1 = 94, + V2SUB_RRR_0_OPCODE_X0 = 148, + V2SUB_RRR_0_OPCODE_X1 = 95, + V4ADDSC_RRR_0_OPCODE_X0 = 149, + V4ADDSC_RRR_0_OPCODE_X1 = 96, + V4ADD_RRR_0_OPCODE_X0 = 150, + V4ADD_RRR_0_OPCODE_X1 = 97, + V4INT_H_RRR_0_OPCODE_X0 = 151, + V4INT_H_RRR_0_OPCODE_X1 = 98, + V4INT_L_RRR_0_OPCODE_X0 = 152, + V4INT_L_RRR_0_OPCODE_X1 = 99, + V4PACKSC_RRR_0_OPCODE_X0 = 153, + V4PACKSC_RRR_0_OPCODE_X1 = 100, + V4SHLSC_RRR_0_OPCODE_X0 = 154, + V4SHLSC_RRR_0_OPCODE_X1 = 101, + V4SHL_RRR_0_OPCODE_X0 = 155, + V4SHL_RRR_0_OPCODE_X1 = 102, + V4SHRS_RRR_0_OPCODE_X0 = 156, + V4SHRS_RRR_0_OPCODE_X1 = 103, + V4SHRU_RRR_0_OPCODE_X0 = 157, + V4SHRU_RRR_0_OPCODE_X1 = 104, + V4SUBSC_RRR_0_OPCODE_X0 = 158, + V4SUBSC_RRR_0_OPCODE_X1 = 105, + V4SUB_RRR_0_OPCODE_X0 = 159, + V4SUB_RRR_0_OPCODE_X1 = 106, + WH64_UNARY_OPCODE_X1 = 38, + XORI_IMM8_OPCODE_X0 = 20, + XORI_IMM8_OPCODE_X1 = 45, + XOR_RRR_0_OPCODE_X0 = 160, + XOR_RRR_0_OPCODE_X1 = 107, + XOR_RRR_5_OPCODE_Y0 = 3, + XOR_RRR_5_OPCODE_Y1 = 3 +}; + +static __inline unsigned int +get_BFEnd_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_BFOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 24)) & 0xf); +} + +static __inline unsigned int +get_BFStart_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3f); +} + +static __inline unsigned int +get_BrOff_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 37)) & 0x0001ffc0); +} + +static __inline unsigned int +get_BrType_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 54)) & 0x1f); +} + +static __inline unsigned int +get_Dest_Imm8_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 43)) & 0x000000c0); +} + +static __inline unsigned int +get_Dest_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 0)) & 0x3f); +} + +static __inline unsigned int +get_Dest_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x3f); +} + +static __inline unsigned int +get_Dest_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 0)) & 0x3f); +} + +static __inline unsigned int +get_Dest_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x3f); +} + +static __inline unsigned int +get_Imm16_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xffff); +} + +static __inline unsigned int +get_Imm16_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xffff); +} + +static __inline unsigned int +get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 20)) & 0xff); +} + +static __inline unsigned int +get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 51)) & 0xff); +} + +static __inline unsigned int +get_Imm8_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xff); +} + +static __inline unsigned int +get_Imm8_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xff); +} + +static __inline unsigned int +get_Imm8_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xff); +} + +static __inline unsigned int +get_Imm8_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xff); +} + +static __inline unsigned int +get_JumpOff_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x7ffffff); +} + +static __inline unsigned int +get_JumpOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 58)) & 0x1); +} + +static __inline unsigned int +get_MF_Imm14_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3fff); +} + +static __inline unsigned int +get_MT_Imm14_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 37)) & 0x00003fc0); +} + +static __inline unsigned int +get_Mode(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 62)) & 0x3); +} + +static __inline unsigned int +get_Opcode_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 28)) & 0x7); +} + +static __inline unsigned int +get_Opcode_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 59)) & 0x7); +} + +static __inline unsigned int +get_Opcode_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 27)) & 0xf); +} + +static __inline unsigned int +get_Opcode_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 58)) & 0xf); +} + +static __inline unsigned int +get_Opcode_Y2(tilegx_bundle_bits n) +{ + return (((n >> 26)) & 0x00000001) | + (((unsigned int)(n >> 56)) & 0x00000002); +} + +static __inline unsigned int +get_RRROpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3ff); +} + +static __inline unsigned int +get_RRROpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3ff); +} + +static __inline unsigned int +get_RRROpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3); +} + +static __inline unsigned int +get_RRROpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3); +} + +static __inline unsigned int +get_ShAmt_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3ff); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3ff); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3); +} + +static __inline unsigned int +get_SrcA_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 6)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 6)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y2(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 20)) & 0x3f); +} + +static __inline unsigned int +get_SrcBDest_Y2(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 51)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline int +sign_extend(int n, int num_bits) +{ + int shift = (int)(sizeof(int) * 8 - num_bits); + return (n << shift) >> shift; +} + +static __inline tilegx_bundle_bits +create_BFEnd_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_BFOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xf) << 24); +} + +static __inline tilegx_bundle_bits +create_BFStart_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 18); +} + +static __inline tilegx_bundle_bits +create_BrOff_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37); +} + +static __inline tilegx_bundle_bits +create_BrType_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x1f)) << 54); +} + +static __inline tilegx_bundle_bits +create_Dest_Imm8_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x000000c0)) << 43); +} + +static __inline tilegx_bundle_bits +create_Dest_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 0); +} + +static __inline tilegx_bundle_bits +create_Dest_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 31); +} + +static __inline tilegx_bundle_bits +create_Dest_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 0); +} + +static __inline tilegx_bundle_bits +create_Dest_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 31); +} + +static __inline tilegx_bundle_bits +create_Imm16_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xffff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm16_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xffff)) << 43); +} + +static __inline tilegx_bundle_bits +create_Imm8OpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 20); +} + +static __inline tilegx_bundle_bits +create_Imm8OpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 51); +} + +static __inline tilegx_bundle_bits +create_Imm8_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm8_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 43); +} + +static __inline tilegx_bundle_bits +create_Imm8_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm8_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 43); +} + +static __inline tilegx_bundle_bits +create_JumpOff_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31); +} + +static __inline tilegx_bundle_bits +create_JumpOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x1)) << 58); +} + +static __inline tilegx_bundle_bits +create_MF_Imm14_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3fff)) << 37); +} + +static __inline tilegx_bundle_bits +create_MT_Imm14_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37); +} + +static __inline tilegx_bundle_bits +create_Mode(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 62); +} + +static __inline tilegx_bundle_bits +create_Opcode_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x7) << 28); +} + +static __inline tilegx_bundle_bits +create_Opcode_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x7)) << 59); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xf) << 27); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xf)) << 58); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x00000001) << 26) | + (((tilegx_bundle_bits)(n & 0x00000002)) << 56); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3ff) << 18); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3) << 18); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 49); +} + +static __inline tilegx_bundle_bits +create_ShAmt_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_ShAmt_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_ShAmt_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_ShAmt_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3ff) << 18); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3) << 18); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 49); +} + +static __inline tilegx_bundle_bits +create_SrcA_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 6); +} + +static __inline tilegx_bundle_bits +create_SrcA_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 37); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 6); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 37); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 20); +} + +static __inline tilegx_bundle_bits +create_SrcBDest_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 51); +} + +static __inline tilegx_bundle_bits +create_SrcB_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_SrcB_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_SrcB_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_SrcB_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +const struct tilegx_opcode tilegx_opcodes[336] = +{ + { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffffffff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a44ae00000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1, + { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00fffULL, + 0xfff807ff80000000ULL, + 0x0000000078000fffULL, + 0x3c0007ff80000000ULL, + 0ULL + }, + { + 0x0000000040300fffULL, + 0x181807ff80000000ULL, + 0x0000000010000fffULL, + 0x0c0007ff80000000ULL, + -1ULL + } +#endif + }, + { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1, + { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000fffULL, + 0xf80007ff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000070000fffULL, + 0x380007ff80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1, + { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x000000005107f000ULL, + 0x283bf80000000000ULL, + 0x00000000500bf000ULL, + 0x2c05f80000000000ULL, + -1ULL + } +#endif + }, + { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1, + { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00fc0ULL, + 0xfff807e000000000ULL, + 0x0000000078000fc0ULL, + 0x3c0007e000000000ULL, + 0ULL + }, + { + 0x0000000040100fc0ULL, + 0x180807e000000000ULL, + 0x0000000000000fc0ULL, + 0x040007e000000000ULL, + -1ULL + } +#endif + }, + { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1, + { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000fc0ULL, + 0xf80007e000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000010000fc0ULL, + 0x000007e000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a801f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000004000000ULL + } +#endif + }, + { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1840001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1838001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1850001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1848001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1860001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a801f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000004000000ULL + } +#endif + }, + { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a781f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000000000000ULL + } +#endif + }, + { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a901f80000000ULL, + -1ULL, + -1ULL, + 0x43f8000004000000ULL + } +#endif + }, + { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a881f80000000ULL, + -1ULL, + -1ULL, + 0x43f8000000000000ULL + } +#endif + }, + { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286aa01f80000000ULL, + -1ULL, + -1ULL, + 0x83f8000000000000ULL + } +#endif + }, + { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a981f80000000ULL, + -1ULL, + -1ULL, + 0x81f8000004000000ULL + } +#endif + }, + { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffffffff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a44ae80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000500c0000ULL, + 0x2806000000000000ULL, + 0x0000000028040000ULL, + 0x1802000000000000ULL, + -1ULL + } +#endif + }, + { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040100000ULL, + 0x1808000000000000ULL, + 0ULL, + 0x0400000000000000ULL, + -1ULL + } +#endif + }, + { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000010000000ULL, + 0ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050080000ULL, + 0x2804000000000000ULL, + 0x0000000028000000ULL, + 0x1800000000000000ULL, + -1ULL + } +#endif + }, + { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040200000ULL, + 0x1810000000000000ULL, + 0x0000000008000000ULL, + 0x0800000000000000ULL, + -1ULL + } +#endif + }, + { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000020000000ULL, + 0x0800000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050040000ULL, + 0x2802000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050100000ULL, + 0x2808000000000000ULL, + 0x0000000050000000ULL, + 0x2c00000000000000ULL, + -1ULL + } +#endif + }, + { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040300000ULL, + 0x1818000000000000ULL, + 0x0000000010000000ULL, + 0x0c00000000000000ULL, + -1ULL + } +#endif + }, + { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1440000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1400000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1, + { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000034000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1, + { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000035000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1, + { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000036000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x14c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1480000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1540000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1500000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x15c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1580000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1640000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1600000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x16c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1680000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1740000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1700000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x17c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1780000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051481000ULL, + -1ULL, + 0x00000000300c1000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050140000ULL, + -1ULL, + 0x0000000048000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050180000ULL, + -1ULL, + 0x0000000048040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000501c0000ULL, + 0x280a000000000000ULL, + 0x0000000040000000ULL, + 0x2404000000000000ULL, + -1ULL + } +#endif + }, + { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040400000ULL, + 0x1820000000000000ULL, + 0x0000000018000000ULL, + 0x1000000000000000ULL, + -1ULL + } +#endif + }, + { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x280e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x280c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050200000ULL, + 0x2810000000000000ULL, + 0x0000000038000000ULL, + 0x2000000000000000ULL, + -1ULL + } +#endif + }, + { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050240000ULL, + 0x2812000000000000ULL, + 0x0000000038040000ULL, + 0x2002000000000000ULL, + -1ULL + } +#endif + }, + { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050280000ULL, + 0x2814000000000000ULL, + 0x0000000038080000ULL, + 0x2004000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040500000ULL, + 0x1828000000000000ULL, + 0x0000000020000000ULL, + 0x1400000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000502c0000ULL, + 0x2816000000000000ULL, + 0x00000000380c0000ULL, + 0x2006000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040600000ULL, + 0x1830000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050300000ULL, + 0x2818000000000000ULL, + 0x0000000040040000ULL, + 0x2406000000000000ULL, + -1ULL + } +#endif + }, + { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000504c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050340000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050400000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000503c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050480000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050440000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050500000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050540000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051482000ULL, + -1ULL, + 0x00000000300c2000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050640000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050580000ULL, + 0x281a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000505c0000ULL, + 0x281c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050600000ULL, + 0x281e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a080000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a100000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2822000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2820000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000506c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050680000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050700000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050740000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050780000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000507c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050800000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2824000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2828000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2826000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2832000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2830000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a180000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a280000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a200000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1, + { { }, { }, { }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x0000000051483000ULL, + 0x286a300000000000ULL, + 0x00000000300c3000ULL, + 0x1c06400000000000ULL, + -1ULL + } +#endif + }, + { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000508c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050900000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050940000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051484000ULL, + -1ULL, + 0x00000000300c4000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050980000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000509c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a380000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a400000000000ULL, + -1ULL, + 0x1c06480000000000ULL, + -1ULL + } +#endif + }, + { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a480000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a500000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfc00000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2400000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1, + { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfc00000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2000000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a600000000000ULL, + -1ULL, + 0x1c06580000000000ULL, + -1ULL + } +#endif + }, + { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a580000000000ULL, + -1ULL, + 0x1c06500000000000ULL, + -1ULL + } +#endif + }, + { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a700000000000ULL, + -1ULL, + 0x1c06680000000000ULL, + -1ULL + } +#endif + }, + { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a680000000000ULL, + -1ULL, + 0x1c06600000000000ULL, + -1ULL + } +#endif + }, + { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286ae80000000000ULL, + -1ULL, + -1ULL, + 0x8200000004000000ULL + } +#endif + }, + { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a780000000000ULL, + -1ULL, + -1ULL, + 0x4000000000000000ULL + } +#endif + }, + { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1838000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a800000000000ULL, + -1ULL, + -1ULL, + 0x4000000004000000ULL + } +#endif + }, + { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1840000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a880000000000ULL, + -1ULL, + -1ULL, + 0x4200000000000000ULL + } +#endif + }, + { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1848000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a900000000000ULL, + -1ULL, + -1ULL, + 0x4200000004000000ULL + } +#endif + }, + { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1850000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a980000000000ULL, + -1ULL, + -1ULL, + 0x8000000004000000ULL + } +#endif + }, + { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286aa00000000000ULL, + -1ULL, + -1ULL, + 0x8200000000000000ULL + } +#endif + }, + { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1860000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286aa80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ae00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ab00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1868000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ab80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1870000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ac00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1878000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ac80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1880000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ad00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1888000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ad80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1890000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1898000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286af00000000000ULL, + -1ULL, + 0x1c06700000000000ULL, + -1ULL + } +#endif + }, + { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286af80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18b0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1, + { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000037000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050a00000ULL, + 0x2834000000000000ULL, + 0x0000000048080000ULL, + 0x2804000000000000ULL, + -1ULL + } +#endif + }, + { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18b8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d40000ULL, + -1ULL, + 0x0000000068000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050dc0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e40000ULL, + -1ULL, + 0x0000000068040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050ec0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f00000ULL, + -1ULL, + 0x0000000068080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f80000ULL, + -1ULL, + 0x00000000680c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050a80000ULL, + -1ULL, + 0x0000000070000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050ac0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b80000ULL, + -1ULL, + 0x0000000070040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050bc0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c40000ULL, + -1ULL, + 0x0000000070080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050cc0000ULL, + -1ULL, + 0x00000000700c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050a40000ULL, + -1ULL, + 0x0000000040080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d00000ULL, + -1ULL, + 0x00000000400c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050fc0000ULL, + 0x2836000000000000ULL, + 0x00000000480c0000ULL, + 0x2806000000000000ULL, + -1ULL + } +#endif + }, + { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1, + { { }, { }, { }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x0000000051485000ULL, + 0x286b080000000000ULL, + 0x00000000300c5000ULL, + 0x1c06780000000000ULL, + -1ULL + } +#endif + }, + { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051000000ULL, + 0x2838000000000000ULL, + 0x0000000050040000ULL, + 0x2c02000000000000ULL, + -1ULL + } +#endif + }, + { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051040000ULL, + 0x283a000000000000ULL, + 0x0000000050080000ULL, + 0x2c04000000000000ULL, + -1ULL + } +#endif + }, + { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040700000ULL, + 0x18c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051486000ULL, + -1ULL, + 0x00000000300c6000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051487000ULL, + -1ULL, + 0x00000000300c7000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051488000ULL, + -1ULL, + 0x00000000300c8000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051080000ULL, + 0x283c000000000000ULL, + 0x0000000058000000ULL, + 0x3000000000000000ULL, + -1ULL + } +#endif + }, + { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060040000ULL, + 0x3002000000000000ULL, + 0x0000000078000000ULL, + 0x3800000000000000ULL, + -1ULL + } +#endif + }, + { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051280000ULL, + 0x284c000000000000ULL, + 0x0000000058040000ULL, + 0x3002000000000000ULL, + -1ULL + } +#endif + }, + { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000070000000ULL, + 0x3800000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051100000ULL, + 0x2840000000000000ULL, + 0x0000000030000000ULL, + 0x1c00000000000000ULL, + -1ULL + } +#endif + }, + { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000510c0000ULL, + 0x283e000000000000ULL, + 0x0000000060040000ULL, + 0x3402000000000000ULL, + -1ULL + } +#endif + }, + { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051180000ULL, + 0x2844000000000000ULL, + 0x0000000030040000ULL, + 0x1c02000000000000ULL, + -1ULL + } +#endif + }, + { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051140000ULL, + 0x2842000000000000ULL, + 0x0000000060080000ULL, + 0x3404000000000000ULL, + -1ULL + } +#endif + }, + { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051200000ULL, + 0x2848000000000000ULL, + 0x0000000030080000ULL, + 0x1c04000000000000ULL, + -1ULL + } +#endif + }, + { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000511c0000ULL, + 0x2846000000000000ULL, + 0x00000000600c0000ULL, + 0x3406000000000000ULL, + -1ULL + } +#endif + }, + { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060080000ULL, + 0x3004000000000000ULL, + 0x0000000078040000ULL, + 0x3802000000000000ULL, + -1ULL + } +#endif + }, + { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051240000ULL, + 0x284a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000600c0000ULL, + 0x3006000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000512c0000ULL, + 0x284e000000000000ULL, + 0x0000000058080000ULL, + 0x3004000000000000ULL, + -1ULL + } +#endif + }, + { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060100000ULL, + 0x3008000000000000ULL, + 0x0000000078080000ULL, + 0x3804000000000000ULL, + -1ULL + } +#endif + }, + { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051340000ULL, + 0x2852000000000000ULL, + 0x00000000580c0000ULL, + 0x3006000000000000ULL, + -1ULL + } +#endif + }, + { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060140000ULL, + 0x300a000000000000ULL, + 0x00000000780c0000ULL, + 0x3806000000000000ULL, + -1ULL + } +#endif + }, + { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051300000ULL, + 0x2850000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060180000ULL, + 0x300c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2862000000000000ULL, + -1ULL, + -1ULL, + 0xc200000004000000ULL + } +#endif + }, + { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2854000000000000ULL, + -1ULL, + -1ULL, + 0xc000000000000000ULL + } +#endif + }, + { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18c8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2856000000000000ULL, + -1ULL, + -1ULL, + 0xc000000004000000ULL + } +#endif + }, + { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18d0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2858000000000000ULL, + -1ULL, + -1ULL, + 0xc200000000000000ULL + } +#endif + }, + { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18d8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1900000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2860000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18e0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18e8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18f0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18f8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051440000ULL, + 0x2868000000000000ULL, + 0x00000000280c0000ULL, + 0x1806000000000000ULL, + -1ULL + } +#endif + }, + { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051400000ULL, + 0x2866000000000000ULL, + 0x0000000028080000ULL, + 0x1804000000000000ULL, + -1ULL + } +#endif + }, + { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000513c0000ULL, + 0x2864000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b100000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b180000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b200000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b280000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051489000ULL, + -1ULL, + 0x00000000300c9000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148a000ULL, + -1ULL, + 0x00000000300ca000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148b000ULL, + -1ULL, + 0x00000000300cb000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148c000ULL, + -1ULL, + 0x00000000300cc000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051500000ULL, + 0x286e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040800000ULL, + 0x1908000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000514c0000ULL, + 0x286c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051540000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051580000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000515c0000ULL, + 0x2870000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040900000ULL, + 0x1910000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051600000ULL, + 0x2872000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051640000ULL, + 0x2874000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051680000ULL, + 0x2876000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040a00000ULL, + 0x1918000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000516c0000ULL, + 0x2878000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040b00000ULL, + 0x1920000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051700000ULL, + 0x287a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051780000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051740000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000517c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052900000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000528c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051800000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000518c0000ULL, + 0x287c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051900000ULL, + 0x287e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051940000ULL, + 0x2880000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040c00000ULL, + 0x1928000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051980000ULL, + 0x2882000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040d00000ULL, + 0x1930000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000519c0000ULL, + 0x2884000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051ac0000ULL, + 0x2886000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b80000ULL, + 0x2888000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000601c0000ULL, + 0x300e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051bc0000ULL, + 0x288a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060200000ULL, + 0x3010000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c00000ULL, + 0x288c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060240000ULL, + 0x3012000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c80000ULL, + 0x2890000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c40000ULL, + 0x288e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d00000ULL, + 0x2894000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040e00000ULL, + 0x1938000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051cc0000ULL, + 0x2892000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051dc0000ULL, + 0x2896000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040f00000ULL, + 0x1940000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e00000ULL, + 0x2898000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e40000ULL, + 0x289a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e80000ULL, + 0x289c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041000000ULL, + 0x1948000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051ec0000ULL, + 0x289e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041100000ULL, + 0x1950000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f00000ULL, + 0x28a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051fc0000ULL, + 0x28a2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052000000ULL, + 0x28a4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052040000ULL, + 0x28a6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041200000ULL, + 0x1958000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052080000ULL, + 0x28a8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041300000ULL, + 0x1960000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000520c0000ULL, + 0x28aa000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052100000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052140000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052180000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000521c0000ULL, + 0x28ac000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052200000ULL, + 0x28ae000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052240000ULL, + 0x28b0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052280000ULL, + 0x28b2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000522c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052300000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052340000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052400000ULL, + 0x28b6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060280000ULL, + 0x3014000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000523c0000ULL, + 0x28b4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052440000ULL, + 0x28b8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000602c0000ULL, + 0x3016000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052480000ULL, + 0x28ba000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060300000ULL, + 0x3018000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052500000ULL, + 0x28be000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000524c0000ULL, + 0x28bc000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052580000ULL, + 0x28c2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052540000ULL, + 0x28c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000525c0000ULL, + 0x28c4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052600000ULL, + 0x28c6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052640000ULL, + 0x28c8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000526c0000ULL, + 0x28cc000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052680000ULL, + 0x28ca000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052700000ULL, + 0x28ce000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052740000ULL, + 0x28d0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000527c0000ULL, + 0x28d4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052780000ULL, + 0x28d2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b300000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000052800000ULL, + 0x28d6000000000000ULL, + 0x00000000500c0000ULL, + 0x2c06000000000000ULL, + -1ULL + } +#endif + }, + { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041400000ULL, + 0x1968000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } }, +#ifndef DISASM_ONLY + { 0, }, { 0, } +#endif + } +}; + +#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6)) +#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index)) + +static const unsigned short decode_X0_fsm[936] = +{ + BITFIELD(22, 9) /* index 0 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS, + TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU, + TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS, + TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM, + TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578), + CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671), + CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865), + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + BITFIELD(6, 2) /* index 513 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), + BITFIELD(8, 2) /* index 518 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), + BITFIELD(10, 2) /* index 523 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, + BITFIELD(20, 2) /* index 528 */, + TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), + BITFIELD(6, 2) /* index 533 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), + BITFIELD(8, 2) /* index 538 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), + BITFIELD(10, 2) /* index 543 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(0, 2) /* index 548 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), + BITFIELD(2, 2) /* index 553 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), + BITFIELD(4, 2) /* index 558 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), + BITFIELD(6, 2) /* index 563 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), + BITFIELD(8, 2) /* index 568 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), + BITFIELD(10, 2) /* index 573 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(20, 2) /* index 578 */, + TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI, + BITFIELD(20, 2) /* index 583 */, + TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI, + TILEGX_OPC_V1CMPLTUI, + BITFIELD(20, 2) /* index 588 */, + TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI, + TILEGX_OPC_V2CMPEQI, + BITFIELD(20, 2) /* index 593 */, + TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI, + TILEGX_OPC_V2MINSI, + BITFIELD(20, 2) /* index 598 */, + TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 603 */, + TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, + TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR, + BITFIELD(18, 4) /* index 620 */, + TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL, + TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2, + TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN, + TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS, + TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1, + TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS, + BITFIELD(18, 4) /* index 637 */, + TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN, + TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2, + TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2, + TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX, + TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS, + TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS, + BITFIELD(18, 4) /* index 654 */, + TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU, + TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS, + TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU, + TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU, + TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU, + TILEGX_OPC_MZ, + BITFIELD(18, 4) /* index 671 */, + TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, + TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES, + TILEGX_OPC_SUBXSC, + BITFIELD(12, 2) /* index 688 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693), + BITFIELD(14, 2) /* index 693 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698), + BITFIELD(16, 2) /* index 698 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(18, 4) /* index 703 */, + TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA, + BITFIELD(12, 4) /* index 720 */, + TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757), + CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787), + CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 737 */, + TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 742 */, + TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 747 */, + TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 752 */, + TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 757 */, + TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 762 */, + TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 767 */, + TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 772 */, + TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 777 */, + TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 782 */, + TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 787 */, + TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 792 */, + TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 797 */, + TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU, + TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS, + TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU, + TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, + BITFIELD(18, 4) /* index 814 */, + TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, + TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS, + TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, + TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE, + TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H, + BITFIELD(18, 4) /* index 831 */, + TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, + TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS, + TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC, + BITFIELD(18, 4) /* index 848 */, + TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC, + TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, + TILEGX_OPC_V4SUB, + BITFIELD(18, 3) /* index 865 */, + CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 874 */, + TILEGX_OPC_XOR, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 877 */, + TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 880 */, + TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 883 */, + TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 886 */, + TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 889 */, + TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(0, 2) /* index 906 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(911), + BITFIELD(2, 2) /* index 911 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(916), + BITFIELD(4, 2) /* index 916 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(921), + BITFIELD(6, 2) /* index 921 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(926), + BITFIELD(8, 2) /* index 926 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(931), + BITFIELD(10, 2) /* index 931 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_INFOL, +}; + +static const unsigned short decode_X1_fsm[1266] = +{ + BITFIELD(53, 9) /* index 0 */, + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT, + TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT, + TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT, + TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT, + TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST, + TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT, + TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT, + TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT, + TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578), + CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758), + CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185), + CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), + BITFIELD(37, 2) /* index 513 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), + BITFIELD(39, 2) /* index 518 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), + BITFIELD(41, 2) /* index 523 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, + BITFIELD(51, 2) /* index 528 */, + TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), + BITFIELD(37, 2) /* index 533 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), + BITFIELD(39, 2) /* index 538 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), + BITFIELD(41, 2) /* index 543 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(31, 2) /* index 548 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), + BITFIELD(33, 2) /* index 553 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), + BITFIELD(35, 2) /* index 558 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), + BITFIELD(37, 2) /* index 563 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), + BITFIELD(39, 2) /* index 568 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), + BITFIELD(41, 2) /* index 573 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(51, 2) /* index 578 */, + TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583), + BITFIELD(31, 2) /* index 583 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588), + BITFIELD(33, 2) /* index 588 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593), + BITFIELD(35, 2) /* index 593 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, + TILEGX_OPC_PREFETCH_ADD_L1_FAULT, + BITFIELD(51, 2) /* index 598 */, + CHILD(603), CHILD(618), CHILD(633), CHILD(648), + BITFIELD(31, 2) /* index 603 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608), + BITFIELD(33, 2) /* index 608 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613), + BITFIELD(35, 2) /* index 613 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, + TILEGX_OPC_PREFETCH_ADD_L1, + BITFIELD(31, 2) /* index 618 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623), + BITFIELD(33, 2) /* index 623 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628), + BITFIELD(35, 2) /* index 628 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, + TILEGX_OPC_PREFETCH_ADD_L2_FAULT, + BITFIELD(31, 2) /* index 633 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638), + BITFIELD(33, 2) /* index 638 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643), + BITFIELD(35, 2) /* index 643 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, + TILEGX_OPC_PREFETCH_ADD_L2, + BITFIELD(31, 2) /* index 648 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(673), + BITFIELD(43, 2) /* index 653 */, + CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(45, 2) /* index 658 */, + CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(47, 2) /* index 663 */, + CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(49, 2) /* index 668 */, + TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + TILEGX_OPC_LD4S_ADD, + BITFIELD(33, 2) /* index 673 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(678), + BITFIELD(35, 2) /* index 678 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(683), + BITFIELD(43, 2) /* index 683 */, + CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(45, 2) /* index 688 */, + CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(47, 2) /* index 693 */, + CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(49, 2) /* index 698 */, + TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(51, 2) /* index 703 */, + CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD, + TILEGX_OPC_LDNT2S_ADD, + BITFIELD(31, 2) /* index 708 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713), + BITFIELD(33, 2) /* index 713 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718), + BITFIELD(35, 2) /* index 718 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, + TILEGX_OPC_PREFETCH_ADD_L3, + BITFIELD(51, 2) /* index 723 */, + TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD, + TILEGX_OPC_LDNT_ADD, + BITFIELD(51, 2) /* index 728 */, + CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR, + BITFIELD(43, 2) /* index 733 */, + CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(45, 2) /* index 738 */, + CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(47, 2) /* index 743 */, + CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(49, 2) /* index 748 */, + TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(51, 2) /* index 753 */, + TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD, + BITFIELD(51, 2) /* index 758 */, + TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD, + TILEGX_OPC_STNT_ADD, + BITFIELD(51, 2) /* index 763 */, + TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, + TILEGX_OPC_V1CMPLTSI, + BITFIELD(51, 2) /* index 768 */, + TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, + TILEGX_OPC_V2ADDI, + BITFIELD(51, 2) /* index 773 */, + TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, + TILEGX_OPC_V2MAXSI, + BITFIELD(51, 2) /* index 778 */, + TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 783 */, + TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, + TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4, + TILEGX_OPC_DBLALIGN6, + BITFIELD(49, 4) /* index 800 */, + TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4, + TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD, + TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4, + TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR, + CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, + BITFIELD(43, 2) /* index 817 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822), + BITFIELD(45, 2) /* index 822 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827), + BITFIELD(47, 2) /* index 827 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(49, 4) /* index 832 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, + TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1, + TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2, + TILEGX_OPC_STNT4, + BITFIELD(46, 7) /* index 849 */, + TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, + TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, + TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, + TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC, + TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, + TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX, + TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, + TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, + TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987), + CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + BITFIELD(43, 3) /* index 978 */, + TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV, + TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH, + BITFIELD(43, 3) /* index 987 */, + CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP, + TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051), + BITFIELD(31, 2) /* index 996 */, + CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(33, 2) /* index 1001 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006), + BITFIELD(35, 2) /* index 1006 */, + TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(37, 2) /* index 1011 */, + TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(39, 2) /* index 1016 */, + TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(41, 2) /* index 1021 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL, + BITFIELD(33, 2) /* index 1026 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031), + BITFIELD(35, 2) /* index 1031 */, + TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(37, 2) /* index 1036 */, + TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(39, 2) /* index 1041 */, + TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(41, 2) /* index 1046 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL, + BITFIELD(31, 2) /* index 1051 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056), + BITFIELD(33, 2) /* index 1056 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061), + BITFIELD(35, 2) /* index 1061 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, + TILEGX_OPC_PREFETCH_L1_FAULT, + BITFIELD(43, 3) /* index 1066 */, + CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135), + TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U, + BITFIELD(31, 2) /* index 1075 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080), + BITFIELD(33, 2) /* index 1080 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085), + BITFIELD(35, 2) /* index 1085 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, + BITFIELD(31, 2) /* index 1090 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095), + BITFIELD(33, 2) /* index 1095 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100), + BITFIELD(35, 2) /* index 1100 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, + TILEGX_OPC_PREFETCH_L2_FAULT, + BITFIELD(31, 2) /* index 1105 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110), + BITFIELD(33, 2) /* index 1110 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115), + BITFIELD(35, 2) /* index 1115 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, + BITFIELD(31, 2) /* index 1120 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125), + BITFIELD(33, 2) /* index 1125 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130), + BITFIELD(35, 2) /* index 1130 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, + TILEGX_OPC_PREFETCH_L3_FAULT, + BITFIELD(31, 2) /* index 1135 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140), + BITFIELD(33, 2) /* index 1140 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145), + BITFIELD(35, 2) /* index 1145 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, + BITFIELD(43, 3) /* index 1150 */, + TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U, + TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF, + BITFIELD(43, 3) /* index 1159 */, + TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1, + TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 1168 */, + TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ, + TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, + TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ, + TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS, + TILEGX_OPC_V2CMPLTU, + BITFIELD(49, 4) /* index 1185 */, + TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L, + TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, + TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB, + BITFIELD(49, 4) /* index 1202 */, + TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, + TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 1219 */, + TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(31, 2) /* index 1236 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1241), + BITFIELD(33, 2) /* index 1241 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1246), + BITFIELD(35, 2) /* index 1246 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1251), + BITFIELD(37, 2) /* index 1251 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1256), + BITFIELD(39, 2) /* index 1256 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1261), + BITFIELD(41, 2) /* index 1261 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_INFOL, +}; + +static const unsigned short decode_Y0_fsm[178] = +{ + BITFIELD(27, 4) /* index 0 */, + CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123), + CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168), + CHILD(173), + BITFIELD(6, 2) /* index 17 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), + BITFIELD(8, 2) /* index 22 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), + BITFIELD(10, 2) /* index 27 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(0, 2) /* index 32 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), + BITFIELD(2, 2) /* index 37 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), + BITFIELD(4, 2) /* index 42 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), + BITFIELD(6, 2) /* index 47 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), + BITFIELD(8, 2) /* index 52 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), + BITFIELD(10, 2) /* index 57 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(18, 2) /* index 62 */, + TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + BITFIELD(15, 5) /* index 67 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100), + CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(12, 3) /* index 100 */, + TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP, + TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT, + TILEGX_OPC_REVBITS, + BITFIELD(12, 3) /* index 109 */, + TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1, + TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(18, 2) /* index 118 */, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + BITFIELD(18, 2) /* index 123 */, + TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX, + BITFIELD(18, 2) /* index 128 */, + TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, + BITFIELD(18, 2) /* index 133 */, + TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR, + BITFIELD(12, 2) /* index 138 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143), + BITFIELD(14, 2) /* index 143 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148), + BITFIELD(16, 2) /* index 148 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(18, 2) /* index 153 */, + TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, + BITFIELD(18, 2) /* index 158 */, + TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADDX, + BITFIELD(18, 2) /* index 163 */, + TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS, + TILEGX_OPC_MUL_LU_LU, + BITFIELD(18, 2) /* index 168 */, + TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS, + TILEGX_OPC_MULA_LU_LU, + BITFIELD(18, 2) /* index 173 */, + TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, +}; + +static const unsigned short decode_Y1_fsm[167] = +{ + BITFIELD(58, 4) /* index 0 */, + TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122), + CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE, + BITFIELD(37, 2) /* index 17 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), + BITFIELD(39, 2) /* index 22 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), + BITFIELD(41, 2) /* index 27 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(31, 2) /* index 32 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), + BITFIELD(33, 2) /* index 37 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), + BITFIELD(35, 2) /* index 42 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), + BITFIELD(37, 2) /* index 47 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), + BITFIELD(39, 2) /* index 52 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), + BITFIELD(41, 2) /* index 57 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(49, 2) /* index 62 */, + TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + BITFIELD(47, 4) /* index 67 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84), + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(43, 3) /* index 84 */, + CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108), + CHILD(111), CHILD(114), + BITFIELD(46, 1) /* index 93 */, + TILEGX_OPC_NONE, TILEGX_OPC_FNOP, + BITFIELD(46, 1) /* index 96 */, + TILEGX_OPC_NONE, TILEGX_OPC_ILL, + BITFIELD(46, 1) /* index 99 */, + TILEGX_OPC_NONE, TILEGX_OPC_JALRP, + BITFIELD(46, 1) /* index 102 */, + TILEGX_OPC_NONE, TILEGX_OPC_JALR, + BITFIELD(46, 1) /* index 105 */, + TILEGX_OPC_NONE, TILEGX_OPC_JRP, + BITFIELD(46, 1) /* index 108 */, + TILEGX_OPC_NONE, TILEGX_OPC_JR, + BITFIELD(46, 1) /* index 111 */, + TILEGX_OPC_NONE, TILEGX_OPC_LNK, + BITFIELD(46, 1) /* index 114 */, + TILEGX_OPC_NONE, TILEGX_OPC_NOP, + BITFIELD(49, 2) /* index 117 */, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + BITFIELD(49, 2) /* index 122 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, + BITFIELD(49, 2) /* index 127 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, + BITFIELD(49, 2) /* index 132 */, + TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR, + BITFIELD(43, 2) /* index 137 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142), + BITFIELD(45, 2) /* index 142 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147), + BITFIELD(47, 2) /* index 147 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(49, 2) /* index 152 */, + TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, + BITFIELD(49, 2) /* index 157 */, + TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADDX, + BITFIELD(49, 2) /* index 162 */, + TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, +}; + +static const unsigned short decode_Y2_fsm[118] = +{ + BITFIELD(62, 2) /* index 0 */, + TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109), + BITFIELD(55, 3) /* index 5 */, + CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40), + CHILD(43), + BITFIELD(26, 1) /* index 14 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1U, + BITFIELD(26, 1) /* index 17 */, + CHILD(20), CHILD(30), + BITFIELD(51, 2) /* index 20 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25), + BITFIELD(53, 2) /* index 25 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, + TILEGX_OPC_PREFETCH_L1_FAULT, + BITFIELD(51, 2) /* index 30 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35), + BITFIELD(53, 2) /* index 35 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, + BITFIELD(26, 1) /* index 40 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2U, + BITFIELD(26, 1) /* index 43 */, + CHILD(46), CHILD(56), + BITFIELD(51, 2) /* index 46 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51), + BITFIELD(53, 2) /* index 51 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, + TILEGX_OPC_PREFETCH_L2_FAULT, + BITFIELD(51, 2) /* index 56 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61), + BITFIELD(53, 2) /* index 61 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, + BITFIELD(56, 2) /* index 66 */, + CHILD(71), CHILD(74), CHILD(90), CHILD(93), + BITFIELD(26, 1) /* index 71 */, + TILEGX_OPC_NONE, TILEGX_OPC_LD4S, + BITFIELD(26, 1) /* index 74 */, + TILEGX_OPC_NONE, CHILD(77), + BITFIELD(51, 2) /* index 77 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82), + BITFIELD(53, 2) /* index 82 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87), + BITFIELD(55, 1) /* index 87 */, + TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT, + BITFIELD(26, 1) /* index 90 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD, + BITFIELD(26, 1) /* index 93 */, + CHILD(96), TILEGX_OPC_LD, + BITFIELD(51, 2) /* index 96 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101), + BITFIELD(53, 2) /* index 101 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106), + BITFIELD(55, 1) /* index 106 */, + TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, + BITFIELD(26, 1) /* index 109 */, + CHILD(112), CHILD(115), + BITFIELD(57, 1) /* index 112 */, + TILEGX_OPC_ST1, TILEGX_OPC_ST4, + BITFIELD(57, 1) /* index 115 */, + TILEGX_OPC_ST2, TILEGX_OPC_ST, +}; + +#undef BITFIELD +#undef CHILD + +const unsigned short * const +tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] = +{ + decode_X0_fsm, + decode_X1_fsm, + decode_Y0_fsm, + decode_Y1_fsm, + decode_Y2_fsm +}; + +const struct tilegx_operand tilegx_operands[35] = +{ + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0), + 8, 1, 0, 0, 0, 0, + create_Imm8_X0, get_Imm8_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1), + 8, 1, 0, 0, 0, 0, + create_Imm8_X1, get_Imm8_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0), + 8, 1, 0, 0, 0, 0, + create_Imm8_Y0, get_Imm8_Y0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1), + 8, 1, 0, 0, 0, 0, + create_Imm8_Y1, get_Imm8_Y1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST), + 16, 1, 0, 0, 0, 0, + create_Imm16_X0, get_Imm16_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST), + 16, 1, 0, 0, 0, 0, + create_Imm16_X1, get_Imm16_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_X1, get_Dest_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_X1, get_SrcA_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_X0, get_Dest_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_X0, get_SrcA_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_Y0, get_Dest_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y0, get_SrcA_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_Y1, get_Dest_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y1, get_SrcA_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y2, get_SrcA_Y2 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_SrcA_X1, get_SrcA_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_X0, get_SrcB_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_X1, get_SrcB_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_Y0, get_SrcB_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_Y1, get_SrcB_Y1 + }, + { + TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1), + 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, + create_BrOff_X1, get_BrOff_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0), + 6, 0, 0, 0, 0, 0, + create_BFStart_X0, get_BFStart_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0), + 6, 0, 0, 0, 0, 0, + create_BFEnd_X0, get_BFEnd_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_Dest_X0, get_Dest_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_Dest_Y0, get_Dest_Y0 + }, + { + TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1), + 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, + create_JumpOff_X1, get_JumpOff_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_SrcBDest_Y2, get_SrcBDest_Y2 + }, + { + TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1), + 14, 0, 0, 0, 0, 0, + create_MF_Imm14_X1, get_MF_Imm14_X1 + }, + { + TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1), + 14, 0, 0, 0, 0, 0, + create_MT_Imm14_X1, get_MT_Imm14_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0), + 6, 0, 0, 0, 0, 0, + create_ShAmt_X0, get_ShAmt_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1), + 6, 0, 0, 0, 0, 0, + create_ShAmt_X1, get_ShAmt_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0), + 6, 0, 0, 0, 0, 0, + create_ShAmt_Y0, get_ShAmt_Y0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1), + 6, 0, 0, 0, 0, 0, + create_ShAmt_Y1, get_ShAmt_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcBDest_Y2, get_SrcBDest_Y2 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1), + 8, 1, 0, 0, 0, 0, + create_Dest_Imm8_X1, get_Dest_Imm8_X1 + } +}; + +/* Given a set of bundle bits and a specific pipe, returns which + * instruction the bundle contains in that pipe. + */ +const struct tilegx_opcode * +find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe) +{ + const unsigned short *table = tilegx_bundle_decoder_fsms[pipe]; + int index = 0; + + while (1) + { + unsigned short bitspec = table[index]; + unsigned int bitfield = + ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6); + + unsigned short next = table[index + 1 + bitfield]; + if (next <= TILEGX_OPC_NONE) + return &tilegx_opcodes[next]; + + index = next - TILEGX_OPC_NONE; + } +} + +int +parse_insn_tilegx(tilegx_bundle_bits bits, + unsigned long long pc, + struct tilegx_decoded_instruction + decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]) +{ + int num_instructions = 0; + int pipe; + + int min_pipe, max_pipe; + if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0) + { + min_pipe = TILEGX_PIPELINE_X0; + max_pipe = TILEGX_PIPELINE_X1; + } + else + { + min_pipe = TILEGX_PIPELINE_Y0; + max_pipe = TILEGX_PIPELINE_Y2; + } + + /* For each pipe, find an instruction that fits. */ + for (pipe = min_pipe; pipe <= max_pipe; pipe++) + { + const struct tilegx_opcode *opc; + struct tilegx_decoded_instruction *d; + int i; + + d = &decoded[num_instructions++]; + opc = find_opcode (bits, (tilegx_pipeline)pipe); + d->opcode = opc; + + /* Decode each operand, sign extending, etc. as appropriate. */ + for (i = 0; i < opc->num_operands; i++) + { + const struct tilegx_operand *op = + &tilegx_operands[opc->operands[pipe][i]]; + int raw_opval = op->extract (bits); + long long opval; + + if (op->is_signed) + { + /* Sign-extend the operand. */ + int shift = (int)((sizeof(int) * 8) - op->num_bits); + raw_opval = (raw_opval << shift) >> shift; + } + + /* Adjust PC-relative scaled branch offsets. */ + if (op->type == TILEGX_OP_TYPE_ADDRESS) + opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc; + else + opval = raw_opval; + + /* Record the final value. */ + d->operands[i] = op; + d->operand_values[i] = opval; + } + } + + return num_instructions; +} + +struct tilegx_spr +{ + /* The number */ + int number; + + /* The name */ + const char *name; +}; + +static int +tilegx_spr_compare (const void *a_ptr, const void *b_ptr) +{ + const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr; + const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr; + return (a->number - b->number); +} + +const struct tilegx_spr tilegx_sprs[] = { + { 0, "MPL_MEM_ERROR_SET_0" }, + { 1, "MPL_MEM_ERROR_SET_1" }, + { 2, "MPL_MEM_ERROR_SET_2" }, + { 3, "MPL_MEM_ERROR_SET_3" }, + { 4, "MPL_MEM_ERROR" }, + { 5, "MEM_ERROR_CBOX_ADDR" }, + { 6, "MEM_ERROR_CBOX_STATUS" }, + { 7, "MEM_ERROR_ENABLE" }, + { 8, "MEM_ERROR_MBOX_ADDR" }, + { 9, "MEM_ERROR_MBOX_STATUS" }, + { 10, "SBOX_ERROR" }, + { 11, "XDN_DEMUX_ERROR" }, + { 256, "MPL_SINGLE_STEP_3_SET_0" }, + { 257, "MPL_SINGLE_STEP_3_SET_1" }, + { 258, "MPL_SINGLE_STEP_3_SET_2" }, + { 259, "MPL_SINGLE_STEP_3_SET_3" }, + { 260, "MPL_SINGLE_STEP_3" }, + { 261, "SINGLE_STEP_CONTROL_3" }, + { 512, "MPL_SINGLE_STEP_2_SET_0" }, + { 513, "MPL_SINGLE_STEP_2_SET_1" }, + { 514, "MPL_SINGLE_STEP_2_SET_2" }, + { 515, "MPL_SINGLE_STEP_2_SET_3" }, + { 516, "MPL_SINGLE_STEP_2" }, + { 517, "SINGLE_STEP_CONTROL_2" }, + { 768, "MPL_SINGLE_STEP_1_SET_0" }, + { 769, "MPL_SINGLE_STEP_1_SET_1" }, + { 770, "MPL_SINGLE_STEP_1_SET_2" }, + { 771, "MPL_SINGLE_STEP_1_SET_3" }, + { 772, "MPL_SINGLE_STEP_1" }, + { 773, "SINGLE_STEP_CONTROL_1" }, + { 1024, "MPL_SINGLE_STEP_0_SET_0" }, + { 1025, "MPL_SINGLE_STEP_0_SET_1" }, + { 1026, "MPL_SINGLE_STEP_0_SET_2" }, + { 1027, "MPL_SINGLE_STEP_0_SET_3" }, + { 1028, "MPL_SINGLE_STEP_0" }, + { 1029, "SINGLE_STEP_CONTROL_0" }, + { 1280, "MPL_IDN_COMPLETE_SET_0" }, + { 1281, "MPL_IDN_COMPLETE_SET_1" }, + { 1282, "MPL_IDN_COMPLETE_SET_2" }, + { 1283, "MPL_IDN_COMPLETE_SET_3" }, + { 1284, "MPL_IDN_COMPLETE" }, + { 1285, "IDN_COMPLETE_PENDING" }, + { 1536, "MPL_UDN_COMPLETE_SET_0" }, + { 1537, "MPL_UDN_COMPLETE_SET_1" }, + { 1538, "MPL_UDN_COMPLETE_SET_2" }, + { 1539, "MPL_UDN_COMPLETE_SET_3" }, + { 1540, "MPL_UDN_COMPLETE" }, + { 1541, "UDN_COMPLETE_PENDING" }, + { 1792, "MPL_ITLB_MISS_SET_0" }, + { 1793, "MPL_ITLB_MISS_SET_1" }, + { 1794, "MPL_ITLB_MISS_SET_2" }, + { 1795, "MPL_ITLB_MISS_SET_3" }, + { 1796, "MPL_ITLB_MISS" }, + { 1797, "ITLB_TSB_BASE_ADDR_0" }, + { 1798, "ITLB_TSB_BASE_ADDR_1" }, + { 1920, "ITLB_CURRENT_ATTR" }, + { 1921, "ITLB_CURRENT_PA" }, + { 1922, "ITLB_CURRENT_VA" }, + { 1923, "ITLB_INDEX" }, + { 1924, "ITLB_MATCH_0" }, + { 1925, "ITLB_PERF" }, + { 1926, "ITLB_PR" }, + { 1927, "ITLB_TSB_ADDR_0" }, + { 1928, "ITLB_TSB_ADDR_1" }, + { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" }, + { 1930, "ITLB_TSB_FILL_MATCH" }, + { 1931, "NUMBER_ITLB" }, + { 1932, "REPLACEMENT_ITLB" }, + { 1933, "WIRED_ITLB" }, + { 2048, "MPL_ILL_SET_0" }, + { 2049, "MPL_ILL_SET_1" }, + { 2050, "MPL_ILL_SET_2" }, + { 2051, "MPL_ILL_SET_3" }, + { 2052, "MPL_ILL" }, + { 2304, "MPL_GPV_SET_0" }, + { 2305, "MPL_GPV_SET_1" }, + { 2306, "MPL_GPV_SET_2" }, + { 2307, "MPL_GPV_SET_3" }, + { 2308, "MPL_GPV" }, + { 2309, "GPV_REASON" }, + { 2560, "MPL_IDN_ACCESS_SET_0" }, + { 2561, "MPL_IDN_ACCESS_SET_1" }, + { 2562, "MPL_IDN_ACCESS_SET_2" }, + { 2563, "MPL_IDN_ACCESS_SET_3" }, + { 2564, "MPL_IDN_ACCESS" }, + { 2565, "IDN_DEMUX_COUNT_0" }, + { 2566, "IDN_DEMUX_COUNT_1" }, + { 2567, "IDN_FLUSH_EGRESS" }, + { 2568, "IDN_PENDING" }, + { 2569, "IDN_ROUTE_ORDER" }, + { 2570, "IDN_SP_FIFO_CNT" }, + { 2688, "IDN_DATA_AVAIL" }, + { 2816, "MPL_UDN_ACCESS_SET_0" }, + { 2817, "MPL_UDN_ACCESS_SET_1" }, + { 2818, "MPL_UDN_ACCESS_SET_2" }, + { 2819, "MPL_UDN_ACCESS_SET_3" }, + { 2820, "MPL_UDN_ACCESS" }, + { 2821, "UDN_DEMUX_COUNT_0" }, + { 2822, "UDN_DEMUX_COUNT_1" }, + { 2823, "UDN_DEMUX_COUNT_2" }, + { 2824, "UDN_DEMUX_COUNT_3" }, + { 2825, "UDN_FLUSH_EGRESS" }, + { 2826, "UDN_PENDING" }, + { 2827, "UDN_ROUTE_ORDER" }, + { 2828, "UDN_SP_FIFO_CNT" }, + { 2944, "UDN_DATA_AVAIL" }, + { 3072, "MPL_SWINT_3_SET_0" }, + { 3073, "MPL_SWINT_3_SET_1" }, + { 3074, "MPL_SWINT_3_SET_2" }, + { 3075, "MPL_SWINT_3_SET_3" }, + { 3076, "MPL_SWINT_3" }, + { 3328, "MPL_SWINT_2_SET_0" }, + { 3329, "MPL_SWINT_2_SET_1" }, + { 3330, "MPL_SWINT_2_SET_2" }, + { 3331, "MPL_SWINT_2_SET_3" }, + { 3332, "MPL_SWINT_2" }, + { 3584, "MPL_SWINT_1_SET_0" }, + { 3585, "MPL_SWINT_1_SET_1" }, + { 3586, "MPL_SWINT_1_SET_2" }, + { 3587, "MPL_SWINT_1_SET_3" }, + { 3588, "MPL_SWINT_1" }, + { 3840, "MPL_SWINT_0_SET_0" }, + { 3841, "MPL_SWINT_0_SET_1" }, + { 3842, "MPL_SWINT_0_SET_2" }, + { 3843, "MPL_SWINT_0_SET_3" }, + { 3844, "MPL_SWINT_0" }, + { 4096, "MPL_ILL_TRANS_SET_0" }, + { 4097, "MPL_ILL_TRANS_SET_1" }, + { 4098, "MPL_ILL_TRANS_SET_2" }, + { 4099, "MPL_ILL_TRANS_SET_3" }, + { 4100, "MPL_ILL_TRANS" }, + { 4101, "ILL_TRANS_REASON" }, + { 4102, "ILL_VA_PC" }, + { 4352, "MPL_UNALIGN_DATA_SET_0" }, + { 4353, "MPL_UNALIGN_DATA_SET_1" }, + { 4354, "MPL_UNALIGN_DATA_SET_2" }, + { 4355, "MPL_UNALIGN_DATA_SET_3" }, + { 4356, "MPL_UNALIGN_DATA" }, + { 4608, "MPL_DTLB_MISS_SET_0" }, + { 4609, "MPL_DTLB_MISS_SET_1" }, + { 4610, "MPL_DTLB_MISS_SET_2" }, + { 4611, "MPL_DTLB_MISS_SET_3" }, + { 4612, "MPL_DTLB_MISS" }, + { 4613, "DTLB_TSB_BASE_ADDR_0" }, + { 4614, "DTLB_TSB_BASE_ADDR_1" }, + { 4736, "AAR" }, + { 4737, "CACHE_PINNED_WAYS" }, + { 4738, "DTLB_BAD_ADDR" }, + { 4739, "DTLB_BAD_ADDR_REASON" }, + { 4740, "DTLB_CURRENT_ATTR" }, + { 4741, "DTLB_CURRENT_PA" }, + { 4742, "DTLB_CURRENT_VA" }, + { 4743, "DTLB_INDEX" }, + { 4744, "DTLB_MATCH_0" }, + { 4745, "DTLB_PERF" }, + { 4746, "DTLB_TSB_ADDR_0" }, + { 4747, "DTLB_TSB_ADDR_1" }, + { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" }, + { 4749, "DTLB_TSB_FILL_MATCH" }, + { 4750, "NUMBER_DTLB" }, + { 4751, "REPLACEMENT_DTLB" }, + { 4752, "WIRED_DTLB" }, + { 4864, "MPL_DTLB_ACCESS_SET_0" }, + { 4865, "MPL_DTLB_ACCESS_SET_1" }, + { 4866, "MPL_DTLB_ACCESS_SET_2" }, + { 4867, "MPL_DTLB_ACCESS_SET_3" }, + { 4868, "MPL_DTLB_ACCESS" }, + { 5120, "MPL_IDN_FIREWALL_SET_0" }, + { 5121, "MPL_IDN_FIREWALL_SET_1" }, + { 5122, "MPL_IDN_FIREWALL_SET_2" }, + { 5123, "MPL_IDN_FIREWALL_SET_3" }, + { 5124, "MPL_IDN_FIREWALL" }, + { 5125, "IDN_DIRECTION_PROTECT" }, + { 5376, "MPL_UDN_FIREWALL_SET_0" }, + { 5377, "MPL_UDN_FIREWALL_SET_1" }, + { 5378, "MPL_UDN_FIREWALL_SET_2" }, + { 5379, "MPL_UDN_FIREWALL_SET_3" }, + { 5380, "MPL_UDN_FIREWALL" }, + { 5381, "UDN_DIRECTION_PROTECT" }, + { 5632, "MPL_TILE_TIMER_SET_0" }, + { 5633, "MPL_TILE_TIMER_SET_1" }, + { 5634, "MPL_TILE_TIMER_SET_2" }, + { 5635, "MPL_TILE_TIMER_SET_3" }, + { 5636, "MPL_TILE_TIMER" }, + { 5637, "TILE_TIMER_CONTROL" }, + { 5888, "MPL_AUX_TILE_TIMER_SET_0" }, + { 5889, "MPL_AUX_TILE_TIMER_SET_1" }, + { 5890, "MPL_AUX_TILE_TIMER_SET_2" }, + { 5891, "MPL_AUX_TILE_TIMER_SET_3" }, + { 5892, "MPL_AUX_TILE_TIMER" }, + { 5893, "AUX_TILE_TIMER_CONTROL" }, + { 6144, "MPL_IDN_TIMER_SET_0" }, + { 6145, "MPL_IDN_TIMER_SET_1" }, + { 6146, "MPL_IDN_TIMER_SET_2" }, + { 6147, "MPL_IDN_TIMER_SET_3" }, + { 6148, "MPL_IDN_TIMER" }, + { 6149, "IDN_DEADLOCK_COUNT" }, + { 6150, "IDN_DEADLOCK_TIMEOUT" }, + { 6400, "MPL_UDN_TIMER_SET_0" }, + { 6401, "MPL_UDN_TIMER_SET_1" }, + { 6402, "MPL_UDN_TIMER_SET_2" }, + { 6403, "MPL_UDN_TIMER_SET_3" }, + { 6404, "MPL_UDN_TIMER" }, + { 6405, "UDN_DEADLOCK_COUNT" }, + { 6406, "UDN_DEADLOCK_TIMEOUT" }, + { 6656, "MPL_IDN_AVAIL_SET_0" }, + { 6657, "MPL_IDN_AVAIL_SET_1" }, + { 6658, "MPL_IDN_AVAIL_SET_2" }, + { 6659, "MPL_IDN_AVAIL_SET_3" }, + { 6660, "MPL_IDN_AVAIL" }, + { 6661, "IDN_AVAIL_EN" }, + { 6912, "MPL_UDN_AVAIL_SET_0" }, + { 6913, "MPL_UDN_AVAIL_SET_1" }, + { 6914, "MPL_UDN_AVAIL_SET_2" }, + { 6915, "MPL_UDN_AVAIL_SET_3" }, + { 6916, "MPL_UDN_AVAIL" }, + { 6917, "UDN_AVAIL_EN" }, + { 7168, "MPL_IPI_3_SET_0" }, + { 7169, "MPL_IPI_3_SET_1" }, + { 7170, "MPL_IPI_3_SET_2" }, + { 7171, "MPL_IPI_3_SET_3" }, + { 7172, "MPL_IPI_3" }, + { 7173, "IPI_EVENT_3" }, + { 7174, "IPI_EVENT_RESET_3" }, + { 7175, "IPI_EVENT_SET_3" }, + { 7176, "IPI_MASK_3" }, + { 7177, "IPI_MASK_RESET_3" }, + { 7178, "IPI_MASK_SET_3" }, + { 7424, "MPL_IPI_2_SET_0" }, + { 7425, "MPL_IPI_2_SET_1" }, + { 7426, "MPL_IPI_2_SET_2" }, + { 7427, "MPL_IPI_2_SET_3" }, + { 7428, "MPL_IPI_2" }, + { 7429, "IPI_EVENT_2" }, + { 7430, "IPI_EVENT_RESET_2" }, + { 7431, "IPI_EVENT_SET_2" }, + { 7432, "IPI_MASK_2" }, + { 7433, "IPI_MASK_RESET_2" }, + { 7434, "IPI_MASK_SET_2" }, + { 7680, "MPL_IPI_1_SET_0" }, + { 7681, "MPL_IPI_1_SET_1" }, + { 7682, "MPL_IPI_1_SET_2" }, + { 7683, "MPL_IPI_1_SET_3" }, + { 7684, "MPL_IPI_1" }, + { 7685, "IPI_EVENT_1" }, + { 7686, "IPI_EVENT_RESET_1" }, + { 7687, "IPI_EVENT_SET_1" }, + { 7688, "IPI_MASK_1" }, + { 7689, "IPI_MASK_RESET_1" }, + { 7690, "IPI_MASK_SET_1" }, + { 7936, "MPL_IPI_0_SET_0" }, + { 7937, "MPL_IPI_0_SET_1" }, + { 7938, "MPL_IPI_0_SET_2" }, + { 7939, "MPL_IPI_0_SET_3" }, + { 7940, "MPL_IPI_0" }, + { 7941, "IPI_EVENT_0" }, + { 7942, "IPI_EVENT_RESET_0" }, + { 7943, "IPI_EVENT_SET_0" }, + { 7944, "IPI_MASK_0" }, + { 7945, "IPI_MASK_RESET_0" }, + { 7946, "IPI_MASK_SET_0" }, + { 8192, "MPL_PERF_COUNT_SET_0" }, + { 8193, "MPL_PERF_COUNT_SET_1" }, + { 8194, "MPL_PERF_COUNT_SET_2" }, + { 8195, "MPL_PERF_COUNT_SET_3" }, + { 8196, "MPL_PERF_COUNT" }, + { 8197, "PERF_COUNT_0" }, + { 8198, "PERF_COUNT_1" }, + { 8199, "PERF_COUNT_CTL" }, + { 8200, "PERF_COUNT_DN_CTL" }, + { 8201, "PERF_COUNT_STS" }, + { 8202, "WATCH_MASK" }, + { 8203, "WATCH_VAL" }, + { 8448, "MPL_AUX_PERF_COUNT_SET_0" }, + { 8449, "MPL_AUX_PERF_COUNT_SET_1" }, + { 8450, "MPL_AUX_PERF_COUNT_SET_2" }, + { 8451, "MPL_AUX_PERF_COUNT_SET_3" }, + { 8452, "MPL_AUX_PERF_COUNT" }, + { 8453, "AUX_PERF_COUNT_0" }, + { 8454, "AUX_PERF_COUNT_1" }, + { 8455, "AUX_PERF_COUNT_CTL" }, + { 8456, "AUX_PERF_COUNT_STS" }, + { 8704, "MPL_INTCTRL_3_SET_0" }, + { 8705, "MPL_INTCTRL_3_SET_1" }, + { 8706, "MPL_INTCTRL_3_SET_2" }, + { 8707, "MPL_INTCTRL_3_SET_3" }, + { 8708, "MPL_INTCTRL_3" }, + { 8709, "INTCTRL_3_STATUS" }, + { 8710, "INTERRUPT_MASK_3" }, + { 8711, "INTERRUPT_MASK_RESET_3" }, + { 8712, "INTERRUPT_MASK_SET_3" }, + { 8713, "INTERRUPT_VECTOR_BASE_3" }, + { 8714, "SINGLE_STEP_EN_0_3" }, + { 8715, "SINGLE_STEP_EN_1_3" }, + { 8716, "SINGLE_STEP_EN_2_3" }, + { 8717, "SINGLE_STEP_EN_3_3" }, + { 8832, "EX_CONTEXT_3_0" }, + { 8833, "EX_CONTEXT_3_1" }, + { 8834, "SYSTEM_SAVE_3_0" }, + { 8835, "SYSTEM_SAVE_3_1" }, + { 8836, "SYSTEM_SAVE_3_2" }, + { 8837, "SYSTEM_SAVE_3_3" }, + { 8960, "MPL_INTCTRL_2_SET_0" }, + { 8961, "MPL_INTCTRL_2_SET_1" }, + { 8962, "MPL_INTCTRL_2_SET_2" }, + { 8963, "MPL_INTCTRL_2_SET_3" }, + { 8964, "MPL_INTCTRL_2" }, + { 8965, "INTCTRL_2_STATUS" }, + { 8966, "INTERRUPT_MASK_2" }, + { 8967, "INTERRUPT_MASK_RESET_2" }, + { 8968, "INTERRUPT_MASK_SET_2" }, + { 8969, "INTERRUPT_VECTOR_BASE_2" }, + { 8970, "SINGLE_STEP_EN_0_2" }, + { 8971, "SINGLE_STEP_EN_1_2" }, + { 8972, "SINGLE_STEP_EN_2_2" }, + { 8973, "SINGLE_STEP_EN_3_2" }, + { 9088, "EX_CONTEXT_2_0" }, + { 9089, "EX_CONTEXT_2_1" }, + { 9090, "SYSTEM_SAVE_2_0" }, + { 9091, "SYSTEM_SAVE_2_1" }, + { 9092, "SYSTEM_SAVE_2_2" }, + { 9093, "SYSTEM_SAVE_2_3" }, + { 9216, "MPL_INTCTRL_1_SET_0" }, + { 9217, "MPL_INTCTRL_1_SET_1" }, + { 9218, "MPL_INTCTRL_1_SET_2" }, + { 9219, "MPL_INTCTRL_1_SET_3" }, + { 9220, "MPL_INTCTRL_1" }, + { 9221, "INTCTRL_1_STATUS" }, + { 9222, "INTERRUPT_MASK_1" }, + { 9223, "INTERRUPT_MASK_RESET_1" }, + { 9224, "INTERRUPT_MASK_SET_1" }, + { 9225, "INTERRUPT_VECTOR_BASE_1" }, + { 9226, "SINGLE_STEP_EN_0_1" }, + { 9227, "SINGLE_STEP_EN_1_1" }, + { 9228, "SINGLE_STEP_EN_2_1" }, + { 9229, "SINGLE_STEP_EN_3_1" }, + { 9344, "EX_CONTEXT_1_0" }, + { 9345, "EX_CONTEXT_1_1" }, + { 9346, "SYSTEM_SAVE_1_0" }, + { 9347, "SYSTEM_SAVE_1_1" }, + { 9348, "SYSTEM_SAVE_1_2" }, + { 9349, "SYSTEM_SAVE_1_3" }, + { 9472, "MPL_INTCTRL_0_SET_0" }, + { 9473, "MPL_INTCTRL_0_SET_1" }, + { 9474, "MPL_INTCTRL_0_SET_2" }, + { 9475, "MPL_INTCTRL_0_SET_3" }, + { 9476, "MPL_INTCTRL_0" }, + { 9477, "INTCTRL_0_STATUS" }, + { 9478, "INTERRUPT_MASK_0" }, + { 9479, "INTERRUPT_MASK_RESET_0" }, + { 9480, "INTERRUPT_MASK_SET_0" }, + { 9481, "INTERRUPT_VECTOR_BASE_0" }, + { 9482, "SINGLE_STEP_EN_0_0" }, + { 9483, "SINGLE_STEP_EN_1_0" }, + { 9484, "SINGLE_STEP_EN_2_0" }, + { 9485, "SINGLE_STEP_EN_3_0" }, + { 9600, "EX_CONTEXT_0_0" }, + { 9601, "EX_CONTEXT_0_1" }, + { 9602, "SYSTEM_SAVE_0_0" }, + { 9603, "SYSTEM_SAVE_0_1" }, + { 9604, "SYSTEM_SAVE_0_2" }, + { 9605, "SYSTEM_SAVE_0_3" }, + { 9728, "MPL_BOOT_ACCESS_SET_0" }, + { 9729, "MPL_BOOT_ACCESS_SET_1" }, + { 9730, "MPL_BOOT_ACCESS_SET_2" }, + { 9731, "MPL_BOOT_ACCESS_SET_3" }, + { 9732, "MPL_BOOT_ACCESS" }, + { 9733, "BIG_ENDIAN_CONFIG" }, + { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" }, + { 9735, "CACHE_INVALIDATION_MASK_0" }, + { 9736, "CACHE_INVALIDATION_MASK_1" }, + { 9737, "CACHE_INVALIDATION_MASK_2" }, + { 9738, "CBOX_CACHEASRAM_CONFIG" }, + { 9739, "CBOX_CACHE_CONFIG" }, + { 9740, "CBOX_HOME_MAP_ADDR" }, + { 9741, "CBOX_HOME_MAP_DATA" }, + { 9742, "CBOX_MMAP_0" }, + { 9743, "CBOX_MMAP_1" }, + { 9744, "CBOX_MMAP_2" }, + { 9745, "CBOX_MMAP_3" }, + { 9746, "CBOX_MSR" }, + { 9747, "DIAG_BCST_CTL" }, + { 9748, "DIAG_BCST_MASK" }, + { 9749, "DIAG_BCST_TRIGGER" }, + { 9750, "DIAG_MUX_CTL" }, + { 9751, "DIAG_TRACE_CTL" }, + { 9752, "DIAG_TRACE_DATA" }, + { 9753, "DIAG_TRACE_STS" }, + { 9754, "IDN_DEMUX_BUF_THRESH" }, + { 9755, "L1_I_PIN_WAY_0" }, + { 9756, "MEM_ROUTE_ORDER" }, + { 9757, "MEM_STRIPE_CONFIG" }, + { 9758, "PERF_COUNT_PLS" }, + { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" }, + { 9760, "QUIESCE_CTL" }, + { 9761, "RSHIM_COORD" }, + { 9762, "SBOX_CONFIG" }, + { 9763, "UDN_DEMUX_BUF_THRESH" }, + { 9764, "XDN_CORE_STARVATION_COUNT" }, + { 9765, "XDN_ROUND_ROBIN_ARB_CTL" }, + { 9856, "CYCLE_MODIFY" }, + { 9857, "I_AAR" }, + { 9984, "MPL_WORLD_ACCESS_SET_0" }, + { 9985, "MPL_WORLD_ACCESS_SET_1" }, + { 9986, "MPL_WORLD_ACCESS_SET_2" }, + { 9987, "MPL_WORLD_ACCESS_SET_3" }, + { 9988, "MPL_WORLD_ACCESS" }, + { 9989, "DONE" }, + { 9990, "DSTREAM_PF" }, + { 9991, "FAIL" }, + { 9992, "INTERRUPT_CRITICAL_SECTION" }, + { 9993, "PASS" }, + { 9994, "PSEUDO_RANDOM_NUMBER" }, + { 9995, "TILE_COORD" }, + { 9996, "TILE_RTF_HWM" }, + { 10112, "CMPEXCH_VALUE" }, + { 10113, "CYCLE" }, + { 10114, "EVENT_BEGIN" }, + { 10115, "EVENT_END" }, + { 10116, "PROC_STATUS" }, + { 10117, "SIM_CONTROL" }, + { 10118, "SIM_SOCKET" }, + { 10119, "STATUS_SATURATE" }, + { 10240, "MPL_I_ASID_SET_0" }, + { 10241, "MPL_I_ASID_SET_1" }, + { 10242, "MPL_I_ASID_SET_2" }, + { 10243, "MPL_I_ASID_SET_3" }, + { 10244, "MPL_I_ASID" }, + { 10245, "I_ASID" }, + { 10496, "MPL_D_ASID_SET_0" }, + { 10497, "MPL_D_ASID_SET_1" }, + { 10498, "MPL_D_ASID_SET_2" }, + { 10499, "MPL_D_ASID_SET_3" }, + { 10500, "MPL_D_ASID" }, + { 10501, "D_ASID" }, + { 10752, "MPL_DOUBLE_FAULT_SET_0" }, + { 10753, "MPL_DOUBLE_FAULT_SET_1" }, + { 10754, "MPL_DOUBLE_FAULT_SET_2" }, + { 10755, "MPL_DOUBLE_FAULT_SET_3" }, + { 10756, "MPL_DOUBLE_FAULT" }, + { 10757, "LAST_INTERRUPT_REASON" }, +}; + +const int tilegx_num_sprs = 441; + +const char * +get_tilegx_spr_name (int num) +{ + void *result; + struct tilegx_spr key; + + key.number = num; + result = bsearch((const void *) &key, (const void *) tilegx_sprs, + tilegx_num_sprs, sizeof (struct tilegx_spr), + tilegx_spr_compare); + + if (result == NULL) + { + return (NULL); + } + else + { + struct tilegx_spr *result_ptr = (struct tilegx_spr *) result; + return (result_ptr->name); + } +} + +int +print_insn_tilegx (unsigned char * memaddr) +{ + struct tilegx_decoded_instruction + decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; + unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES]; + int i, num_instructions, num_printed; + tilegx_mnemonic padding_mnemonic; + + memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES); + + /* Parse the instructions in the bundle. */ + num_instructions = + parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded); + + /* Print the instructions in the bundle. */ + printf("{ "); + num_printed = 0; + + /* Determine which nop opcode is used for padding and should be skipped. */ + padding_mnemonic = TILEGX_OPC_FNOP; + for (i = 0; i < num_instructions; i++) + { + if (!decoded[i].opcode->can_bundle) + { + /* Instructions that cannot be bundled are padded out with nops, + rather than fnops. Displaying them is always clutter. */ + padding_mnemonic = TILEGX_OPC_NOP; + break; + } + } + + for (i = 0; i < num_instructions; i++) + { + const struct tilegx_opcode *opcode = decoded[i].opcode; + const char *name; + int j; + + /* Do not print out fnops, unless everything is an fnop, in + which case we will print out just the last one. */ + if (opcode->mnemonic == padding_mnemonic + && (num_printed > 0 || i + 1 < num_instructions)) + continue; + + if (num_printed > 0) + printf(" ; "); + ++num_printed; + + name = opcode->name; + if (name == NULL) + name = ""; + printf("%s", name); + + for (j = 0; j < opcode->num_operands; j++) + { + unsigned long long num; + const struct tilegx_operand *op; + const char *spr_name; + + if (j > 0) + printf (","); + printf (" "); + + num = decoded[i].operand_values[j]; + + op = decoded[i].operands[j]; + switch (op->type) + { + case TILEGX_OP_TYPE_REGISTER: + printf ("%s", tilegx_register_names[(int)num]); + break; + case TILEGX_OP_TYPE_SPR: + spr_name = get_tilegx_spr_name(num); + if (spr_name != NULL) + printf ("%s", spr_name); + else + printf ("%d", (int)num); + break; + case TILEGX_OP_TYPE_IMMEDIATE: + printf ("%d", (int)num); + break; + case TILEGX_OP_TYPE_ADDRESS: + printf ("0x%016llx", num); + break; + default: + abort (); + } + } + } + printf (" }\n"); + + return TILEGX_BUNDLE_SIZE_IN_BYTES; +} diff --git a/pcre2/src/sljit/sljitNativeTILEGX_64.c b/pcre2/src/sljit/sljitNativeTILEGX_64.c new file mode 100644 index 000000000..4d40392fa --- /dev/null +++ b/pcre2/src/sljit/sljitNativeTILEGX_64.c @@ -0,0 +1,2561 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TileGX architecture. */ +/* Contributed by Tilera Corporation. */ +#include "sljitNativeTILEGX-encoder.c" + +#define SIMM_8BIT_MAX (0x7f) +#define SIMM_8BIT_MIN (-0x80) +#define SIMM_16BIT_MAX (0x7fff) +#define SIMM_16BIT_MIN (-0x8000) +#define SIMM_17BIT_MAX (0xffff) +#define SIMM_17BIT_MIN (-0x10000) +#define SIMM_32BIT_MAX (0x7fffffff) +#define SIMM_32BIT_MIN (-0x7fffffff - 1) +#define SIMM_48BIT_MAX (0x7fffffff0000L) +#define SIMM_48BIT_MIN (-0x800000000000L) +#define IMM16(imm) ((imm) & 0xffff) + +#define UIMM_16BIT_MAX (0xffff) + +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) +#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5) +#define PIC_ADDR_REG TMP_REG2 + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { + 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 +}; + +#define SLJIT_LOCALS_REG_mapped 54 +#define TMP_REG1_mapped 5 +#define TMP_REG2_mapped 16 +#define TMP_REG3_mapped 6 +#define ADDR_TMP_mapped 7 + +/* Flags are keept in volatile registers. */ +#define EQUAL_FLAG 8 +/* And carry flag as well. */ +#define ULESS_FLAG 9 +#define UGREATER_FLAG 10 +#define LESS_FLAG 11 +#define GREATER_FLAG 12 +#define OVERFLOW_FLAG 13 + +#define ZERO 63 +#define RA 55 +#define TMP_EREG1 14 +#define TMP_EREG2 15 + +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +#define DOUBLE_DATA 0x10 + +/* Separates integer and floating point registers */ +#define GPR_REG 0xf + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define LOGICAL_OP 0x00200 +#define IMM_OP 0x00400 +#define SRC2_IMM 0x00800 + +#define UNUSED_DEST 0x01000 +#define REG_DEST 0x02000 +#define REG1_SOURCE 0x04000 +#define REG2_SOURCE 0x08000 +#define SLOW_SRC1 0x10000 +#define SLOW_SRC2 0x20000 +#define SLOW_DEST 0x40000 + +/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. + */ +#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void) +{ + return "TileGX" SLJIT_CPUINFO; +} + +/* Length of an instruction word */ +typedef sljit_uw sljit_ins; + +struct jit_instr { + const struct tilegx_opcode* opcode; + tilegx_pipeline pipe; + unsigned long input_registers; + unsigned long output_registers; + int operand_value[4]; + int line; +}; + +/* Opcode Helper Macros */ +#define TILEGX_X_MODE 0 + +#define X_MODE create_Mode(TILEGX_X_MODE) + +#define FNOP_X0 \ + create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) + +#define FNOP_X1 \ + create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1) + +#define NOP \ + create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1 + +#define ANOP_X0 \ + create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0) + +#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \ + create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0 + +#define ADD_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0 + +#define ADDI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0 + +#define SUB_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0 + +#define NOR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define OR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define AND_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0 + +#define XOR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define CMOVNEZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1 + +#define CMOVEQZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1 + +#define ADDLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0 + +#define V4INT_L_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0 + +#define BFEXTU_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ + create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1 + +#define BFEXTS_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ + create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1 + +#define SHL16INSLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0 + +#define ST_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0 + +#define LD_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0 + +#define JR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0 + +#define JALR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0 + +#define CLZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1 + +#define CMPLTUI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0 + +#define CMPLTU_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0 + +#define CMPLTS_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0 + +#define XORI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0 + +#define ORI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0 + +#define ANDI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0 + +#define SHLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHL_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0 + +#define SHRSI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHRS_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0 + +#define SHRUI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHRU_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0 + +#define BEQZ_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ + create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0 + +#define BNEZ_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ + create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0 + +#define J_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ + create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0 + +#define JAL_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ + create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0 + +#define DEST_X0(x) create_Dest_X0(x) +#define SRCA_X0(x) create_SrcA_X0(x) +#define SRCB_X0(x) create_SrcB_X0(x) +#define DEST_X1(x) create_Dest_X1(x) +#define SRCA_X1(x) create_SrcA_X1(x) +#define SRCB_X1(x) create_SrcB_X1(x) +#define IMM16_X1(x) create_Imm16_X1(x) +#define IMM8_X1(x) create_Imm8_X1(x) +#define BFSTART_X0(x) create_BFStart_X0(x) +#define BFEND_X0(x) create_BFEnd_X0(x) +#define SHIFTIMM_X1(x) create_ShAmt_X1(x) +#define JOFF_X1(x) create_JumpOff_X1(x) +#define BOFF_X1(x) create_BrOff_X1(x) + +static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { + /* u w s */ TILEGX_OPC_ST /* st */, + /* u w l */ TILEGX_OPC_LD /* ld */, + /* u b s */ TILEGX_OPC_ST1 /* st1 */, + /* u b l */ TILEGX_OPC_LD1U /* ld1u */, + /* u h s */ TILEGX_OPC_ST2 /* st2 */, + /* u h l */ TILEGX_OPC_LD2U /* ld2u */, + /* u i s */ TILEGX_OPC_ST4 /* st4 */, + /* u i l */ TILEGX_OPC_LD4U /* ld4u */, + /* s w s */ TILEGX_OPC_ST /* st */, + /* s w l */ TILEGX_OPC_LD /* ld */, + /* s b s */ TILEGX_OPC_ST1 /* st1 */, + /* s b l */ TILEGX_OPC_LD1S /* ld1s */, + /* s h s */ TILEGX_OPC_ST2 /* st2 */, + /* s h l */ TILEGX_OPC_LD2S /* ld2s */, + /* s i s */ TILEGX_OPC_ST4 /* st4 */, + /* s i l */ TILEGX_OPC_LD4S /* ld4s */, +}; + +#ifdef TILEGX_JIT_DEBUG +static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) +{ + sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + printf("|%04d|S0|:\t\t", line); + print_insn_tilegx(ptr); + return SLJIT_SUCCESS; +} + +static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + return SLJIT_SUCCESS; +} + +#define push_inst(a, b) push_inst_debug(a, b, __LINE__) +#else +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + return SLJIT_SUCCESS; +} +#endif + +#define BUNDLE_FORMAT_MASK(p0, p1, p2) \ + ((p0) | ((p1) << 8) | ((p2) << 16)) + +#define BUNDLE_FORMAT(p0, p1, p2) \ + { \ + { \ + (tilegx_pipeline)(p0), \ + (tilegx_pipeline)(p1), \ + (tilegx_pipeline)(p2) \ + }, \ + BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \ + } + +#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS + +#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1) + +#define PI(encoding) \ + push_inst(compiler, encoding) + +#define PB3(opcode, dst, srca, srcb) \ + push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__) + +#define PB2(opcode, dst, src) \ + push_2_buffer(compiler, opcode, dst, src, __LINE__) + +#define JR(reg) \ + push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__) + +#define ADD(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__) + +#define SUB(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__) + +#define MUL(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__) + +#define NOR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__) + +#define OR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__) + +#define XOR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__) + +#define AND(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__) + +#define CLZ(dst, src) \ + push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__) + +#define SHLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__) + +#define SHRUI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__) + +#define XORI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__) + +#define ORI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__) + +#define CMPLTU(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__) + +#define CMPLTS(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__) + +#define CMPLTUI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__) + +#define CMOVNEZ(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__) + +#define CMOVEQZ(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__) + +#define ADDLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__) + +#define SHL16INSLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__) + +#define LD_ADD(dst, addr, adjust) \ + push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__) + +#define ST_ADD(src, addr, adjust) \ + push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__) + +#define LD(dst, addr) \ + push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__) + +#define BFEXTU(dst, src, start, end) \ + push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__) + +#define BFEXTS(dst, src, start, end) \ + push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__) + +#define ADD_SOLO(dest, srca, srcb) \ + push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb)) + +#define ADDI_SOLO(dest, srca, imm) \ + push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm)) + +#define ADDLI_SOLO(dest, srca, imm) \ + push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) + +#define SHL16INSLI_SOLO(dest, srca, imm) \ + push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) + +#define JALR_SOLO(reg) \ + push_inst(compiler, JALR_X1 | SRCA_X1(reg)) + +#define JR_SOLO(reg) \ + push_inst(compiler, JR_X1 | SRCA_X1(reg)) + +struct Format { + /* Mapping of bundle issue slot to assigned pipe. */ + tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; + + /* Mask of pipes used by this bundle. */ + unsigned int pipe_mask; +}; + +const struct Format formats[] = +{ + /* In Y format we must always have something in Y2, since it has + * no fnop, so this conveys that Y2 must always be used. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE), + + /* Y format has three instructions. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0), + + /* X format has only two instructions. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE) +}; + + +struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; +unsigned long inst_buf_index; + +tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode) +{ + /* FIXME: tile: we could pregenerate this. */ + int pipe; + for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++) + ; + return (tilegx_pipeline)(pipe); +} + +void insert_nop(tilegx_mnemonic opc, int line) +{ + const struct tilegx_opcode* opcode = NULL; + + memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]); + + opcode = &tilegx_opcodes[opc]; + inst_buf[0].opcode = opcode; + inst_buf[0].pipe = get_any_valid_pipe(opcode); + inst_buf[0].input_registers = 0; + inst_buf[0].output_registers = 0; + inst_buf[0].line = line; + ++inst_buf_index; +} + +const struct Format* compute_format() +{ + unsigned int compatible_pipes = BUNDLE_FORMAT_MASK( + inst_buf[0].opcode->pipes, + inst_buf[1].opcode->pipes, + (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE))); + + const struct Format* match = NULL; + const struct Format *b = NULL; + unsigned int i; + for (i = 0; i < sizeof formats / sizeof formats[0]; i++) { + b = &formats[i]; + if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) { + match = b; + break; + } + } + + return match; +} + +sljit_si assign_pipes() +{ + unsigned long output_registers = 0; + unsigned int i = 0; + + if (inst_buf_index == 1) { + tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle + ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP; + insert_nop(opc, __LINE__); + } + + const struct Format* match = compute_format(); + + if (match == NULL) + return -1; + + for (i = 0; i < inst_buf_index; i++) { + + if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0)) + return -1; + + if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0)) + return -1; + + /* Don't include Rzero in the match set, to avoid triggering + needlessly on 'prefetch' instrs. */ + + output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL; + + inst_buf[i].pipe = match->pipe[i]; + } + + /* If only 2 instrs, and in Y-mode, insert a nop. */ + if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) { + insert_nop(TILEGX_OPC_FNOP, __LINE__); + + /* Select the yet unassigned pipe. */ + tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0 + + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2) + - (inst_buf[1].pipe + inst_buf[2].pipe))); + + inst_buf[0].pipe = pipe; + } + + return 0; +} + +tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) +{ + int i, val; + const struct tilegx_opcode* opcode = inst->opcode; + tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe]; + + const struct tilegx_operand* operand = NULL; + for (i = 0; i < opcode->num_operands; i++) { + operand = &tilegx_operands[opcode->operands[inst->pipe][i]]; + val = inst->operand_value[i]; + + bits |= operand->insert(val); + } + + return bits; +} + +static sljit_si update_buffer(struct sljit_compiler *compiler) +{ + int i; + int orig_index = inst_buf_index; + struct jit_instr inst0 = inst_buf[0]; + struct jit_instr inst1 = inst_buf[1]; + struct jit_instr inst2 = inst_buf[2]; + tilegx_bundle_bits bits = 0; + + /* If the bundle is valid as is, perform the encoding and return 1. */ + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M0|:\t"); + else + printf("|M0|:\t\t"); + print_insn_tilegx(&bits); +#endif + + inst_buf_index = 0; + +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } + + /* If the bundle is invalid, split it in two. First encode the first two + (or possibly 1) instructions, and then the last, separately. Note that + assign_pipes may have re-ordered the instrs (by inserting no-ops in + lower slots) so we need to reset them. */ + + inst_buf_index = orig_index - 1; + inst_buf[0] = inst0; + inst_buf[1] = inst1; + inst_buf[2] = inst2; + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } + +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M1|:\t"); + else + printf("|M1|:\t\t"); + print_insn_tilegx(&bits); +#endif + + if ((orig_index - 1) == 2) { + inst_buf[0] = inst2; + inst_buf_index = 1; + } else if ((orig_index - 1) == 1) { + inst_buf[0] = inst1; + inst_buf_index = 1; + } else + SLJIT_ASSERT_STOP(); + +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } else { + /* We had 3 instrs of which the first 2 can't live in the same bundle. + Split those two. Note that we don't try to then combine the second + and third instr into a single bundle. First instruction: */ + inst_buf_index = 1; + inst_buf[0] = inst0; + inst_buf[1] = inst1; + inst_buf[2] = inst2; + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } + +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M2|:\t"); + else + printf("|M2|:\t\t"); + print_insn_tilegx(&bits); +#endif + + inst_buf[0] = inst1; + inst_buf[1] = inst2; + inst_buf_index = orig_index - 1; +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } else + SLJIT_ASSERT_STOP(); + } + + SLJIT_ASSERT_STOP(); +} + +static sljit_si flush_buffer(struct sljit_compiler *compiler) +{ + while (inst_buf_index != 0) { + FAIL_IF(update_buffer(compiler)); + } + return SLJIT_SUCCESS; +} + +static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].operand_value[2] = op2; + inst_buf[inst_buf_index].operand_value[3] = op3; + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].operand_value[2] = op2; + inst_buf[inst_buf_index].line = line; + + switch (opc) { + case TILEGX_OPC_ST_ADD: + inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + case TILEGX_OPC_LD_ADD: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1); + break; + case TILEGX_OPC_ADD: + case TILEGX_OPC_AND: + case TILEGX_OPC_SUB: + case TILEGX_OPC_MULX: + case TILEGX_OPC_OR: + case TILEGX_OPC_XOR: + case TILEGX_OPC_NOR: + case TILEGX_OPC_SHL: + case TILEGX_OPC_SHRU: + case TILEGX_OPC_SHRS: + case TILEGX_OPC_CMPLTU: + case TILEGX_OPC_CMPLTS: + case TILEGX_OPC_CMOVEQZ: + case TILEGX_OPC_CMOVNEZ: + inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2); + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + case TILEGX_OPC_ADDLI: + case TILEGX_OPC_XORI: + case TILEGX_OPC_ORI: + case TILEGX_OPC_SHLI: + case TILEGX_OPC_SHRUI: + case TILEGX_OPC_SHRSI: + case TILEGX_OPC_SHL16INSLI: + case TILEGX_OPC_CMPLTUI: + case TILEGX_OPC_CMPLTSI: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + default: + printf("unrecoginzed opc: %s\n", opcode->name); + SLJIT_ASSERT_STOP(); + } + + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].line = line; + + switch (opc) { + case TILEGX_OPC_BEQZ: + case TILEGX_OPC_BNEZ: + inst_buf[inst_buf_index].input_registers = 1L << op0; + break; + case TILEGX_OPC_ST: + case TILEGX_OPC_ST1: + case TILEGX_OPC_ST2: + case TILEGX_OPC_ST4: + inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); + inst_buf[inst_buf_index].output_registers = 0; + break; + case TILEGX_OPC_CLZ: + case TILEGX_OPC_LD: + case TILEGX_OPC_LD1U: + case TILEGX_OPC_LD1S: + case TILEGX_OPC_LD2U: + case TILEGX_OPC_LD2S: + case TILEGX_OPC_LD4U: + case TILEGX_OPC_LD4S: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + default: + printf("unrecoginzed opc: %s\n", opcode->name); + SLJIT_ASSERT_STOP(); + } + + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].input_registers = 0; + inst_buf[inst_buf_index].output_registers = 0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].input_registers = 1L << op0; + inst_buf[inst_buf_index].output_registers = 0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return flush_buffer(compiler); +} + +static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + sljit_ins *inst; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return code_ptr; + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + + inst = (sljit_ins *)jump->addr; + if (jump->flags & IS_COND) + inst--; + + diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3; + if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + if (jump->flags & IS_JAL) { + jump->flags &= ~(PATCH_B); + jump->flags |= PATCH_J; + inst[0] = JAL_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } else { + inst[0] = BEQZ_X1 | SRCA_X1(ZERO); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } + + return inst; + } + + inst[0] = inst[0] ^ (0x7L << 55); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + jump->addr -= sizeof(sljit_ins); + return inst; + } + + if (jump->flags & IS_COND) { + if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { + jump->flags |= PATCH_J; + inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2); + inst[1] = J_X1; + return inst + 1; + } + + return code_ptr; + } + + if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { + jump->flags |= PATCH_J; + + if (jump->flags & IS_JAL) { + inst[0] = JAL_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + + } else { + inst[0] = J_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } + + return inst; + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins *)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 3); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw) code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + if (jump && jump->addr == word_count) { + if (jump->flags & IS_JAL) + jump->addr = (sljit_uw)(code_ptr - 4); + else + jump->addr = (sljit_uw)(code_ptr - 3); + + code_ptr = detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw) code_ptr; + const_ = const_->next; + } + + code_ptr++; + word_count++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw) code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins *)jump->addr; + + if (jump->flags & PATCH_B) { + addr = (sljit_sw)(addr - (jump->addr)) >> 3; + SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN); + buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(buf_ptr); +#endif + break; + } + + if (jump->flags & PATCH_J) { + SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)); + addr = (sljit_sw)(addr - (jump->addr)) >> 3; + buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(buf_ptr); +#endif + break; + } + + SLJIT_ASSERT(!(jump->flags & IS_JAL)); + + /* Set the fields of immediate loads. */ + buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43); + buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43); + buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43); + } while (0); + + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +{ + + if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) + return ADDLI(dst_ar, ZERO, imm); + + if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) { + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); + } + + if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) { + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); + } + + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); +} + +static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +{ + /* Should *not* be optimized as load_immediate, as pcre relocation + mechanism will match this fixed 4-instruction pattern. */ + if (flush) { + FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI_SOLO(dst_ar, dst_ar, imm); + } + + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); +} + +static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +{ + /* Should *not* be optimized as load_immediate, as pcre relocation + mechanism will match this fixed 4-instruction pattern. */ + if (flush) { + FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); + FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); + return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm); + } + + FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); + FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); + return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_ins base; + sljit_si i, tmp; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + local_size = (local_size + 7) & ~7; + compiler->local_size = local_size; + + if (local_size <= SIMM_16BIT_MAX) { + /* Frequent case. */ + FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size)); + base = SLJIT_LOCALS_REG_mapped; + } else { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); + FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO)); + FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); + base = TMP_REG2_mapped; + local_size = 0; + } + + /* Save the return address. */ + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); + FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8)); + + /* Save the S registers. */ + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) { + FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); + } + + /* Save the R registers that need to be reserved. */ + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); + } + + /* Move the arguments to S registers. */ + for (i = 0; i < args; i++) { + FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + compiler->local_size = (local_size + 7) & ~7; + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si local_size; + sljit_ins base; + sljit_si i, tmp; + sljit_si saveds; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + local_size = compiler->local_size; + if (local_size <= SIMM_16BIT_MAX) + base = SLJIT_LOCALS_REG_mapped; + else { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); + FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); + base = TMP_REG1_mapped; + local_size = 0; + } + + /* Restore the return address. */ + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); + FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8)); + + /* Restore the S registers. */ + saveds = compiler->saveds; + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) { + FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); + } + + /* Restore the R registers that need to be reserved. */ + for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); + } + + if (compiler->local_size <= SIMM_16BIT_MAX) + FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size)); + else + FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO)); + + return JR(RA); +} + +/* reg_ar is an absoulute register! */ + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) + && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + /* Works for both absoulte and relative addresses. */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw)); + + if (flags & LOAD_DATA) + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); + else + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); + + return -1; + } + + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* Simple operation except for updates. */ + if (arg & OFFS_REG_MASK) { + argw &= 0x3; + next_argw &= 0x3; + if (argw && argw == next_argw + && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) + return 1; + return 0; + } + + if (arg == next_arg) { + if (((next_argw - argw) <= SIMM_16BIT_MAX + && (next_argw - argw) >= SIMM_16BIT_MIN)) + return 1; + + return 0; + } + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_ar, base; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) + tmp_ar = reg_ar; + else + tmp_ar = TMP_REG1_mapped; + + base = arg & REG_MASK; + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + + if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar); + FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); + reg_ar = TMP_REG1_mapped; + } + + /* Using the cache. */ + if (argw == compiler->cache_argw) { + if (!(flags & WRITE_BACK)) { + if (arg == compiler->cache_arg) { + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); + } + } else { + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + } + } + + if (SLJIT_UNLIKELY(argw)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw)); + } + + if (!(flags & WRITE_BACK)) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + tmp_ar = TMP_REG3_mapped; + } else + FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); + } + + FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + + if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { + /* Update only applies if a base register exists. */ + if (reg_ar == reg_map[base]) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar); + if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw)); + if (flags & LOAD_DATA) + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); + else + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); + + if (argw) + return ADDLI(reg_map[base], reg_map[base], argw); + + return SLJIT_SUCCESS; + } + + FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); + reg_ar = TMP_REG1_mapped; + } + + if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + if (argw) + FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw)); + } else { + if (compiler->cache_arg == SLJIT_MEM + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + compiler->cache_argw = argw; + } + + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + } else { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + } + } + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + + if (compiler->cache_arg == arg + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + compiler->cache_argw = argw; + } + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if (compiler->cache_arg == SLJIT_MEM + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) + FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + } else { + compiler->cache_arg = SLJIT_MEM; + FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); + } + + compiler->cache_argw = argw; + + if (!base) { + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if (arg == next_arg + && next_argw - argw <= SIMM_16BIT_MAX + && next_argw - argw >= SIMM_16BIT_MIN) { + compiler->cache_arg = arg; + FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base])); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) + return compiler->error; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return ADD(reg_map[dst], RA, ZERO); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(ADD(RA, reg_map[src], ZERO)); + + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw)); + + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, RA, srcw)); + + return JR(RA); +} + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) +{ + sljit_si overflow_ra = 0; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return ADD(reg_map[dst], reg_map[src2], ZERO); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SI) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); + } else if (dst != src2) { + SLJIT_ASSERT(src2 == 0); + return ADD(reg_map[dst], reg_map[src2], ZERO); + } + + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); + } else if (dst != src2) { + SLJIT_ASSERT(src2 == 0); + return ADD(reg_map[dst], reg_map[src2], ZERO); + } + + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); + } else if (dst != src2) { + SLJIT_ASSERT(src2 == 0); + return ADD(reg_map[dst], reg_map[src2], ZERO); + } + + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2])); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2])); + + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2])); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(CLZ(reg_map[dst], reg_map[src2])); + + return SLJIT_SUCCESS; + + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63)); + if (src2 < 0) + FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2)); + + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2)); + else { + FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2)); + FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG)); + } + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); + + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63)); + + if (src2 < 0) + FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1)); + } + } else { + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); + FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else if (src2 != dst) + overflow_ra = reg_map[src2]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_C) + FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2])); + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra)); + FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); + } + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG)); + + if (op & SLJIT_SET_O) + return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); + + return SLJIT_SUCCESS; + + case SLJIT_ADDC: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2)); + else { + FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2)); + FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1)); + } + } + + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); + + } else { + if (op & SLJIT_SET_C) + FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2])); + + /* dst may be the same as src1 or src2. */ + FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1)); + + FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG)); + + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1)); + FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG)); + /* Set carry flag. */ + return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) { + FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63)); + + if (src2 < 0) + FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2)); + + if (op & SLJIT_SET_C) { + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); + FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped)); + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); + + } else { + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); + FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2])); + + if (op & (SLJIT_SET_U | SLJIT_SET_C)) + FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_U) + FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1])); + + if (op & SLJIT_SET_S) { + FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2])); + FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1])); + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) + FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra)); + FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); + return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); + } + + return SLJIT_SUCCESS; + + case SLJIT_SUBC: + if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) { + FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2)); + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped)); + } + + /* dst may be the same as src1 or src2. */ + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); + + } else { + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2])); + /* dst may be the same as src1 or src2. */ + FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_C) + FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG)); + + FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG)); + + if (op & SLJIT_SET_C) + FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO)); + + return SLJIT_SUCCESS; + + case SLJIT_MUL: + if (flags & SRC2_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2)); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2])); + + return SLJIT_SUCCESS; + +#define EMIT_LOGICAL(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ + ADDR_TMP_mapped, __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + ADDR_TMP_mapped, __LINE__)); \ + } else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ + reg_map[src2], __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + reg_map[src2], __LINE__)); \ + } + + case SLJIT_AND: + EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND); + return SLJIT_SUCCESS; + + case SLJIT_OR: + EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR); + return SLJIT_SUCCESS; + + case SLJIT_XOR: + EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR); + return SLJIT_SUCCESS; + +#define EMIT_SHIFT(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_imm, EQUAL_FLAG, reg_map[src1], \ + src2 & 0x3F, __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_imm, reg_map[dst], reg_map[src1], \ + src2 & 0x3F, __LINE__)); \ + } else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ + reg_map[src2], __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + reg_map[src2], __LINE__)); \ + } + + case SLJIT_SHL: + EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS); + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +{ + /* arg1 goes to TMP_REG1 or src reg. + arg2 goes to TMP_REG2, imm or src reg. + TMP_REG3 can be used for caching. + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + if (GET_FLAGS(op)) + flags |= UNUSED_DEST; + } else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if ((!(flags & LOGICAL_OP) + && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN)) + || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + + if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if ((!(flags & LOGICAL_OP) + && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN)) + || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) { + src1_r = src1; + flags |= REG1_SOURCE; + } else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w)); + src1_r = TMP_REG1; + } else + src1_r = 0; + } else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (FAST_IS_REG(src2)) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } else if (src2 & SLJIT_IMM) { + if (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w)); + src2_r = sugg_src2_r; + } else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } + } + } else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + src2_r = sugg_src2_r; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + SLJIT_ASSERT(src2_r == TMP_REG2); + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); + } else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw)); + } + } else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw)); + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw); + return compiler->error; + } + + return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type) +{ + sljit_si sugg_dst_ar, dst_ar; + sljit_si flags = GET_ALL_FLAGS(op); + sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + mem_type = INT_DATA | SIGNED_DATA; + sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + switch (type & 0xff) { + case SLJIT_EQUAL: + case SLJIT_NOT_EQUAL: + FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1)); + dst_ar = sugg_dst_ar; + break; + case SLJIT_LESS: + case SLJIT_GREATER_EQUAL: + dst_ar = ULESS_FLAG; + break; + case SLJIT_GREATER: + case SLJIT_LESS_EQUAL: + dst_ar = UGREATER_FLAG; + break; + case SLJIT_SIG_LESS: + case SLJIT_SIG_GREATER_EQUAL: + dst_ar = LESS_FLAG; + break; + case SLJIT_SIG_GREATER: + case SLJIT_SIG_LESS_EQUAL: + dst_ar = GREATER_FLAG; + break; + case SLJIT_OVERFLOW: + case SLJIT_NOT_OVERFLOW: + dst_ar = OVERFLOW_FLAG; + break; + case SLJIT_MUL_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1)); + dst_ar = sugg_dst_ar; + type ^= 0x1; /* Flip type bit for the XORI below. */ + break; + + default: + SLJIT_ASSERT_STOP(); + dst_ar = sugg_dst_ar; + break; + } + + if (type & 0x1) { + FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1)); + dst_ar = sugg_dst_ar; + } + + if (op >= SLJIT_ADD) { + if (TMP_REG2_mapped != dst_ar) + FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO)); + return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw); + + if (sugg_dst_ar != dst_ar) + return ADD(sugg_dst_ar, dst_ar, ZERO); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_NOP: + return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__); + + case SLJIT_BREAKPOINT: + return PI(BPT); + + case SLJIT_LUMUL: + case SLJIT_LSMUL: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + SLJIT_ASSERT_STOP(); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (src2 & SLJIT_IMM) + src2w &= 0x3f; + if (op & SLJIT_INT_OP) + src2w &= 0x1f; + + return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + flush_buffer(compiler); + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_si src_r = TMP_REG2; + struct sljit_jump *jump = NULL; + + flush_buffer(compiler); + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) { + if (reg_map[src] != 0) + src_r = src; + else + FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO)); + } + + if (type >= SLJIT_CALL0) { + SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); + if (src & (SLJIT_IMM | SLJIT_MEM)) { + if (src & SLJIT_IMM) + FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1)); + else { + SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + } + + FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); + + FAIL_IF(ADDI_SOLO(54, 54, -16)); + + FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG])); + + return ADDI_SOLO(54, 54, 16); + } + + /* Register input. */ + if (type >= SLJIT_CALL1) + FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); + + FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO)); + + FAIL_IF(ADDI_SOLO(54, 54, -16)); + + FAIL_IF(JALR_SOLO(reg_map[src_r])); + + return ADDI_SOLO(54, 54, 16); + } + + if (src & SLJIT_IMM) { + jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); + jump->u.target = srcw; + FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); + + if (type >= SLJIT_FAST_CALL) { + FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO)); + jump->addr = compiler->size; + FAIL_IF(JR_SOLO(reg_map[src_r])); + } else { + jump->addr = compiler->size; + FAIL_IF(JR_SOLO(reg_map[src_r])); + } + + return SLJIT_SUCCESS; + + } else if (src & SLJIT_MEM) { + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + flush_buffer(compiler); + } + + FAIL_IF(JR_SOLO(reg_map[src_r])); + + if (jump) + jump->addr = compiler->size; + + return SLJIT_SUCCESS; +} + +#define BR_Z(src) \ + inst = BEQZ_X1 | SRCA_X1(src); \ + flags = IS_COND; + +#define BR_NZ(src) \ + inst = BNEZ_X1 | SRCA_X1(src); \ + flags = IS_COND; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si flags = 0; + + flush_buffer(compiler); + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + switch (type) { + case SLJIT_EQUAL: + BR_NZ(EQUAL_FLAG); + break; + case SLJIT_NOT_EQUAL: + BR_Z(EQUAL_FLAG); + break; + case SLJIT_LESS: + BR_Z(ULESS_FLAG); + break; + case SLJIT_GREATER_EQUAL: + BR_NZ(ULESS_FLAG); + break; + case SLJIT_GREATER: + BR_Z(UGREATER_FLAG); + break; + case SLJIT_LESS_EQUAL: + BR_NZ(UGREATER_FLAG); + break; + case SLJIT_SIG_LESS: + BR_Z(LESS_FLAG); + break; + case SLJIT_SIG_GREATER_EQUAL: + BR_NZ(LESS_FLAG); + break; + case SLJIT_SIG_GREATER: + BR_Z(GREATER_FLAG); + break; + case SLJIT_SIG_LESS_EQUAL: + BR_NZ(GREATER_FLAG); + break; + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + BR_Z(OVERFLOW_FLAG); + break; + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + BR_NZ(OVERFLOW_FLAG); + break; + default: + /* Not conditional branch. */ + inst = 0; + break; + } + + jump->flags |= flags; + + if (inst) { + inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6)); + PTR_FAIL_IF(PI(inst)); + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); + if (type <= SLJIT_JUMP) { + jump->addr = compiler->size; + PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped)); + } else { + SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); + /* Cannot be optimized out if type is >= CALL0. */ + jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); + PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); + jump->addr = compiler->size; + PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped)); + } + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +{ + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +{ + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si reg; + + flush_buffer(compiler); + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = FAST_IS_REG(dst) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins *)addr; + + inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43); + inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43); + inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43); + SLJIT_CACHE_FLUSH(inst, inst + 3); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins *)addr; + + inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43); + inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43); + inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43); + inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + return SLJIT_ERR_UNSUPPORTED; +} + diff --git a/pcre2/src/sljit/sljitNativeX86_32.c b/pcre2/src/sljit/sljitNativeX86_32.c new file mode 100644 index 000000000..d7129c8e2 --- /dev/null +++ b/pcre2/src/sljit/sljitNativeX86_32.c @@ -0,0 +1,550 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* x86 32-bit arch dependent functions. */ + +static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) +{ + sljit_ub *inst; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); + FAIL_IF(!inst); + INC_SIZE(1 + sizeof(sljit_sw)); + *inst++ = opcode; + *(sljit_sw*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +{ + if (type == SLJIT_JUMP) { + *code_ptr++ = JMP_i32; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + *code_ptr++ = CALL_i32; + jump->addr++; + } + else { + *code_ptr++ = GROUP_0F; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MW; + else + *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4); + code_ptr += 4; + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si size; + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + compiler->args = args; + compiler->flags_saved = 0; + + size = 1 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3); +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0); +#else + size += (args > 0 ? (2 + args * 3) : 0); +#endif + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + PUSH_REG(reg_map[TMP_REG1]); +#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (args > 0) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */; + } +#endif + if (saveds > 2 || scratches > 7) + PUSH_REG(reg_map[SLJIT_S2]); + if (saveds > 1 || scratches > 8) + PUSH_REG(reg_map[SLJIT_S1]); + if (saveds > 0 || scratches > 9) + PUSH_REG(reg_map[SLJIT_S0]); + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (args > 0) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2]; + } + if (args > 1) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1]; + } + if (args > 2) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */; + *inst++ = 0x24; + *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ + } +#else + if (args > 0) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1]; + *inst++ = sizeof(sljit_sw) * 2; + } + if (args > 1) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1]; + *inst++ = sizeof(sljit_sw) * 3; + } + if (args > 2) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1]; + *inst++ = sizeof(sljit_sw) * 4; + } +#endif + + SLJIT_COMPILE_ASSERT(SLJIT_LOCALS_OFFSET >= (2 + 4) * sizeof(sljit_uw), require_at_least_two_words); +#if defined(__APPLE__) + /* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */ + saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); + local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds; +#else + if (options & SLJIT_DOUBLE_ALIGNMENT) { + local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 17); + FAIL_IF(!inst); + + INC_SIZE(17); + inst[0] = MOV_r_rm; + inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP]; + inst[2] = GROUP_F7; + inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP]; + *(sljit_sw*)(inst + 4) = 0x4; + inst[8] = JNE_i8; + inst[9] = 6; + inst[10] = GROUP_BINARY_81; + inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP]; + *(sljit_sw*)(inst + 12) = 0x4; + inst[16] = PUSH_r + reg_map[TMP_REG1]; + } + else + local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3); +#endif + + compiler->local_size = local_size; +#ifdef _WIN32 + if (local_size > 1024) { +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); +#else + local_size -= SLJIT_LOCALS_OFFSET; + FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); + FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, SLJIT_LOCALS_OFFSET)); +#endif + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + } +#endif + + SLJIT_ASSERT(local_size > 0); + return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + compiler->args = args; + +#if defined(__APPLE__) + saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); + compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds; +#else + if (options & SLJIT_DOUBLE_ALIGNMENT) + compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); + else + compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3); +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si size; + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + SLJIT_ASSERT(compiler->args >= 0); + + compiler->flags_saved = 0; + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + SLJIT_ASSERT(compiler->local_size > 0); + FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size)); + +#if !defined(__APPLE__) + if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + + INC_SIZE(3); + inst[0] = MOV_r_rm; + inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */; + inst[2] = (4 << 3) | reg_map[SLJIT_SP]; + } +#endif + + size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) + + (compiler->saveds <= 3 ? compiler->saveds : 3); +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (compiler->args > 2) + size += 2; +#else + if (compiler->args > 0) + size += 2; +#endif + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + + if (compiler->saveds > 0 || compiler->scratches > 9) + POP_REG(reg_map[SLJIT_S0]); + if (compiler->saveds > 1 || compiler->scratches > 8) + POP_REG(reg_map[SLJIT_S1]); + if (compiler->saveds > 2 || compiler->scratches > 7) + POP_REG(reg_map[SLJIT_S2]); + POP_REG(reg_map[TMP_REG1]); +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (compiler->args > 2) + RET_I16(sizeof(sljit_sw)); + else + RET(); +#else + RET(); +#endif + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* Size contains the flags as well. */ +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, + /* The register or immediate operand. */ + sljit_si a, sljit_sw imma, + /* The general operand (not immediate). */ + sljit_si b, sljit_sw immb) +{ + sljit_ub *inst; + sljit_ub *buf_ptr; + sljit_si flags = size & ~0xf; + sljit_si inst_size; + + /* Both cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); + /* Size flags not allowed for typed instructions. */ + SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); + /* Both size flags cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); + /* SSE2 and immediate is not possible. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); + SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) + && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) + && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + + size &= 0xf; + inst_size = size; + + if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) + inst_size++; + if (flags & EX86_PREF_66) + inst_size++; + + /* Calculate size of b. */ + inst_size += 1; /* mod r/m byte. */ + if (b & SLJIT_MEM) { + if ((b & REG_MASK) == SLJIT_UNUSED) + inst_size += sizeof(sljit_sw); + else if (immb != 0 && !(b & OFFS_REG_MASK)) { + /* Immediate operand. */ + if (immb <= 127 && immb >= -128) + inst_size += sizeof(sljit_sb); + else + inst_size += sizeof(sljit_sw); + } + + if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK)) + b |= TO_OFFS_REG(SLJIT_SP); + + if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) + inst_size += 1; /* SIB byte. */ + } + + /* Calculate size of a. */ + if (a & SLJIT_IMM) { + if (flags & EX86_BIN_INS) { + if (imma <= 127 && imma >= -128) { + inst_size += 1; + flags |= EX86_BYTE_ARG; + } else + inst_size += 4; + } + else if (flags & EX86_SHIFT_INS) { + imma &= 0x1f; + if (imma != 1) { + inst_size ++; + flags |= EX86_BYTE_ARG; + } + } else if (flags & EX86_BYTE_ARG) + inst_size++; + else if (flags & EX86_HALF_ARG) + inst_size += sizeof(short); + else + inst_size += sizeof(sljit_sw); + } + else + SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!inst); + + /* Encoding the byte. */ + INC_SIZE(inst_size); + if (flags & EX86_PREF_F2) + *inst++ = 0xf2; + if (flags & EX86_PREF_F3) + *inst++ = 0xf3; + if (flags & EX86_PREF_66) + *inst++ = 0x66; + + buf_ptr = inst + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + + if ((a & SLJIT_IMM) || (a == 0)) + *buf_ptr = 0; + else if (!(flags & EX86_SSE2_OP1)) + *buf_ptr = reg_map[a] << 3; + else + *buf_ptr = a << 3; + } + else { + if (a & SLJIT_IMM) { + if (imma == 1) + *inst = GROUP_SHIFT_1; + else + *inst = GROUP_SHIFT_N; + } else + *inst = GROUP_SHIFT_CL; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) + *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : b); + else if ((b & REG_MASK) != SLJIT_UNUSED) { + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) { + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr |= 0x40; + else + *buf_ptr |= 0x80; + } + + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) + *buf_ptr++ |= reg_map[b & REG_MASK]; + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3); + } + + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr++ = immb; /* 8 bit displacement. */ + else { + *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_sw); + } + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6); + } + } + else { + *buf_ptr++ |= 0x05; + *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_sw); + } + + if (a & SLJIT_IMM) { + if (flags & EX86_BYTE_ARG) + *buf_ptr = imma; + else if (flags & EX86_HALF_ARG) + *(short*)buf_ptr = imma; + else if (!(flags & EX86_SHIFT_INS)) + *(sljit_sw*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + FAIL_IF(!inst); + INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); + + if (type >= SLJIT_CALL3) + PUSH_REG(reg_map[SLJIT_R2]); + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0]; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); + FAIL_IF(!inst); + INC_SIZE(4 * (type - SLJIT_CALL0)); + + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; + *inst++ = 0; + if (type >= SLJIT_CALL2) { + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; + *inst++ = sizeof(sljit_sw); + } + if (type >= SLJIT_CALL3) { + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; + *inst++ = 2 * sizeof(sljit_sw); + } +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + dst = TMP_REG1; + + if (FAST_IS_REG(dst)) { + /* Unused dest is possible here. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1); + POP_REG(reg_map[dst]); + return SLJIT_SUCCESS; + } + + /* Memory. */ + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = POP_rm; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (FAST_IS_REG(src)) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1 + 1); + PUSH_REG(reg_map[src]); + } + else if (src & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= PUSH_rm; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + } + else { + /* SLJIT_IMM. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!inst); + + INC_SIZE(5 + 1); + *inst++ = PUSH_i32; + *(sljit_sw*)inst = srcw; + inst += sizeof(sljit_sw); + } + + RET(); + return SLJIT_SUCCESS; +} diff --git a/pcre2/src/sljit/sljitNativeX86_64.c b/pcre2/src/sljit/sljitNativeX86_64.c new file mode 100644 index 000000000..1790d8a4d --- /dev/null +++ b/pcre2/src/sljit/sljitNativeX86_64.c @@ -0,0 +1,747 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* x86 64-bit arch dependent functions. */ + +static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +{ + sljit_ub *inst; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); + FAIL_IF(!inst); + INC_SIZE(2 + sizeof(sljit_sw)); + *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7); + *(sljit_sw*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +{ + if (type < SLJIT_JUMP) { + /* Invert type. */ + *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10; + *code_ptr++ = 10 + 3; + } + + SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first); + *code_ptr++ = REX_W | REX_B; + *code_ptr++ = MOV_r_i32 + 1; + jump->addr = (sljit_uw)code_ptr; + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MD; + else + *(sljit_sw*)code_ptr = jump->u.target; + + code_ptr += sizeof(sljit_sw); + *code_ptr++ = REX_B; + *code_ptr++ = GROUP_FF; + *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + + return code_ptr; +} + +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) +{ + sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); + + if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) { + *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; + *(sljit_sw*)code_ptr = delta; + } + else { + SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); + *code_ptr++ = REX_W | REX_B; + *code_ptr++ = MOV_r_i32 + 1; + *(sljit_sw*)code_ptr = addr; + code_ptr += sizeof(sljit_sw); + *code_ptr++ = REX_B; + *code_ptr++ = GROUP_FF; + *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si i, tmp, size, saved_register_size; + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + compiler->flags_saved = 0; + + /* Including the return address saved by the call instruction. */ + saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + + tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; + for (i = SLJIT_S0; i >= tmp; i--) { + size = reg_map[i] >= 8 ? 2 : 1; + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + if (reg_map[i] >= 8) + *inst++ = REX_B; + PUSH_REG(reg_lmap[i]); + } + + for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { + size = reg_map[i] >= 8 ? 2 : 1; + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + if (reg_map[i] >= 8) + *inst++ = REX_B; + PUSH_REG(reg_lmap[i]); + } + + if (args > 0) { + size = args * 3; + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + +#ifndef _WIN64 + if (args > 0) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */; + } + if (args > 1) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */; + } + if (args > 2) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */; + } +#else + if (args > 0) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */; + } + if (args > 1) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */; + } + if (args > 2) { + *inst++ = REX_W | REX_B; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */; + } +#endif + } + + local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size; + compiler->local_size = local_size; + +#ifdef _WIN64 + if (local_size > 1024) { + /* Allocate stack for the callback, which grows the stack. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); + FAIL_IF(!inst); + INC_SIZE(4 + (3 + sizeof(sljit_si))); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | SUB | 4; + /* Allocated size for registers must be divisible by 8. */ + SLJIT_ASSERT(!(saved_register_size & 0x7)); + /* Aligned to 16 byte. */ + if (saved_register_size & 0x8) { + *inst++ = 5 * sizeof(sljit_sw); + local_size -= 5 * sizeof(sljit_sw); + } else { + *inst++ = 4 * sizeof(sljit_sw); + local_size -= 4 * sizeof(sljit_sw); + } + /* Second instruction */ + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg); + *inst++ = REX_W; + *inst++ = MOV_rm_i32; + *inst++ = MOD_REG | reg_lmap[SLJIT_R0]; + *(sljit_si*)inst = local_size; +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + } +#endif + + SLJIT_ASSERT(local_size > 0); + if (local_size <= 127) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | SUB | 4; + *inst++ = local_size; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!inst); + INC_SIZE(7); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_81; + *inst++ = MOD_REG | SUB | 4; + *(sljit_si*)inst = local_size; + inst += sizeof(sljit_si); + } + +#ifdef _WIN64 + /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */ + if (fscratches >= 6 || fsaveds >= 1) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = GROUP_0F; + *(sljit_si*)inst = 0x20247429; + } +#endif + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, + sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, + sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +{ + sljit_si saved_register_size; + + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); + + /* Including the return address saved by the call instruction. */ + saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); + compiler->local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si i, tmp, size; + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + compiler->flags_saved = 0; + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + +#ifdef _WIN64 + /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */ + if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = GROUP_0F; + *(sljit_si*)inst = 0x20247428; + } +#endif + + SLJIT_ASSERT(compiler->local_size > 0); + if (compiler->local_size <= 127) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | ADD | 4; + *inst = compiler->local_size; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!inst); + INC_SIZE(7); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_81; + *inst++ = MOD_REG | ADD | 4; + *(sljit_si*)inst = compiler->local_size; + } + + tmp = compiler->scratches; + for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { + size = reg_map[i] >= 8 ? 2 : 1; + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + if (reg_map[i] >= 8) + *inst++ = REX_B; + POP_REG(reg_lmap[i]); + } + + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + for (i = tmp; i <= SLJIT_S0; i++) { + size = reg_map[i] >= 8 ? 2 : 1; + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + if (reg_map[i] >= 8) + *inst++ = REX_B; + POP_REG(reg_lmap[i]); + } + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + RET(); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) +{ + sljit_ub *inst; + sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + length); + FAIL_IF(!inst); + INC_SIZE(length); + if (rex) + *inst++ = rex; + *inst++ = opcode; + *(sljit_si*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, + /* The register or immediate operand. */ + sljit_si a, sljit_sw imma, + /* The general operand (not immediate). */ + sljit_si b, sljit_sw immb) +{ + sljit_ub *inst; + sljit_ub *buf_ptr; + sljit_ub rex = 0; + sljit_si flags = size & ~0xf; + sljit_si inst_size; + + /* The immediate operand must be 32 bit. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); + /* Both cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); + /* Size flags not allowed for typed instructions. */ + SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); + /* Both size flags cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); + /* SSE2 and immediate is not possible. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); + SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) + && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) + && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + + size &= 0xf; + inst_size = size; + + if (!compiler->mode32 && !(flags & EX86_NO_REXW)) + rex |= REX_W; + else if (flags & EX86_REX) + rex |= REX; + + if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) + inst_size++; + if (flags & EX86_PREF_66) + inst_size++; + + /* Calculate size of b. */ + inst_size += 1; /* mod r/m byte. */ + if (b & SLJIT_MEM) { + if (!(b & OFFS_REG_MASK)) { + if (NOT_HALFWORD(immb)) { + if (emit_load_imm64(compiler, TMP_REG3, immb)) + return NULL; + immb = 0; + if (b & REG_MASK) + b |= TO_OFFS_REG(TMP_REG3); + else + b |= TMP_REG3; + } + else if (reg_lmap[b & REG_MASK] == 4) + b |= TO_OFFS_REG(SLJIT_SP); + } + + if ((b & REG_MASK) == SLJIT_UNUSED) + inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ + else { + if (reg_map[b & REG_MASK] >= 8) + rex |= REX_B; + + if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) { + /* Immediate operand. */ + if (immb <= 127 && immb >= -128) + inst_size += sizeof(sljit_sb); + else + inst_size += sizeof(sljit_si); + } + else if (reg_lmap[b & REG_MASK] == 5) + inst_size += sizeof(sljit_sb); + + if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) { + inst_size += 1; /* SIB byte. */ + if (reg_map[OFFS_REG(b)] >= 8) + rex |= REX_X; + } + } + } + else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8) + rex |= REX_B; + + if (a & SLJIT_IMM) { + if (flags & EX86_BIN_INS) { + if (imma <= 127 && imma >= -128) { + inst_size += 1; + flags |= EX86_BYTE_ARG; + } else + inst_size += 4; + } + else if (flags & EX86_SHIFT_INS) { + imma &= compiler->mode32 ? 0x1f : 0x3f; + if (imma != 1) { + inst_size ++; + flags |= EX86_BYTE_ARG; + } + } else if (flags & EX86_BYTE_ARG) + inst_size++; + else if (flags & EX86_HALF_ARG) + inst_size += sizeof(short); + else + inst_size += sizeof(sljit_si); + } + else { + SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); + /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ + if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8) + rex |= REX_R; + } + + if (rex) + inst_size++; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!inst); + + /* Encoding the byte. */ + INC_SIZE(inst_size); + if (flags & EX86_PREF_F2) + *inst++ = 0xf2; + if (flags & EX86_PREF_F3) + *inst++ = 0xf3; + if (flags & EX86_PREF_66) + *inst++ = 0x66; + if (rex) + *inst++ = rex; + buf_ptr = inst + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + + if ((a & SLJIT_IMM) || (a == 0)) + *buf_ptr = 0; + else if (!(flags & EX86_SSE2_OP1)) + *buf_ptr = reg_lmap[a] << 3; + else + *buf_ptr = a << 3; + } + else { + if (a & SLJIT_IMM) { + if (imma == 1) + *inst = GROUP_SHIFT_1; + else + *inst = GROUP_SHIFT_N; + } else + *inst = GROUP_SHIFT_CL; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) + *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b); + else if ((b & REG_MASK) != SLJIT_UNUSED) { + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) { + if (immb != 0 || reg_lmap[b & REG_MASK] == 5) { + if (immb <= 127 && immb >= -128) + *buf_ptr |= 0x40; + else + *buf_ptr |= 0x80; + } + + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) + *buf_ptr++ |= reg_lmap[b & REG_MASK]; + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3); + } + + if (immb != 0 || reg_lmap[b & REG_MASK] == 5) { + if (immb <= 127 && immb >= -128) + *buf_ptr++ = immb; /* 8 bit displacement. */ + else { + *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_si); + } + } + } + else { + if (reg_lmap[b & REG_MASK] == 5) + *buf_ptr |= 0x40; + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6); + if (reg_lmap[b & REG_MASK] == 5) + *buf_ptr++ = 0; + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = 0x25; + *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_si); + } + + if (a & SLJIT_IMM) { + if (flags & EX86_BYTE_ARG) + *buf_ptr = imma; + else if (flags & EX86_HALF_ARG) + *(short*)buf_ptr = imma; + else if (!(flags & EX86_SHIFT_INS)) + *(sljit_si*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + +#ifndef _WIN64 + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!inst); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2]; + } + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0]; +#else + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!inst); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2]; + } + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0]; +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + dst = TMP_REG1; + + if (FAST_IS_REG(dst)) { + if (reg_map[dst] < 8) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; + } + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = REX_B; + POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; + } + + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = POP_rm; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + + if (FAST_IS_REG(src)) { + if (reg_map[src] < 8) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1 + 1); + PUSH_REG(reg_lmap[src]); + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + FAIL_IF(!inst); + + INC_SIZE(2 + 1); + *inst++ = REX_B; + PUSH_REG(reg_lmap[src]); + } + } + else if (src & SLJIT_MEM) { + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= PUSH_rm; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + } + else { + SLJIT_ASSERT(IS_HALFWORD(srcw)); + /* SLJIT_IMM. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!inst); + + INC_SIZE(5 + 1); + *inst++ = PUSH_i32; + *(sljit_si*)inst = srcw; + inst += sizeof(sljit_si); + } + + RET(); + return SLJIT_SUCCESS; +} + + +/* --------------------------------------------------------------------- */ +/* Extend input */ +/* --------------------------------------------------------------------- */ + +static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; + + compiler->mode32 = 0; + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (FAST_IS_REG(dst)) { + if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + return emit_load_imm64(compiler, dst, srcw); + } + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + compiler->mode32 = 0; + return SLJIT_SUCCESS; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) + dst_r = src; + else { + if (sign) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = MOVSXD_r_rm; + } else { + compiler->mode32 = 1; + FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); + compiler->mode32 = 0; + } + } + + if (dst & SLJIT_MEM) { + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + compiler->mode32 = 0; + } + + return SLJIT_SUCCESS; +} diff --git a/pcre2/src/sljit/sljitNativeX86_common.c b/pcre2/src/sljit/sljitNativeX86_common.c new file mode 100644 index 000000000..416c15afa --- /dev/null +++ b/pcre2/src/sljit/sljitNativeX86_common.c @@ -0,0 +1,3004 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ + return "x86" SLJIT_CPUINFO; +} + +/* + 32b register indexes: + 0 - EAX + 1 - ECX + 2 - EDX + 3 - EBX + 4 - none + 5 - EBP + 6 - ESI + 7 - EDI +*/ + +/* + 64b register indexes: + 0 - RAX + 1 - RCX + 2 - RDX + 3 - RBX + 4 - none + 5 - RBP + 6 - RSI + 7 - RDI + 8 - R8 - From now on REX prefix is required + 9 - R9 + 10 - R10 + 11 - R11 + 12 - R12 + 13 - R13 + 14 - R14 + 15 - R15 +*/ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { + 0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5 +}; + +#define CHECK_EXTRA_REGS(p, w, do) \ + if (p >= SLJIT_R3 && p <= SLJIT_R6) { \ + w = SLJIT_LOCALS_OFFSET + ((p) - (SLJIT_R3 + 4)) * sizeof(sljit_sw); \ + p = SLJIT_MEM1(SLJIT_SP); \ + do; \ + } + +#else /* SLJIT_CONFIG_X86_32 */ + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) +#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) + +/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present + Note: avoid to use r12 and r13 for memory addessing + therefore r12 is better for SAVED_EREG than SAVED_REG. */ +#ifndef _WIN64 +/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9 +}; +/* low-map. reg_map & 0x7. */ +static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1 +}; +#else +/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9 +}; +/* low-map. reg_map & 0x7. */ +static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1 +}; +#endif + +#define REX_W 0x48 +#define REX_R 0x44 +#define REX_X 0x42 +#define REX_B 0x41 +#define REX 0x40 + +#ifndef _WIN64 +#define HALFWORD_MAX 0x7fffffffl +#define HALFWORD_MIN -0x80000000l +#else +#define HALFWORD_MAX 0x7fffffffll +#define HALFWORD_MIN -0x80000000ll +#endif + +#define IS_HALFWORD(x) ((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN) +#define NOT_HALFWORD(x) ((x) > HALFWORD_MAX || (x) < HALFWORD_MIN) + +#define CHECK_EXTRA_REGS(p, w, do) + +#endif /* SLJIT_CONFIG_X86_32 */ + +#define TMP_FREG (0) + +/* Size flags for emit_x86_instruction: */ +#define EX86_BIN_INS 0x0010 +#define EX86_SHIFT_INS 0x0020 +#define EX86_REX 0x0040 +#define EX86_NO_REXW 0x0080 +#define EX86_BYTE_ARG 0x0100 +#define EX86_HALF_ARG 0x0200 +#define EX86_PREF_66 0x0400 +#define EX86_PREF_F2 0x0800 +#define EX86_PREF_F3 0x1000 +#define EX86_SSE2_OP1 0x2000 +#define EX86_SSE2_OP2 0x4000 +#define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define ADD (/* BINARY */ 0 << 3) +#define ADD_EAX_i32 0x05 +#define ADD_r_rm 0x03 +#define ADD_rm_r 0x01 +#define ADDSD_x_xm 0x58 +#define ADC (/* BINARY */ 2 << 3) +#define ADC_EAX_i32 0x15 +#define ADC_r_rm 0x13 +#define ADC_rm_r 0x11 +#define AND (/* BINARY */ 4 << 3) +#define AND_EAX_i32 0x25 +#define AND_r_rm 0x23 +#define AND_rm_r 0x21 +#define ANDPD_x_xm 0x54 +#define BSR_r_rm (/* GROUP_0F */ 0xbd) +#define CALL_i32 0xe8 +#define CALL_rm (/* GROUP_FF */ 2 << 3) +#define CDQ 0x99 +#define CMOVNE_r_rm (/* GROUP_0F */ 0x45) +#define CMP (/* BINARY */ 7 << 3) +#define CMP_EAX_i32 0x3d +#define CMP_r_rm 0x3b +#define CMP_rm_r 0x39 +#define CVTPD2PS_x_xm 0x5a +#define CVTSI2SD_x_rm 0x2a +#define CVTTSD2SI_r_xm 0x2c +#define DIV (/* GROUP_F7 */ 6 << 3) +#define DIVSD_x_xm 0x5e +#define INT3 0xcc +#define IDIV (/* GROUP_F7 */ 7 << 3) +#define IMUL (/* GROUP_F7 */ 5 << 3) +#define IMUL_r_rm (/* GROUP_0F */ 0xaf) +#define IMUL_r_rm_i8 0x6b +#define IMUL_r_rm_i32 0x69 +#define JE_i8 0x74 +#define JNE_i8 0x75 +#define JMP_i8 0xeb +#define JMP_i32 0xe9 +#define JMP_rm (/* GROUP_FF */ 4 << 3) +#define LEA_r_m 0x8d +#define MOV_r_rm 0x8b +#define MOV_r_i32 0xb8 +#define MOV_rm_r 0x89 +#define MOV_rm_i32 0xc7 +#define MOV_rm8_i8 0xc6 +#define MOV_rm8_r8 0x88 +#define MOVSD_x_xm 0x10 +#define MOVSD_xm_x 0x11 +#define MOVSXD_r_rm 0x63 +#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) +#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) +#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) +#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) +#define MUL (/* GROUP_F7 */ 4 << 3) +#define MULSD_x_xm 0x59 +#define NEG_rm (/* GROUP_F7 */ 3 << 3) +#define NOP 0x90 +#define NOT_rm (/* GROUP_F7 */ 2 << 3) +#define OR (/* BINARY */ 1 << 3) +#define OR_r_rm 0x0b +#define OR_EAX_i32 0x0d +#define OR_rm_r 0x09 +#define OR_rm8_r8 0x08 +#define POP_r 0x58 +#define POP_rm 0x8f +#define POPF 0x9d +#define PUSH_i32 0x68 +#define PUSH_r 0x50 +#define PUSH_rm (/* GROUP_FF */ 6 << 3) +#define PUSHF 0x9c +#define RET_near 0xc3 +#define RET_i16 0xc2 +#define SBB (/* BINARY */ 3 << 3) +#define SBB_EAX_i32 0x1d +#define SBB_r_rm 0x1b +#define SBB_rm_r 0x19 +#define SAR (/* SHIFT */ 7 << 3) +#define SHL (/* SHIFT */ 4 << 3) +#define SHR (/* SHIFT */ 5 << 3) +#define SUB (/* BINARY */ 5 << 3) +#define SUB_EAX_i32 0x2d +#define SUB_r_rm 0x2b +#define SUB_rm_r 0x29 +#define SUBSD_x_xm 0x5c +#define TEST_EAX_i32 0xa9 +#define TEST_rm_r 0x85 +#define UCOMISD_x_xm 0x2e +#define UNPCKLPD_x_xm 0x14 +#define XCHG_EAX_r 0x90 +#define XCHG_r_rm 0x87 +#define XOR (/* BINARY */ 6 << 3) +#define XOR_EAX_i32 0x35 +#define XOR_r_rm 0x33 +#define XOR_rm_r 0x31 +#define XORPD_x_xm 0x57 + +#define GROUP_0F 0x0f +#define GROUP_F7 0xf7 +#define GROUP_FF 0xff +#define GROUP_BINARY_81 0x81 +#define GROUP_BINARY_83 0x83 +#define GROUP_SHIFT_1 0xd1 +#define GROUP_SHIFT_N 0xc1 +#define GROUP_SHIFT_CL 0xd3 + +#define MOD_REG 0xc0 +#define MOD_DISP8 0x40 + +#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s)) + +#define PUSH_REG(r) (*inst++ = (PUSH_r + (r))) +#define POP_REG(r) (*inst++ = (POP_r + (r))) +#define RET() (*inst++ = (RET_near)) +#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0) +/* r32, r/m32 */ +#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm)) + +/* Multithreading does not affect these static variables, since they store + built-in CPU features. Therefore they can be overwritten by different threads + if they detect the CPU features in the same time. */ +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) +static sljit_si cpu_has_sse2 = -1; +#endif +static sljit_si cpu_has_cmov = -1; + +#ifdef _WIN32_WCE +#include +#elif defined(_MSC_VER) && _MSC_VER >= 1400 +#include +#endif + +static void get_cpu_features(void) +{ + sljit_ui features; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + int CPUInfo[4]; + __cpuid(CPUInfo, 1); + features = (sljit_ui)CPUInfo[3]; + +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) + + /* AT&T syntax. */ + __asm__ ( + "movl $0x1, %%eax\n" +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + /* On x86-32, there is no red zone, so this + should work (no need for a local variable). */ + "push %%ebx\n" +#endif + "cpuid\n" +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + "pop %%ebx\n" +#endif + "movl %%edx, %0\n" + : "=g" (features) + : +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + : "%eax", "%ecx", "%edx" +#else + : "%rax", "%rbx", "%rcx", "%rdx" +#endif + ); + +#else /* _MSC_VER && _MSC_VER >= 1400 */ + + /* Intel syntax. */ + __asm { + mov eax, 1 + cpuid + mov features, edx + } + +#endif /* _MSC_VER && _MSC_VER >= 1400 */ + +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + cpu_has_sse2 = (features >> 26) & 0x1; +#endif + cpu_has_cmov = (features >> 15) & 0x1; +} + +static sljit_ub get_jump_code(sljit_si type) +{ + switch (type) { + case SLJIT_EQUAL: + case SLJIT_D_EQUAL: + return 0x84 /* je */; + + case SLJIT_NOT_EQUAL: + case SLJIT_D_NOT_EQUAL: + return 0x85 /* jne */; + + case SLJIT_LESS: + case SLJIT_D_LESS: + return 0x82 /* jc */; + + case SLJIT_GREATER_EQUAL: + case SLJIT_D_GREATER_EQUAL: + return 0x83 /* jae */; + + case SLJIT_GREATER: + case SLJIT_D_GREATER: + return 0x87 /* jnbe */; + + case SLJIT_LESS_EQUAL: + case SLJIT_D_LESS_EQUAL: + return 0x86 /* jbe */; + + case SLJIT_SIG_LESS: + return 0x8c /* jl */; + + case SLJIT_SIG_GREATER_EQUAL: + return 0x8d /* jnl */; + + case SLJIT_SIG_GREATER: + return 0x8f /* jnle */; + + case SLJIT_SIG_LESS_EQUAL: + return 0x8e /* jle */; + + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + return 0x80 /* jo */; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + return 0x81 /* jno */; + + case SLJIT_D_UNORDERED: + return 0x8a /* jp */; + + case SLJIT_D_ORDERED: + return 0x8b /* jpo */; + } + return 0; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); +#endif + +static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) +{ + sljit_si short_jump; + sljit_uw label_addr; + + if (jump->flags & JUMP_LABEL) + label_addr = (sljit_uw)(code + jump->u.label->size); + else + label_addr = jump->u.target; + short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) + return generate_far_jump_code(jump, code_ptr, type); +#endif + + if (type == SLJIT_JUMP) { + if (short_jump) + *code_ptr++ = JMP_i8; + else + *code_ptr++ = JMP_i32; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + short_jump = 0; + *code_ptr++ = CALL_i32; + jump->addr++; + } + else if (short_jump) { + *code_ptr++ = get_jump_code(type) - 0x10; + jump->addr++; + } + else { + *code_ptr++ = GROUP_0F; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (short_jump) { + jump->flags |= PATCH_MB; + code_ptr += sizeof(sljit_sb); + } else { + jump->flags |= PATCH_MW; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code_ptr += sizeof(sljit_sw); +#else + code_ptr += sizeof(sljit_si); +#endif + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ub *code; + sljit_ub *code_ptr; + sljit_ub *buf_ptr; + sljit_ub *buf_end; + sljit_ub len; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + /* Second code generation pass. */ + code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = buf->memory; + buf_end = buf_ptr + buf->used_size; + do { + len = *buf_ptr++; + if (len > 0) { + /* The code is already generated. */ + SLJIT_MEMMOVE(code_ptr, buf_ptr, len); + code_ptr += len; + buf_ptr += len; + } + else { + if (*buf_ptr >= 4) { + jump->addr = (sljit_uw)code_ptr; + if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) + code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4); + else + code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4); + jump = jump->next; + } + else if (*buf_ptr == 0) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + else if (*buf_ptr == 1) { + const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw); + const_ = const_->next; + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32; + buf_ptr++; + *(sljit_sw*)code_ptr = *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)); + code_ptr += sizeof(sljit_sw); + buf_ptr += sizeof(sljit_sw) - 1; +#else + code_ptr = generate_fixed_jump(code_ptr, *(sljit_sw*)(buf_ptr + 1), *buf_ptr); + buf_ptr += sizeof(sljit_sw); +#endif + } + buf_ptr++; + } + } while (buf_ptr < buf_end); + SLJIT_ASSERT(buf_ptr == buf_end); + buf = buf->next; + } while (buf); + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + + jump = compiler->jumps; + while (jump) { + if (jump->flags & PATCH_MB) { + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); + *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); + } else if (jump->flags & PATCH_MW) { + if (jump->flags & JUMP_LABEL) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); +#else + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); + *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); +#endif + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); +#else + SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); + *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); +#endif + } + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + else if (jump->flags & PATCH_MD) + *(sljit_sw*)jump->addr = jump->u.label->addr; +#endif + + jump = jump->next; + } + + /* Maybe we waste some space because of short jumps. */ + SLJIT_ASSERT(code_ptr <= code + compiler->size); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = code_ptr - code; + return (void*)code; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +static sljit_si emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +static sljit_si emit_mov(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw); + +static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) +{ + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!inst); + INC_SIZE(6); + *inst++ = REX_W; +#endif + *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ + *inst++ = 0x64; + *inst++ = 0x24; + *inst++ = (sljit_ub)sizeof(sljit_sw); + *inst++ = PUSHF; + compiler->flags_saved = 1; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) +{ + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = POPF; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!inst); + INC_SIZE(6); + *inst++ = POPF; + *inst++ = REX_W; +#endif + *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ + *inst++ = 0x64; + *inst++ = 0x24; + *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); + compiler->flags_saved = keep_flags; + return SLJIT_SUCCESS; +} + +#ifdef _WIN32 +#include + +static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) +{ + /* Workaround for calling the internal _chkstk() function on Windows. + This function touches all 4k pages belongs to the requested stack space, + which size is passed in local_size. This is necessary on Windows where + the stack can only grow in 4k steps. However, this function just burn + CPU cycles if the stack is large enough. However, you don't know it in + advance, so it must always be called. I think this is a bad design in + general even if it has some reasons. */ + *(volatile sljit_si*)alloca(local_size) = 0; +} + +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#include "sljitNativeX86_32.c" +#else +#include "sljitNativeX86_64.c" +#endif + +static sljit_si emit_mov(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + /* No destination, doesn't need to setup flags. */ + if (src & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + } + return SLJIT_SUCCESS; + } + if (FAST_IS_REG(src)) { + inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; + } + if (src & SLJIT_IMM) { + if (FAST_IS_REG(dst)) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); +#else + if (!compiler->mode32) { + if (NOT_HALFWORD(srcw)) + return emit_load_imm64(compiler, dst, srcw); + } + else + return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw); +#endif + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (!compiler->mode32 && NOT_HALFWORD(srcw)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; + } +#endif + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + if (FAST_IS_REG(dst)) { + inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + return SLJIT_SUCCESS; + } + + /* Memory to memory move. Requires two instruction. */ + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; +} + +#define EMIT_MOV(compiler, dst, dstw, src, srcw) \ + FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + sljit_ub *inst; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si size; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + switch (GET_OPCODE(op)) { + case SLJIT_BREAKPOINT: + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = INT3; + break; + case SLJIT_NOP: + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = NOP; + break; + case SLJIT_LUMUL: + case SLJIT_LSMUL: + case SLJIT_UDIVMOD: + case SLJIT_SDIVMOD: + case SLJIT_UDIVI: + case SLJIT_SDIVI: + compiler->flags_saved = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#ifdef _WIN64 + SLJIT_COMPILE_ASSERT( + reg_map[SLJIT_R0] == 0 + && reg_map[SLJIT_R1] == 2 + && reg_map[TMP_REG1] > 7, + invalid_register_assignment_for_div_mul); +#else + SLJIT_COMPILE_ASSERT( + reg_map[SLJIT_R0] == 0 + && reg_map[SLJIT_R1] < 7 + && reg_map[TMP_REG1] == 2, + invalid_register_assignment_for_div_mul); +#endif + compiler->mode32 = op & SLJIT_INT_OP; +#endif + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + + op = GET_OPCODE(op); + if ((op | 0x2) == SLJIT_UDIVI) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); + inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0); +#else + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); +#endif + FAIL_IF(!inst); + *inst = XOR_r_rm; + } + + if ((op | 0x2) == SLJIT_SDIVI) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = CDQ; +#else + if (compiler->mode32) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = CDQ; + } else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = REX_W; + *inst = CDQ; + } +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = GROUP_F7; + *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); +#else +#ifdef _WIN64 + size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2; +#else + size = (!compiler->mode32) ? 3 : 2; +#endif + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); +#ifdef _WIN64 + if (!compiler->mode32) + *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0); + else if (op >= SLJIT_UDIVMOD) + *inst++ = REX_B; + *inst++ = GROUP_F7; + *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); +#else + if (!compiler->mode32) + *inst++ = REX_W; + *inst++ = GROUP_F7; + *inst = MOD_REG | reg_map[SLJIT_R1]; +#endif +#endif + switch (op) { + case SLJIT_LUMUL: + *inst |= MUL; + break; + case SLJIT_LSMUL: + *inst |= IMUL; + break; + case SLJIT_UDIVMOD: + case SLJIT_UDIVI: + *inst |= DIV; + break; + case SLJIT_SDIVMOD: + case SLJIT_SDIVI: + *inst |= IDIV; + break; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) + if (op <= SLJIT_SDIVMOD) + EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); +#else + if (op >= SLJIT_UDIVI) + EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); +#endif + break; + } + + return SLJIT_SUCCESS; +} + +#define ENCODE_PREFIX(prefix) \ + do { \ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + FAIL_IF(!inst); \ + INC_SIZE(1); \ + *inst = (prefix); \ + } while (0) + +static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si work_r; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (FAST_IS_REG(dst)) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; +#endif + } + inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_i8; + return SLJIT_SUCCESS; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (reg_map[src] >= 4) { + SLJIT_ASSERT(dst_r == TMP_REG1); + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + } else + dst_r = src; +#else + dst_r = src; +#endif + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else if (FAST_IS_REG(src) && reg_map[src] >= 4) { + /* src, dst are registers. */ + SLJIT_ASSERT(SLOW_IS_REG(dst)); + if (reg_map[dst] < 4) { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + } + else { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + if (sign) { + /* shl reg, 24 */ + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!inst); + *inst |= SHL; + /* sar reg, 24 */ + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!inst); + *inst |= SAR; + } + else { + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); + FAIL_IF(!inst); + *(inst + 1) |= AND; + } + } + return SLJIT_SUCCESS; + } +#endif + else { + /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + } + + if (dst & SLJIT_MEM) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_r == TMP_REG1) { + /* Find a non-used register, whose reg_map[src] < 4. */ + if ((dst & REG_MASK) == SLJIT_R0) { + if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1)) + work_r = SLJIT_R2; + else + work_r = SLJIT_R1; + } + else { + if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) + work_r = SLJIT_R0; + else if ((dst & REG_MASK) == SLJIT_R1) + work_r = SLJIT_R2; + else + work_r = SLJIT_R1; + } + + if (work_r == SLJIT_R0) { + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); + } + else { + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } + + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; + + if (work_r == SLJIT_R0) { + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); + } + else { + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } + } + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; + } +#else + inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; +#endif + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (FAST_IS_REG(dst)) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; +#endif + } + inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) + dst_r = src; + else { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; + } + + if (dst & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + if (dst == src && dstw == srcw) { + /* Same input and output */ + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + if (FAST_IS_REG(dst)) { + EMIT_MOV(compiler, dst, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + return SLJIT_SUCCESS; +} + +static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + return SLJIT_SUCCESS; + } + if (FAST_IS_REG(dst)) { + EMIT_MOV(compiler, dst, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + return SLJIT_SUCCESS; +} + +static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; + + SLJIT_UNUSED_ARG(op_flags); + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + /* Just set the zero flag. */ + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0); +#else + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REG1, 0); +#endif + FAIL_IF(!inst); + *inst |= SHR; + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; + srcw = 0; + } + + inst = emit_x86_instruction(compiler, 2, TMP_REG1, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = BSR_r_rm; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (FAST_IS_REG(dst)) + dst_r = dst; + else { + /* Find an unused temporary register. */ + if ((dst & REG_MASK) != SLJIT_R0 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) + dst_r = SLJIT_R0; + else if ((dst & REG_MASK) != SLJIT_R1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R1)) + dst_r = SLJIT_R1; + else + dst_r = SLJIT_R2; + EMIT_MOV(compiler, dst, dstw, dst_r, 0); + } + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); +#else + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + compiler->mode32 = 0; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op_flags & SLJIT_INT_OP; +#endif + + if (cpu_has_cmov == -1) + get_cpu_features(); + + if (cpu_has_cmov) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = CMOVNE_r_rm; + } else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + *inst++ = JE_i8; + *inst++ = 2; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1]; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + + *inst++ = JE_i8; + *inst++ = 3; + *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REG1] >= 8 ? REX_B : 0); + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REG1]; +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); +#else + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); +#endif + FAIL_IF(!inst); + *(inst + 1) |= XOR; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } +#else + if (dst & SLJIT_MEM) + EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0); +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si update = 0; + sljit_si op_flags = GET_ALL_FLAGS(op); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si dst_is_ereg = 0; + sljit_si src_is_ereg = 0; +#else +# define src_is_ereg 0 +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); + CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op_flags & SLJIT_INT_OP; +#endif + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (op_flags & SLJIT_INT_OP) { + if (FAST_IS_REG(src) && src == dst) { + if (!TYPE_CAST_NEEDED(op)) + return SLJIT_SUCCESS; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) + op = SLJIT_MOV_UI; + if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) + op = SLJIT_MOVU_UI; + if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) + op = SLJIT_MOV_SI; + if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) + op = SLJIT_MOVU_SI; +#endif + } + + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset); + if (op >= SLJIT_MOVU) { + update = 1; + op -= 8; + } + + if (src & SLJIT_IMM) { + switch (op) { + case SLJIT_MOV_UB: + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + srcw = (sljit_sh)srcw; + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case SLJIT_MOV_UI: + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOV_SI: + srcw = (sljit_si)srcw; + break; +#endif + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg)) + return emit_mov(compiler, dst, dstw, src, srcw); +#endif + } + + if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK) && (srcw != 0 || (src & OFFS_REG_MASK) != 0)) { + inst = emit_x86_instruction(compiler, 1, src & REG_MASK, 0, src, srcw); + FAIL_IF(!inst); + *inst = LEA_r_m; + src &= SLJIT_MEM | 0xf; + srcw = 0; + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { + SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); + dst = TMP_REG1; + } +#endif + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: +#endif + FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_UB: + FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_SB: + FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_UH: + FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_SH: + FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw)); + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case SLJIT_MOV_UI: + FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_SI: + FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw)); + break; +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1) + return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0); +#endif + + if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) { + inst = emit_x86_instruction(compiler, 1, dst & REG_MASK, 0, dst, dstw); + FAIL_IF(!inst); + *inst = LEA_r_m; + } + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(GET_FLAGS(op_flags))) + compiler->flags_saved = 0; + + switch (op) { + case SLJIT_NOT: + if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E)) + return emit_not_with_flags(compiler, dst, dstw, src, srcw); + return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); + + case SLJIT_NEG: + if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw); + + case SLJIT_CLZ: + if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_clz(compiler, op_flags, dst, dstw, src, srcw); + } + + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +# undef src_is_ereg +#endif +} + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ + if (IS_HALFWORD(immw) || compiler->mode32) { \ + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!inst); \ + *(inst + 1) |= (op_imm); \ + } \ + else { \ + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ + FAIL_IF(!inst); \ + *inst = (op_mr); \ + } + +#define BINARY_EAX_IMM(op_eax_imm, immw) \ + FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw)) + +#else + +#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!inst); \ + *(inst + 1) |= (op_imm); + +#define BINARY_EAX_IMM(op_eax_imm, immw) \ + FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw)) + +#endif + +static sljit_si emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + return SLJIT_SUCCESS; + } + + if (dst == src1 && dstw == src1w) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src2w); + } + else { + BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); + } + } + else if (FAST_IS_REG(dst)) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (FAST_IS_REG(src2)) { + /* Special exception for sljit_emit_op_flags. */ + inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + return SLJIT_SUCCESS; + } + + /* Only for cumulative operations. */ + if (dst == src2 && dstw == src2w) { + if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src1w); + } + else { + BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); + } + } + else if (FAST_IS_REG(dst)) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (FAST_IS_REG(src1)) { + inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if (FAST_IS_REG(dst)) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + } + else { + /* This version requires less memory writing. */ + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + return SLJIT_SUCCESS; + } + + if (dst == src1 && dstw == src1w) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src2w); + } + else { + BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); + } + } + else if (FAST_IS_REG(dst)) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (FAST_IS_REG(src2)) { + inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if (FAST_IS_REG(dst) && dst != src2) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + } + else { + /* This version requires less memory writing. */ + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_mul(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + sljit_si dst_r; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + /* Register destination. */ + if (dst_r == src1 && !(src2 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + else if (src1 & SLJIT_IMM) { + if (src2 & SLJIT_IMM) { + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); + src2 = dst_r; + src2w = 0; + } + + if (src1w <= 127 && src1w >= -128) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i8; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = (sljit_sb)src1w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_sw*)inst = src1w; + } +#else + else if (IS_HALFWORD(src1w)) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_si*)inst = (sljit_si)src1w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); + if (dst_r != src2) + EMIT_MOV(compiler, dst_r, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } +#endif + } + else if (src2 & SLJIT_IMM) { + /* Note: src1 is NOT immediate. */ + + if (src2w <= 127 && src2w >= -128) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i8; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = (sljit_sb)src2w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_sw*)inst = src2w; + } +#else + else if (IS_HALFWORD(src2w)) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_si*)inst = (sljit_si)src2w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w); + if (dst_r != src1) + EMIT_MOV(compiler, dst_r, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } +#endif + } + else { + /* Neither argument is immediate. */ + if (ADDRESSING_DEPENDS_ON(src2, dst_r)) + dst_r = TMP_REG1; + EMIT_MOV(compiler, dst_r, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + + if (dst_r == TMP_REG1) + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + + return SLJIT_SUCCESS; +} + +static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + sljit_si dst_r, done = 0; + + /* These cases better be left to handled by normal way. */ + if (!keep_flags) { + if (dst == src1 && dstw == src1w) + return SLJIT_ERR_UNSUPPORTED; + if (dst == src2 && dstw == src2w) + return SLJIT_ERR_UNSUPPORTED; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (FAST_IS_REG(src1)) { + if (FAST_IS_REG(src2)) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); + FAIL_IF(!inst); + *inst = LEA_r_m; + done = 1; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); +#else + if (src2 & SLJIT_IMM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); +#endif + FAIL_IF(!inst); + *inst = LEA_r_m; + done = 1; + } + } + else if (FAST_IS_REG(src2)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); +#else + if (src1 & SLJIT_IMM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); +#endif + FAIL_IF(!inst); + *inst = LEA_r_m; + done = 1; + } + } + + if (done) { + if (dst_r == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + return SLJIT_SUCCESS; + } + return SLJIT_ERR_UNSUPPORTED; +} + +static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(CMP_EAX_i32, src2w); + return SLJIT_SUCCESS; + } + + if (FAST_IS_REG(src1)) { + if (src2 & SLJIT_IMM) { + BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = CMP_r_rm; + } + return SLJIT_SUCCESS; + } + + if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!inst); + *inst = CMP_rm_r; + return SLJIT_SUCCESS; + } + + if (src2 & SLJIT_IMM) { + if (src1 & SLJIT_IMM) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = TMP_REG1; + src1w = 0; + } + BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w); + } + else { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = CMP_r_rm; + } + return SLJIT_SUCCESS; +} + +static sljit_si emit_test_binary(struct sljit_compiler *compiler, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(TEST_EAX_i32, src2w); + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src2 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { +#endif + BINARY_EAX_IMM(TEST_EAX_i32, src1w); + return SLJIT_SUCCESS; + } + + if (!(src1 & SLJIT_IMM)) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src2w) || compiler->mode32) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + return SLJIT_SUCCESS; + } + else if (FAST_IS_REG(src1)) { + inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + return SLJIT_SUCCESS; + } + } + + if (!(src2 & SLJIT_IMM)) { + if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src1w) || compiler->mode32) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + return SLJIT_SUCCESS; + } + else if (FAST_IS_REG(src2)) { + inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + return SLJIT_SUCCESS; + } + } + + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src2w) || compiler->mode32) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } + return SLJIT_SUCCESS; +} + +static sljit_si emit_shift(struct sljit_compiler *compiler, + sljit_ub mode, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { + if (dst == src1 && dstw == src1w) { + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + return SLJIT_SUCCESS; + } + if (FAST_IS_REG(dst)) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + return SLJIT_SUCCESS; + } + + if (dst == SLJIT_PREF_SHIFT_REG) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + } + else if (FAST_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { + if (src1 != dst) + EMIT_MOV(compiler, dst, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + } + else { + /* This case is really difficult, since ecx itself may used for + addressing, and we must ensure to work even in that case. */ + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0); +#else + /* [esp+0] contains the flags. */ + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0); +#endif + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + FAIL_IF(!inst); + *inst |= mode; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0); +#else + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw)); +#endif + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_ub mode, sljit_si set_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* The CPU does not set flags if the shift count is 0. */ + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0)) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); +#else + if ((src2w & 0x1f) != 0) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); +#endif + if (!set_flags) + return emit_mov(compiler, dst, dstw, src1, src1w); + /* OR dst, src, 0 */ + return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, + dst, dstw, src1, src1w, SLJIT_IMM, 0); + } + + if (!set_flags) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); + + if (!FAST_IS_REG(dst)) + FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); + + FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); + + if (FAST_IS_REG(dst)) + return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + CHECK_EXTRA_REGS(src1, src1w, (void)0); + CHECK_EXTRA_REGS(src2, src2w, (void)0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op & SLJIT_INT_OP; +#endif + + if (GET_OPCODE(op) >= SLJIT_MUL) { + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + if (!GET_FLAGS(op)) { + if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED) + return compiler->error; + } + else + compiler->flags_saved = 0; + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_ADDC: + if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ + FAIL_IF(emit_restore_flags(compiler, 1)); + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) + FAIL_IF(emit_save_flags(compiler)); + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SUB: + if (!GET_FLAGS(op)) { + if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) + return compiler->error; + } + else + compiler->flags_saved = 0; + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + if (dst == SLJIT_UNUSED) + return emit_cmp_binary(compiler, src1, src1w, src2, src2w); + return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SUBC: + if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ + FAIL_IF(emit_restore_flags(compiler, 1)); + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) + FAIL_IF(emit_save_flags(compiler)); + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_MUL: + return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_AND: + if (dst == SLJIT_UNUSED) + return emit_test_binary(compiler, src1, src1w, src2, src2w); + return emit_cum_binary(compiler, AND_r_rm, AND_rm_r, AND, AND_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_OR: + return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SHL: + return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_LSHR: + return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_ASHR: + return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (reg >= SLJIT_R3 && reg <= SLJIT_R6) + return -1; +#endif + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + sljit_ub *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + SLJIT_MEMMOVE(inst, instruction, size); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +/* Alignment + 2 * 16 bytes. */ +static sljit_si sse2_data[3 + (4 + 4) * 2]; +static sljit_si *sse2_buffer; + +static void init_compiler(void) +{ + sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); + /* Single precision constants. */ + sse2_buffer[0] = 0x80000000; + sse2_buffer[4] = 0x7fffffff; + /* Double precision constants. */ + sse2_buffer[8] = 0; + sse2_buffer[9] = 0x80000000; + sse2_buffer[12] = 0xffffffff; + sse2_buffer[13] = 0x7fffffff; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + if (cpu_has_sse2 == -1) + get_cpu_features(); + return cpu_has_sse2; +#else /* SLJIT_DETECT_SSE2 */ + return 1; +#endif /* SLJIT_DETECT_SSE2 */ +} + +static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +{ + sljit_ub *inst; + + inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = opcode; + return SLJIT_SUCCESS; +} + +static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +{ + sljit_ub *inst; + + inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = opcode; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, + sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) +{ + return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); +} + +static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, + sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) +{ + return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVW_FROMD) + compiler->mode32 = 0; +#endif + + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = CVTTSD2SI_r_xm; + + if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVD_FROMW) + compiler->mode32 = 0; +#endif + + if (src & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + srcw = (sljit_si)srcw; +#endif + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + src = TMP_REG1; + srcw = 0; + } + + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = CVTSI2SD_x_rm; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + compiler->flags_saved = 0; + if (!FAST_IS_REG(src1)) { + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + src1 = TMP_FREG; + } + return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), src1, src2, src2w); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + CHECK_ERROR(); + SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); + + if (GET_OPCODE(op) == SLJIT_DMOV) { + if (FAST_IS_REG(dst)) + return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); + if (FAST_IS_REG(src)) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + } + + if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) { + dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + if (FAST_IS_REG(src)) { + /* We overwrite the high bits of source. From SLJIT point of view, + this is not an issue. + Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ + FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_SINGLE_OP, src, src, 0)); + } + else { + FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_SINGLE_OP), TMP_FREG, src, srcw)); + src = TMP_FREG; + } + + FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_SINGLE_OP, dst_r, src, 0)); + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; + } + + if (SLOW_IS_REG(dst)) { + dst_r = dst; + if (dst != src) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_DNEG: + FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); + break; + + case SLJIT_DABS: + FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + if (FAST_IS_REG(dst)) { + dst_r = dst; + if (dst == src1) + ; /* Do nothing here. */ + else if (dst == src2 && (op == SLJIT_DADD || op == SLJIT_DMUL)) { + /* Swap arguments. */ + src2 = src1; + src2w = src1w; + } + else if (dst != src2) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + } + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_DADD: + FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_DSUB: + FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_DMUL: + FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_DDIV: + FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + sljit_ub *inst; + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + /* We should restore the flags before the label, + since other taken jumps has their own flags as well. */ + if (SLJIT_UNLIKELY(compiler->flags_saved)) + PTR_FAIL_IF(emit_restore_flags(compiler, 0)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!inst); + + *inst++ = 0; + *inst++ = 0; + + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + if (SLJIT_UNLIKELY(compiler->flags_saved)) { + if ((type & 0xff) <= SLJIT_JUMP) + PTR_FAIL_IF(emit_restore_flags(compiler, 0)); + compiler->flags_saved = 0; + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF_NULL(jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type >= SLJIT_CALL1) + PTR_FAIL_IF(call_with_args(compiler, type)); + + /* Worst case size. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->size += (type >= SLJIT_JUMP) ? 5 : 6; +#else + compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); +#endif + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF_NULL(inst); + + *inst++ = 0; + *inst++ = type + 4; + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (SLJIT_UNLIKELY(compiler->flags_saved)) { + if (type <= SLJIT_JUMP) + FAIL_IF(emit_restore_flags(compiler, 0)); + compiler->flags_saved = 0; + } + + if (type >= SLJIT_CALL1) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (src == SLJIT_R2) { + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; + } + if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3) + srcw += sizeof(sljit_sw); +#endif +#endif +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) + if (src == SLJIT_R2) { + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; + } +#endif + FAIL_IF(call_with_args(compiler, type)); + } + + if (src == SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF_NULL(jump); + set_jump(jump, compiler, JUMP_ADDR); + jump->u.target = srcw; + + /* Worst case size. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->size += 5; +#else + compiler->size += 10 + 3; +#endif + + inst = (sljit_ub*)ensure_buf(compiler, 2); + FAIL_IF_NULL(inst); + + *inst++ = 0; + *inst++ = type + 4; + } + else { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; +#endif + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm; + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_ub *inst; + sljit_ub cond_set = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si reg; +#else + /* CHECK_EXTRA_REGS migh overwrite these values. */ + sljit_si dst_save = dst; + sljit_sw dstw_save = dstw; +#endif + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); + SLJIT_UNUSED_ARG(srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK_EXTRA_REGS(dst, dstw, (void)0); + if (SLJIT_UNLIKELY(compiler->flags_saved)) + FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS)); + + type &= 0xff; + /* setcc = jcc + 0x10. */ + cond_set = get_jump_code(type) + 0x10; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3); + FAIL_IF(!inst); + INC_SIZE(4 + 3); + /* Set low register to conditional flag. */ + *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_lmap[TMP_REG1]; + *inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B); + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]; + return SLJIT_SUCCESS; + } + + reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + FAIL_IF(!inst); + INC_SIZE(4 + 4); + /* Set low register to conditional flag. */ + *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_lmap[reg]; + *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]; + + if (reg != TMP_REG1) + return SLJIT_SUCCESS; + + if (GET_OPCODE(op) < SLJIT_ADD) { + compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV; + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + } +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0); +#else /* SLJIT_CONFIG_X86_64 */ + if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { + if (reg_map[dst] <= 4) { + /* Low byte is accessible. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!inst); + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_map[dst]; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst]; + return SLJIT_SUCCESS; + } + + /* Low byte is not accessible. */ + if (cpu_has_cmov == -1) + get_cpu_features(); + + if (cpu_has_cmov) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); + /* a xor reg, reg operation would overwrite the flags. */ + EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + *inst++ = GROUP_0F; + /* cmovcc = setcc - 0x50. */ + *inst++ = cond_set - 0x50; + *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]; + return SLJIT_SUCCESS; + } + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 3 + 1); + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + /* Set al to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + return SLJIT_SUCCESS; + } + + if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax); + if (dst != SLJIT_R0) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 2 + 1); + /* Set low register to conditional flag. */ + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); + FAIL_IF(!inst); + INC_SIZE(2 + 3 + 2 + 2); + /* Set low register to conditional flag. */ + *inst++ = XCHG_r_rm; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 1 /* ecx */; + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */; + *inst++ = XCHG_r_rm; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; + } + return SLJIT_SUCCESS; + } + + /* Set TMP_REG1 to the bit. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 3 + 1); + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + /* Set al to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; + + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + + if (GET_OPCODE(op) < SLJIT_ADD) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_64 */ +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +{ + CHECK_ERROR(); + CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (NOT_HALFWORD(offset)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset)); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED); + return compiler->error; +#else + return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0); +#endif + } +#endif + + if (offset != 0) + return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset); + return emit_mov(compiler, dst, dstw, SLJIT_SP, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + sljit_ub *inst; + struct sljit_const *const_; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si reg; +#endif + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + reg = SLOW_IS_REG(dst) ? dst : TMP_REG1; + + if (emit_load_imm64(compiler, reg, init_value)) + return NULL; +#else + if (dst == SLJIT_UNUSED) + dst = TMP_REG1; + + if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value)) + return NULL; +#endif + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!inst); + + *inst++ = 0; + *inst++ = 1; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (dst & SLJIT_MEM) + if (emit_mov(compiler, dst, dstw, TMP_REG1, 0)) + return NULL; +#endif + + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_sw*)addr = new_addr - (addr + 4); +#else + *(sljit_uw*)addr = new_addr; +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + *(sljit_sw*)addr = new_constant; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) +{ +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + if (cpu_has_sse2 == -1) + get_cpu_features(); + return cpu_has_sse2; +#else + return 1; +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void) +{ + if (cpu_has_cmov == -1) + get_cpu_features(); + return cpu_has_cmov; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_si type, + sljit_si dst_reg, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + CHECK_ERROR(); +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_x86_is_cmov_available()); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP)); + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " x86_cmov%s %s%s, ", + !(dst_reg & SLJIT_INT_OP) ? "" : ".i", + JUMP_PREFIX(type), jump_names[type & 0xff]); + sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + + ADJUST_LOCAL_OFFSET(src, srcw); + CHECK_EXTRA_REGS(src, srcw, (void)0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = dst_reg & SLJIT_INT_OP; +#endif + dst_reg &= ~SLJIT_INT_OP; + + if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; + srcw = 0; + } + + inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = get_jump_code(type & 0xff) - 0x40; + return SLJIT_SUCCESS; +} diff --git a/pcre2/src/sljit/sljitUtils.c b/pcre2/src/sljit/sljitUtils.c new file mode 100644 index 000000000..5294b5f3f --- /dev/null +++ b/pcre2/src/sljit/sljitUtils.c @@ -0,0 +1,334 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* ------------------------------------------------------------------------ */ +/* Locks */ +/* ------------------------------------------------------------------------ */ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + /* Always successful. */ +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + /* Always successful. */ +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + /* Always successful. */ +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + /* Always successful. */ +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ + +#include "windows.h" + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +static HANDLE allocator_mutex = 0; + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + /* No idea what to do if an error occures. Static mutexes should never fail... */ + if (!allocator_mutex) + allocator_mutex = CreateMutex(NULL, TRUE, NULL); + else + WaitForSingleObject(allocator_mutex, INFINITE); +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + ReleaseMutex(allocator_mutex); +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +static HANDLE global_mutex = 0; + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + /* No idea what to do if an error occures. Static mutexes should never fail... */ + if (!global_mutex) + global_mutex = CreateMutex(NULL, TRUE, NULL); + else + WaitForSingleObject(global_mutex, INFINITE); +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + ReleaseMutex(global_mutex); +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#else /* _WIN32 */ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +#include + +static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + pthread_mutex_lock(&allocator_mutex); +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + pthread_mutex_unlock(&allocator_mutex); +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +#include + +static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + pthread_mutex_lock(&global_mutex); +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + pthread_mutex_unlock(&global_mutex); +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#endif /* _WIN32 */ + +/* ------------------------------------------------------------------------ */ +/* Stack */ +/* ------------------------------------------------------------------------ */ + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +#ifdef _WIN32 +#include "windows.h" +#else +/* Provides mmap function. */ +#include +/* For detecting the page size. */ +#include + +#ifndef MAP_ANON + +#include + +/* Some old systems does not have MAP_ANON. */ +static sljit_si dev_zero = -1; + +#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + +static SLJIT_INLINE sljit_si open_dev_zero(void) +{ + dev_zero = open("/dev/zero", O_RDWR); + return dev_zero < 0; +} + +#else /* SLJIT_SINGLE_THREADED */ + +#include + +static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; + +static SLJIT_INLINE sljit_si open_dev_zero(void) +{ + pthread_mutex_lock(&dev_zero_mutex); + dev_zero = open("/dev/zero", O_RDWR); + pthread_mutex_unlock(&dev_zero_mutex); + return dev_zero < 0; +} + +#endif /* SLJIT_SINGLE_THREADED */ + +#endif + +#endif + +#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) + +/* Planning to make it even more clever in the future. */ +static sljit_sw sljit_page_align = 0; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data) +{ + struct sljit_stack *stack; + union { + void *ptr; + sljit_uw uw; + } base; +#ifdef _WIN32 + SYSTEM_INFO si; +#endif + + SLJIT_UNUSED_ARG(allocator_data); + if (limit > max_limit || limit < 1) + return NULL; + +#ifdef _WIN32 + if (!sljit_page_align) { + GetSystemInfo(&si); + sljit_page_align = si.dwPageSize - 1; + } +#else + if (!sljit_page_align) { + sljit_page_align = sysconf(_SC_PAGESIZE); + /* Should never happen. */ + if (sljit_page_align < 0) + sljit_page_align = 4096; + sljit_page_align--; + } +#endif + + /* Align limit and max_limit. */ + max_limit = (max_limit + sljit_page_align) & ~sljit_page_align; + + stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data); + if (!stack) + return NULL; + +#ifdef _WIN32 + base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE); + if (!base.ptr) { + SLJIT_FREE(stack, allocator_data); + return NULL; + } + stack->base = base.uw; + stack->limit = stack->base; + stack->max_limit = stack->base + max_limit; + if (sljit_stack_resize(stack, stack->base + limit)) { + sljit_free_stack(stack, allocator_data); + return NULL; + } +#else +#ifdef MAP_ANON + base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +#else + if (dev_zero < 0) { + if (open_dev_zero()) { + SLJIT_FREE(stack, allocator_data); + return NULL; + } + } + base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); +#endif + if (base.ptr == MAP_FAILED) { + SLJIT_FREE(stack, allocator_data); + return NULL; + } + stack->base = base.uw; + stack->limit = stack->base + limit; + stack->max_limit = stack->base + max_limit; +#endif + stack->top = stack->base; + return stack; +} + +#undef PAGE_ALIGN + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data) +{ + SLJIT_UNUSED_ARG(allocator_data); +#ifdef _WIN32 + VirtualFree((void*)stack->base, 0, MEM_RELEASE); +#else + munmap((void*)stack->base, stack->max_limit - stack->base); +#endif + SLJIT_FREE(stack, allocator_data); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) +{ + sljit_uw aligned_old_limit; + sljit_uw aligned_new_limit; + + if ((new_limit > stack->max_limit) || (new_limit < stack->base)) + return -1; +#ifdef _WIN32 + aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; + aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; + if (aligned_new_limit != aligned_old_limit) { + if (aligned_new_limit > aligned_old_limit) { + if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE)) + return -1; + } + else { + if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT)) + return -1; + } + } + stack->limit = new_limit; + return 0; +#else + if (new_limit >= stack->limit) { + stack->limit = new_limit; + return 0; + } + aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; + aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; + /* If madvise is available, we release the unnecessary space. */ +#if defined(MADV_DONTNEED) + if (aligned_new_limit < aligned_old_limit) + madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); +#elif defined(POSIX_MADV_DONTNEED) + if (aligned_new_limit < aligned_old_limit) + posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); +#endif + stack->limit = new_limit; + return 0; +#endif +} + +#endif /* SLJIT_UTIL_STACK */ + +#endif diff --git a/pcre2/test-driver b/pcre2/test-driver new file mode 100755 index 000000000..8e575b017 --- /dev/null +++ b/pcre2/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: From 6e873719fd74bb18832ddd5e3c48f5f106f5af56 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sun, 30 Oct 2016 21:25:21 -0700 Subject: [PATCH 043/112] Fix alias doc typo Fix spelling typo, and a couple small tweaks. --- doc_src/alias.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/doc_src/alias.txt b/doc_src/alias.txt index f02f9d69b..fc36fbbac 100644 --- a/doc_src/alias.txt +++ b/doc_src/alias.txt @@ -9,16 +9,14 @@ alias NAME=DEFINITION \subsection alias-description Description -`alias` is a simple wrapper for the `function` builtin, which creates a function wrapping a command. It has similar syntax to POSIX sh `alias`. For other uses, it is recommended to define a function. +`alias` is a simple wrapper for the `function` builtin, which creates a function wrapping a command. It has similar syntax to POSIX shell `alias`. For other uses, it is recommended to define a function. -`fish` marks functions that have been created by `alias` by including the command used to craete them in the function description. You can list alias-created functions by running `alias` without arguments. They must be erased using `functions -e`. +`fish` marks functions that have been created by `alias` by including the command used to create them in the function description. You can list `alias`-created functions by running `alias` without arguments. They must be erased using `functions -e`. - `NAME` is the name of the alias - `DEFINITION` is the actual command to execute. The string `$argv` will be appended. -You cannot create an alias to a function with the same name. - -Note that spaces need to be escaped in the call to alias just like in the commandline _even inside the quotes_. +You cannot create an alias to a function with the same name. Note that spaces need to be escaped in the call to `alias` just like at the command line, _even inside quoted parts_. \subsection alias-example Example From 6b41240cd20b0def8215c767618a42976877d3b7 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sun, 30 Oct 2016 21:29:48 -0700 Subject: [PATCH 044/112] Revert "Move PCRE2 to pcre2" This reverts commit f4f9ed56eee28d790c765dd23e64da1212d8e6ae. --- pcre2/.gitignore | 15 - pcre2/132html | 313 - pcre2/AUTHORS | 36 - pcre2/CMakeLists.txt | 780 - pcre2/COPYING | 5 - pcre2/ChangeLog | 758 - pcre2/CheckMan | 67 - pcre2/CleanTxt | 113 - pcre2/Detrail | 35 - pcre2/HACKING | 604 - pcre2/INSTALL | 370 - pcre2/LICENCE | 83 - pcre2/Makefile.am | 796 - pcre2/Makefile.in | 3136 --- pcre2/NEWS | 88 - pcre2/NON-AUTOTOOLS-BUILD | 392 - pcre2/PrepareRelease | 235 - pcre2/README | 843 - pcre2/RunGrepTest | 633 - pcre2/RunTest | 850 - pcre2/aclocal.m4 | 1531 -- pcre2/ar-lib | 270 - pcre2/cmake/COPYING-CMAKE-SCRIPTS | 22 - pcre2/cmake/FindEditline.cmake | 17 - .../cmake/FindPackageHandleStandardArgs.cmake | 58 - pcre2/cmake/FindReadline.cmake | 29 - pcre2/compile | 347 - pcre2/config-cmake.h.in | 48 - pcre2/config.guess | 1421 -- pcre2/config.sub | 1807 -- pcre2/configure | 18296 ---------------- pcre2/configure.ac | 927 - pcre2/depcomp | 791 - pcre2/install-sh | 501 - pcre2/libpcre2-16.pc.in | 13 - pcre2/libpcre2-32.pc.in | 13 - pcre2/libpcre2-8.pc.in | 13 - pcre2/libpcre2-posix.pc.in | 13 - pcre2/ltmain.sh | 11147 ---------- pcre2/m4/ax_pthread.m4 | 309 - pcre2/m4/libtool.m4 | 8369 ------- pcre2/m4/ltoptions.m4 | 437 - pcre2/m4/ltsugar.m4 | 124 - pcre2/m4/ltversion.m4 | 23 - pcre2/m4/lt~obsolete.m4 | 99 - pcre2/m4/pcre2_visibility.m4 | 87 - pcre2/missing | 215 - pcre2/pcre2-config.in | 121 - pcre2/perltest.sh | 297 - pcre2/src/config.h.generic | 306 - pcre2/src/config.h.in | 297 - pcre2/src/dftables.c | 214 - pcre2/src/pcre2.h.generic | 722 - pcre2/src/pcre2.h.in | 722 - pcre2/src/pcre2_auto_possess.c | 1287 -- pcre2/src/pcre2_chartables.c.dist | 198 - pcre2/src/pcre2_compile.c | 9018 -------- pcre2/src/pcre2_config.c | 217 - pcre2/src/pcre2_context.c | 391 - pcre2/src/pcre2_dfa_match.c | 3618 --- pcre2/src/pcre2_error.c | 321 - pcre2/src/pcre2_find_bracket.c | 218 - pcre2/src/pcre2_internal.h | 1944 -- pcre2/src/pcre2_intmodedep.h | 852 - pcre2/src/pcre2_jit_compile.c | 11503 ---------- pcre2/src/pcre2_jit_match.c | 189 - pcre2/src/pcre2_jit_misc.c | 227 - pcre2/src/pcre2_jit_test.c | 1735 -- pcre2/src/pcre2_maketables.c | 157 - pcre2/src/pcre2_match.c | 7243 ------ pcre2/src/pcre2_match_data.c | 147 - pcre2/src/pcre2_newline.c | 243 - pcre2/src/pcre2_ord2utf.c | 120 - pcre2/src/pcre2_pattern_info.c | 410 - pcre2/src/pcre2_printint.c | 832 - pcre2/src/pcre2_serialize.c | 258 - pcre2/src/pcre2_string_utils.c | 201 - pcre2/src/pcre2_study.c | 1575 -- pcre2/src/pcre2_substitute.c | 850 - pcre2/src/pcre2_substring.c | 536 - pcre2/src/pcre2_tables.c | 765 - pcre2/src/pcre2_ucd.c | 3747 ---- pcre2/src/pcre2_ucp.h | 268 - pcre2/src/pcre2_valid_utf.c | 398 - pcre2/src/pcre2_xclass.c | 271 - pcre2/src/pcre2demo.c | 423 - pcre2/src/pcre2grep.c | 3270 --- pcre2/src/pcre2posix.c | 335 - pcre2/src/pcre2posix.h | 146 - pcre2/src/pcre2test.c | 7426 ------- pcre2/src/sljit/sljitConfig.h | 135 - pcre2/src/sljit/sljitConfigInternal.h | 713 - pcre2/src/sljit/sljitExecAllocator.c | 312 - pcre2/src/sljit/sljitLir.c | 2029 -- pcre2/src/sljit/sljitLir.h | 1249 -- pcre2/src/sljit/sljitNativeARM_32.c | 2566 --- pcre2/src/sljit/sljitNativeARM_64.c | 2050 -- pcre2/src/sljit/sljitNativeARM_T2_32.c | 2090 -- pcre2/src/sljit/sljitNativeMIPS_32.c | 366 - pcre2/src/sljit/sljitNativeMIPS_64.c | 469 - pcre2/src/sljit/sljitNativeMIPS_common.c | 2138 -- pcre2/src/sljit/sljitNativePPC_32.c | 269 - pcre2/src/sljit/sljitNativePPC_64.c | 421 - pcre2/src/sljit/sljitNativePPC_common.c | 2375 -- pcre2/src/sljit/sljitNativeSPARC_32.c | 164 - pcre2/src/sljit/sljitNativeSPARC_common.c | 1435 -- pcre2/src/sljit/sljitNativeTILEGX-encoder.c | 10159 --------- pcre2/src/sljit/sljitNativeTILEGX_64.c | 2561 --- pcre2/src/sljit/sljitNativeX86_32.c | 550 - pcre2/src/sljit/sljitNativeX86_64.c | 747 - pcre2/src/sljit/sljitNativeX86_common.c | 3004 --- pcre2/src/sljit/sljitUtils.c | 334 - pcre2/test-driver | 148 - 113 files changed, 157381 deletions(-) delete mode 100644 pcre2/.gitignore delete mode 100755 pcre2/132html delete mode 100644 pcre2/AUTHORS delete mode 100644 pcre2/CMakeLists.txt delete mode 100644 pcre2/COPYING delete mode 100644 pcre2/ChangeLog delete mode 100755 pcre2/CheckMan delete mode 100755 pcre2/CleanTxt delete mode 100755 pcre2/Detrail delete mode 100644 pcre2/HACKING delete mode 100644 pcre2/INSTALL delete mode 100644 pcre2/LICENCE delete mode 100644 pcre2/Makefile.am delete mode 100644 pcre2/Makefile.in delete mode 100644 pcre2/NEWS delete mode 100644 pcre2/NON-AUTOTOOLS-BUILD delete mode 100755 pcre2/PrepareRelease delete mode 100644 pcre2/README delete mode 100755 pcre2/RunGrepTest delete mode 100755 pcre2/RunTest delete mode 100644 pcre2/aclocal.m4 delete mode 100755 pcre2/ar-lib delete mode 100644 pcre2/cmake/COPYING-CMAKE-SCRIPTS delete mode 100644 pcre2/cmake/FindEditline.cmake delete mode 100644 pcre2/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 pcre2/cmake/FindReadline.cmake delete mode 100755 pcre2/compile delete mode 100644 pcre2/config-cmake.h.in delete mode 100755 pcre2/config.guess delete mode 100755 pcre2/config.sub delete mode 100755 pcre2/configure delete mode 100644 pcre2/configure.ac delete mode 100755 pcre2/depcomp delete mode 100755 pcre2/install-sh delete mode 100644 pcre2/libpcre2-16.pc.in delete mode 100644 pcre2/libpcre2-32.pc.in delete mode 100644 pcre2/libpcre2-8.pc.in delete mode 100644 pcre2/libpcre2-posix.pc.in delete mode 100644 pcre2/ltmain.sh delete mode 100644 pcre2/m4/ax_pthread.m4 delete mode 100644 pcre2/m4/libtool.m4 delete mode 100644 pcre2/m4/ltoptions.m4 delete mode 100644 pcre2/m4/ltsugar.m4 delete mode 100644 pcre2/m4/ltversion.m4 delete mode 100644 pcre2/m4/lt~obsolete.m4 delete mode 100644 pcre2/m4/pcre2_visibility.m4 delete mode 100755 pcre2/missing delete mode 100644 pcre2/pcre2-config.in delete mode 100755 pcre2/perltest.sh delete mode 100644 pcre2/src/config.h.generic delete mode 100644 pcre2/src/config.h.in delete mode 100644 pcre2/src/dftables.c delete mode 100644 pcre2/src/pcre2.h.generic delete mode 100644 pcre2/src/pcre2.h.in delete mode 100644 pcre2/src/pcre2_auto_possess.c delete mode 100644 pcre2/src/pcre2_chartables.c.dist delete mode 100644 pcre2/src/pcre2_compile.c delete mode 100644 pcre2/src/pcre2_config.c delete mode 100644 pcre2/src/pcre2_context.c delete mode 100644 pcre2/src/pcre2_dfa_match.c delete mode 100644 pcre2/src/pcre2_error.c delete mode 100644 pcre2/src/pcre2_find_bracket.c delete mode 100644 pcre2/src/pcre2_internal.h delete mode 100644 pcre2/src/pcre2_intmodedep.h delete mode 100644 pcre2/src/pcre2_jit_compile.c delete mode 100644 pcre2/src/pcre2_jit_match.c delete mode 100644 pcre2/src/pcre2_jit_misc.c delete mode 100644 pcre2/src/pcre2_jit_test.c delete mode 100644 pcre2/src/pcre2_maketables.c delete mode 100644 pcre2/src/pcre2_match.c delete mode 100644 pcre2/src/pcre2_match_data.c delete mode 100644 pcre2/src/pcre2_newline.c delete mode 100644 pcre2/src/pcre2_ord2utf.c delete mode 100644 pcre2/src/pcre2_pattern_info.c delete mode 100644 pcre2/src/pcre2_printint.c delete mode 100644 pcre2/src/pcre2_serialize.c delete mode 100644 pcre2/src/pcre2_string_utils.c delete mode 100644 pcre2/src/pcre2_study.c delete mode 100644 pcre2/src/pcre2_substitute.c delete mode 100644 pcre2/src/pcre2_substring.c delete mode 100644 pcre2/src/pcre2_tables.c delete mode 100644 pcre2/src/pcre2_ucd.c delete mode 100644 pcre2/src/pcre2_ucp.h delete mode 100644 pcre2/src/pcre2_valid_utf.c delete mode 100644 pcre2/src/pcre2_xclass.c delete mode 100644 pcre2/src/pcre2demo.c delete mode 100644 pcre2/src/pcre2grep.c delete mode 100644 pcre2/src/pcre2posix.c delete mode 100644 pcre2/src/pcre2posix.h delete mode 100644 pcre2/src/pcre2test.c delete mode 100644 pcre2/src/sljit/sljitConfig.h delete mode 100644 pcre2/src/sljit/sljitConfigInternal.h delete mode 100644 pcre2/src/sljit/sljitExecAllocator.c delete mode 100644 pcre2/src/sljit/sljitLir.c delete mode 100644 pcre2/src/sljit/sljitLir.h delete mode 100644 pcre2/src/sljit/sljitNativeARM_32.c delete mode 100644 pcre2/src/sljit/sljitNativeARM_64.c delete mode 100644 pcre2/src/sljit/sljitNativeARM_T2_32.c delete mode 100644 pcre2/src/sljit/sljitNativeMIPS_32.c delete mode 100644 pcre2/src/sljit/sljitNativeMIPS_64.c delete mode 100644 pcre2/src/sljit/sljitNativeMIPS_common.c delete mode 100644 pcre2/src/sljit/sljitNativePPC_32.c delete mode 100644 pcre2/src/sljit/sljitNativePPC_64.c delete mode 100644 pcre2/src/sljit/sljitNativePPC_common.c delete mode 100644 pcre2/src/sljit/sljitNativeSPARC_32.c delete mode 100644 pcre2/src/sljit/sljitNativeSPARC_common.c delete mode 100644 pcre2/src/sljit/sljitNativeTILEGX-encoder.c delete mode 100644 pcre2/src/sljit/sljitNativeTILEGX_64.c delete mode 100644 pcre2/src/sljit/sljitNativeX86_32.c delete mode 100644 pcre2/src/sljit/sljitNativeX86_64.c delete mode 100644 pcre2/src/sljit/sljitNativeX86_common.c delete mode 100644 pcre2/src/sljit/sljitUtils.c delete mode 100755 pcre2/test-driver diff --git a/pcre2/.gitignore b/pcre2/.gitignore deleted file mode 100644 index fa91befa7..000000000 --- a/pcre2/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -!config.h.in -!configure -!doc/ -.deps -.dirstamp -.libs/ -*.la -*.lo -*.pc -libtool -pcre2_chartables.c -pcre2-config -pcre2test -pcre2.h -stamp-h1 \ No newline at end of file diff --git a/pcre2/132html b/pcre2/132html deleted file mode 100755 index 3a16a59e0..000000000 --- a/pcre2/132html +++ /dev/null @@ -1,313 +0,0 @@ -#! /usr/bin/perl -w - -# Script to turn PCRE2 man pages into HTML - - -# Subroutine to handle font changes and other escapes - -sub do_line { -my($s) = $_[0]; - -$s =~ s/ -$s =~ s/>/>/g; -$s =~ s"\\fI(.*?)\\f[RP]"$1"g; -$s =~ s"\\fB(.*?)\\f[RP]"$1"g; -$s =~ s"\\e"\\"g; -$s =~ s/(?<=Copyright )\(c\)/©/g; -$s; -} - -# Subroutine to ensure not in a paragraph - -sub end_para { -if ($inpara) - { - print TEMP "\n" if ($inpre); - print TEMP "

\n"; - } -$inpara = $inpre = 0; -$wrotetext = 0; -} - -# Subroutine to start a new paragraph - -sub new_para { -&end_para(); -print TEMP "

\n"; -$inpara = 1; -} - - -# Main program - -$innf = 0; -$inpara = 0; -$inpre = 0; -$wrotetext = 0; -$toc = 0; -$ref = 1; - -while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) - { - $toc = 1 if $ARGV[0] eq "-toc"; - shift; - } - -# Initial output to STDOUT - -print < - -$ARGV[0] specification - - -

$ARGV[0] man page

-

-Return to the PCRE2 index page. -

-

-This page is part of the PCRE2 HTML documentation. It was generated -automatically from the original man page. If there is any nonsense in it, -please consult the man page, in case the conversion went wrong. -
-End - -print "

    \n" if ($toc); - -open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n"; - -while () - { - # Handle lines beginning with a dot - - if (/^\./) - { - # Some of the PCRE2 man pages used to contain instances of .br. However, - # they should have all been removed because they cause trouble in some - # (other) automated systems that translate man pages to HTML. Complain if - # we find .br or .in (another macro that is deprecated). - - if (/^\.br/ || /^\.in/) - { - print STDERR "\n*** Deprecated macro encountered - rewrite needed\n"; - print STDERR "*** $_\n"; - die "*** Processing abandoned\n"; - } - - # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi. - - elsif (/^\.nf/) - { - $innf = 1; - } - - elsif (/^\.fi/) - { - $innf = 0; - } - - # Handling .sp is subtle. If it is inside a literal section, do nothing if - # the next line is a non literal text line; similarly, if not inside a - # literal section, do nothing if a literal follows, unless we are inside - # a .nf/.ne section. The point being that the
     and 
    that delimit - # literal sections will do the spacing. Always skip if no previous output. - - elsif (/^\.sp/) - { - if ($wrotetext) - { - $_ = ; - if ($inpre) - { - print TEMP "\n" if (/^[\s.]/); - } - else - { - print TEMP "
    \n
    \n" if ($innf || !/^[\s.]/); - } - redo; # Now process the lookahead line we just read - } - } - elsif (/^\.TP/ || /^\.PP/ || /^\.P/) - { - &new_para(); - } - elsif (/^\.SH\s*("?)(.*)\1/) - { - # Ignore the NAME section - if ($2 =~ /^NAME\b/) - { - ; - next; - } - - &end_para(); - my($title) = &do_line($2); - if ($toc) - { - printf("
  • $title\n", - $ref, $ref); - printf TEMP ("
    $title
    \n", - $ref); - $ref++; - } - else - { - print TEMP "
    \n$title\n
    \n"; - } - } - elsif (/^\.SS\s*("?)(.*)\1/) - { - &end_para(); - my($title) = &do_line($2); - print TEMP "
    \n$title\n
    \n"; - } - elsif (/^\.B\s*(.*)/) - { - &new_para() if (!$inpara); - $_ = &do_line($1); - s/"(.*?)"/$1/g; - print TEMP "$_\n"; - $wrotetext = 1; - } - elsif (/^\.I\s*(.*)/) - { - &new_para() if (!$inpara); - $_ = &do_line($1); - s/"(.*?)"/$1/g; - print TEMP "$_\n"; - $wrotetext = 1; - } - - # A comment that starts "HREF" takes the next line as a name that - # is turned into a hyperlink, using the text given, which might be - # in a special font. If it ends in () or (digits) or punctuation, they - # aren't part of the link. - - elsif (/^\.\\"\s*HREF/) - { - $_=; - chomp; - $_ = &do_line($_); - $_ =~ s/\s+$//; - $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/; - print TEMP "$_\n"; - } - - # A comment that starts "HTML" inserts literal HTML - - elsif (/^\.\\"\s*HTML\s*(.*)/) - { - print TEMP $1; - } - - # A comment that starts < inserts that HTML at the end of the - # *next* input line - so as not to get a newline between them. - - elsif (/^\.\\"\s*(<.*>)/) - { - my($markup) = $1; - $_=; - chomp; - $_ = &do_line($_); - $_ =~ s/\s+$//; - print TEMP "$_$markup\n"; - } - - # A comment that starts JOIN joins the next two lines together, with one - # space between them. Then that line is processed. This is used in some - # displays where two lines are needed for the "man" version. JOINSH works - # the same, except that it assumes this is a shell command, so removes - # continuation backslashes. - - elsif (/^\.\\"\s*JOIN(SH)?/) - { - my($one,$two); - $one = ; - $two = ; - $one =~ s/\s*\\e\s*$// if (defined($1)); - chomp($one); - $two =~ s/^\s+//; - $_ = "$one $two"; - redo; # Process the joined lines - } - - # .EX/.EE are used in the pcre2demo page to bracket the entire program, - # which is unmodified except for turning backslash into "\e". - - elsif (/^\.EX\s*$/) - { - print TEMP "
    \n";
    -      while ()
    -        {
    -        last if /^\.EE\s*$/;
    -        s/\\e/\\/g;
    -        s/&/&/g;
    -        s//>/g;
    -        print TEMP;
    -        }
    -      }
    -
    -    # Ignore anything not recognized
    -
    -    next;
    -    }
    -
    -  # Line does not begin with a dot. Replace blank lines with new paragraphs
    -
    -  if (/^\s*$/)
    -    {
    -    &end_para() if ($wrotetext);
    -    next;
    -    }
    -
    -  # Convert fonts changes and output an ordinary line. Ensure that indented
    -  # lines are marked as literal.
    -
    -  $_ = &do_line($_);
    -  &new_para() if (!$inpara);
    -
    -  if (/^\s/)
    -    {
    -    if (!$inpre)
    -      {
    -      print TEMP "
    \n";
    -      $inpre = 1;
    -      }
    -    }
    -  elsif ($inpre)
    -    {
    -    print TEMP "
    \n"; - $inpre = 0; - } - - # Add
    to the end of a non-literal line if we are within .nf/.fi - - $_ .= "
    \n" if (!$inpre && $innf); - - print TEMP; - $wrotetext = 1; - } - -# The TOC, if present, will have been written - terminate it - -print "
\n" if ($toc); - -# Copy the remainder to the standard output - -close(TEMP); -open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n"; - -print while (); - -print < -Return to the PCRE2 index page. -

-End - -close(TEMP); -unlink("/tmp/$$"); - -# End diff --git a/pcre2/AUTHORS b/pcre2/AUTHORS deleted file mode 100644 index d9a0e1569..000000000 --- a/pcre2/AUTHORS +++ /dev/null @@ -1,36 +0,0 @@ -THE MAIN PCRE2 LIBRARY CODE ---------------------------- - -Written by: Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk - -University of Cambridge Computing Service, -Cambridge, England. - -Copyright (c) 1997-2016 University of Cambridge -All rights reserved - - -PCRE2 JUST-IN-TIME COMPILATION SUPPORT --------------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2010-2016 Zoltan Herczeg -All rights reserved. - - -STACK-LESS JUST-IN-TIME COMPILER --------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2009-2016 Zoltan Herczeg -All rights reserved. - -#### diff --git a/pcre2/CMakeLists.txt b/pcre2/CMakeLists.txt deleted file mode 100644 index 2c84b054d..000000000 --- a/pcre2/CMakeLists.txt +++ /dev/null @@ -1,780 +0,0 @@ -# CMakeLists.txt -# -# -# This file enables PCRE2 to be built with the CMake configuration and build -# tool. Download CMake in source or binary form from http://www.cmake.org/ -# Converted to support PCRE2 from the original PCRE file, August 2014. -# -# Original listfile by Christian Ehrlicher -# Refined and expanded by Daniel Richard G. -# 2007-09-14 mod by Sheri so 7.4 supported configuration options can be entered -# 2007-09-19 Adjusted by PH to retain previous default settings -# 2007-12-26 (a) On UNIX, use names libpcre instead of just pcre -# (b) Ensure pcretest and pcregrep link with the local library, -# not a previously-installed one. -# (c) Add PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, and -# PCRE_SUPPORT_LIBBZ2. -# 2008-01-20 Brought up to date to include several new features by Christian -# Ehrlicher. -# 2008-01-22 Sheri added options for backward compatibility of library names -# when building with minGW: -# if "ON", NON_STANDARD_LIB_PREFIX causes shared libraries to -# be built without "lib" as prefix. (The libraries will be named -# pcre.dll, pcreposix.dll and pcrecpp.dll). -# if "ON", NON_STANDARD_LIB_SUFFIX causes shared libraries to -# be built with suffix of "-0.dll". (The libraries will be named -# libpcre-0.dll, libpcreposix-0.dll and libpcrecpp-0.dll - same names -# built by default with Configure and Make. -# 2008-01-23 PH removed the automatic build of pcredemo. -# 2008-04-22 PH modified READLINE support so it finds NCURSES when needed. -# 2008-07-03 PH updated for revised UCP property support (change of files) -# 2009-03-23 PH applied Steven Van Ingelgem's patch to change the name -# CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE -# is included within another project. -# 2009-03-23 PH applied a modified version of Steven Van Ingelgem's patches to -# add options to stop the building of pcregrep and the tests, and -# to disable the final configuration report. -# 2009-04-11 PH applied Christian Ehrlicher's patch to show compiler flags that -# are set by specifying a release type. -# 2010-01-02 PH added test for stdint.h -# 2010-03-02 PH added test for inttypes.h -# 2011-08-01 PH added PCREGREP_BUFSIZE -# 2011-08-22 PH added PCRE_SUPPORT_JIT -# 2011-09-06 PH modified WIN32 ADD_TEST line as suggested by Sergey Cherepanov -# 2011-09-06 PH added PCRE_SUPPORT_PCREGREP_JIT -# 2011-10-04 Sheri added support for including coff data in windows shared libraries -# compiled with MINGW if pcre.rc and/or pcreposix.rc are placed in -# the source dir by the user prior to building -# 2011-10-04 Sheri changed various add_test's to use exes' location built instead -# of DEBUG location only (likely only matters in MSVC) -# 2011-10-04 Sheri added scripts to provide needed variables to RunTest and -# RunGrepTest (used for UNIX and Msys) -# 2011-10-04 Sheri added scripts to provide needed variables and to execute -# RunTest.bat in Win32 (for effortless testing with "make test") -# 2011-10-04 Sheri Increased minimum required cmake version -# 2012-01-06 PH removed pcre_info.c and added pcre_string_utils.c -# 2012-01-10 Zoltan Herczeg added libpcre16 support -# 2012-01-13 Stephen Kelly added out of source build support -# 2012-01-17 PH applied Stephen Kelly's patch to parse the version data out -# of the configure.ac file -# 2012-02-26 PH added support for libedit -# 2012-09-06 PH added support for PCRE_EBCDIC_NL25 -# 2012-09-08 ChPe added PCRE32 support -# 2012-10-23 PH added support for VALGRIND and GCOV -# 2012-12-08 PH added patch from Daniel Richard G to quash some MSVC warnings -# 2013-07-01 PH realized that the "support" for GCOV was a total nonsense and -# so it has been removed. -# 2013-10-08 PH got rid of the "source" command, which is a bash-ism (use ".") -# 2013-11-05 PH added support for PARENS_NEST_LIMIT -# 2014-08-29 PH converted the file for PCRE2 (which has no C++). -# 2015-04-24 PH added support for PCRE2_DEBUG -# 2015-07-16 PH updated for new pcre2_find_bracket source module -# 2015-08-24 PH correct C_FLAGS setting (patch from Roy Ivy III) -# 2015-10=16 PH added support for never-backslash-C - -PROJECT(PCRE2 C) - -# Increased minimum to 2.8.0 to support newer add_test features. Set policy -# CMP0026 to avoid warnings for the use of LOCATION in GET_TARGET_PROPERTY. - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) -CMAKE_POLICY(SET CMP0026 OLD) - -SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${PROJECT_SOURCE_DIR}/src") - -# external packages -FIND_PACKAGE( BZip2 ) -FIND_PACKAGE( ZLIB ) -FIND_PACKAGE( Readline ) -FIND_PACKAGE( Editline ) - -# Configuration checks - -INCLUDE(CheckIncludeFile) -INCLUDE(CheckFunctionExists) -INCLUDE(CheckTypeSize) - -CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) -CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) -CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) -CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) -CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) -CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) -CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) - -CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) -CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) -CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) - -# User-configurable options -# -# Note: CMakeSetup displays these in alphabetical order, regardless of -# the order we use here. - -SET(BUILD_SHARED_LIBS OFF CACHE BOOL - "Build shared libraries instead of static ones.") - -OPTION(PCRE2_BUILD_PCRE2_8 "Build 8 bit PCRE2 library" ON) - -OPTION(PCRE2_BUILD_PCRE2_16 "Build 16 bit PCRE2 library" OFF) - -OPTION(PCRE2_BUILD_PCRE2_32 "Build 32 bit PCRE2 library" OFF) - -OPTION(PCRE2_DEBUG "Include debugging code" OFF) - -SET(PCRE2_EBCDIC OFF CACHE BOOL - "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems.)") - -SET(PCRE2_EBCDIC_NL25 OFF CACHE BOOL - "Use 0x25 as EBCDIC NL character instead of 0x15; implies EBCDIC.") - -SET(PCRE2_LINK_SIZE "2" CACHE STRING - "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") - -SET(PCRE2_PARENS_NEST_LIMIT "250" CACHE STRING - "Default nested parentheses limit. See PARENS_NEST_LIMIT in config.h.in for details.") - -SET(PCRE2_MATCH_LIMIT "10000000" CACHE STRING - "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") - -SET(PCRE2_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING - "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") - -SET(PCRE2GREP_BUFSIZE "20480" CACHE STRING - "Buffer size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.") - -SET(PCRE2_NEWLINE "LF" CACHE STRING - "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).") - -SET(PCRE2_HEAP_MATCH_RECURSE OFF CACHE BOOL - "If ON, then don't use stack recursion when matching. See HEAP_MATCH_RECURSE in config.h.in for details.") - -SET(PCRE2_SUPPORT_JIT OFF CACHE BOOL - "Enable support for Just-in-time compiling.") - -SET(PCRE2_SUPPORT_PCRE2GREP_JIT ON CACHE BOOL - "Enable use of Just-in-time compiling in pcre2grep.") - -SET(PCRE2_SUPPORT_UNICODE ON CACHE BOOL - "Enable support for Unicode and UTF-8/UTF-16/UTF-32 encoding.") - -SET(PCRE2_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL - "ON=Backslash-R matches only LF CR and CRLF, OFF=Backslash-R matches all Unicode Linebreaks") - -SET(PCRE2_NEVER_BACKSLASH_C OFF CACHE BOOL - "If ON, backslash-C (upper case C) is locked out.") - -SET(PCRE2_SUPPORT_VALGRIND OFF CACHE BOOL - "Enable Valgrind support.") - -OPTION(PCRE2_SHOW_REPORT "Show the final configuration report" ON) -OPTION(PCRE2_BUILD_PCRE2GREP "Build pcre2grep" ON) -OPTION(PCRE2_BUILD_TESTS "Build the tests" ON) - -IF (MINGW) - OPTION(NON_STANDARD_LIB_PREFIX - "ON=Shared libraries built in mingw will be named pcre2.dll, etc., instead of libpcre2.dll, etc." - OFF) - - OPTION(NON_STANDARD_LIB_SUFFIX - "ON=Shared libraries built in mingw will be named libpcre2-0.dll, etc., instead of libpcre2.dll, etc." - OFF) -ENDIF(MINGW) - -IF(MSVC) - OPTION(INSTALL_MSVC_PDB - "ON=Install .pdb files built by MSVC, if generated" - OFF) -ENDIF(MSVC) - -# bzip2 lib -IF(BZIP2_FOUND) - OPTION (PCRE2_SUPPORT_LIBBZ2 "Enable support for linking pcre2grep with libbz2." ON) -ENDIF(BZIP2_FOUND) -IF(PCRE2_SUPPORT_LIBBZ2) - INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) -ENDIF(PCRE2_SUPPORT_LIBBZ2) - -# zlib -IF(ZLIB_FOUND) - OPTION (PCRE2_SUPPORT_LIBZ "Enable support for linking pcre2grep with libz." ON) -ENDIF(ZLIB_FOUND) -IF(PCRE2_SUPPORT_LIBZ) - INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) -ENDIF(PCRE2_SUPPORT_LIBZ) - -# editline lib -IF(EDITLINE_FOUND) - OPTION (PCRE2_SUPPORT_LIBEDIT "Enable support for linking pcre2test with libedit." OFF) -ENDIF(EDITLINE_FOUND) -IF(PCRE2_SUPPORT_LIBEDIT) - INCLUDE_DIRECTORIES(${EDITLINE_INCLUDE_DIR}) -ENDIF(PCRE2_SUPPORT_LIBEDIT) - -# readline lib -IF(READLINE_FOUND) - OPTION (PCRE2_SUPPORT_LIBREADLINE "Enable support for linking pcre2test with libreadline." ON) -ENDIF(READLINE_FOUND) -IF(PCRE2_SUPPORT_LIBREADLINE) - INCLUDE_DIRECTORIES(${READLINE_INCLUDE_DIR}) -ENDIF(PCRE2_SUPPORT_LIBREADLINE) - -# Prepare build configuration - -IF(NOT BUILD_SHARED_LIBS) - SET(PCRE2_STATIC 1) -ENDIF(NOT BUILD_SHARED_LIBS) - -IF(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32) - MESSAGE(FATAL_ERROR "At least one of PCRE2_BUILD_PCRE2_8, PCRE2_BUILD_PCRE2_16 or PCRE2_BUILD_PCRE2_32 must be enabled") -ENDIF(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32) - -IF(PCRE2_BUILD_PCRE2_8) - SET(SUPPORT_PCRE2_8 1) -ENDIF(PCRE2_BUILD_PCRE2_8) - -IF(PCRE2_BUILD_PCRE2_16) - SET(SUPPORT_PCRE2_16 1) -ENDIF(PCRE2_BUILD_PCRE2_16) - -IF(PCRE2_BUILD_PCRE2_32) - SET(SUPPORT_PCRE2_32 1) -ENDIF(PCRE2_BUILD_PCRE2_32) - -IF(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8) - MESSAGE(STATUS "** PCRE2_BUILD_PCRE2_8 must be enabled for the pcre2grep program") - SET(PCRE2_BUILD_PCRE2GREP OFF) -ENDIF(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8) - -IF(PCRE2_SUPPORT_LIBREADLINE AND PCRE2_SUPPORT_LIBEDIT) - MESSAGE(FATAL_ERROR "Only one of libreadline or libeditline can be specified") -ENDIF(PCRE2_SUPPORT_LIBREADLINE AND PCRE2_SUPPORT_LIBEDIT) - -IF(PCRE2_SUPPORT_BSR_ANYCRLF) - SET(BSR_ANYCRLF 1) -ENDIF(PCRE2_SUPPORT_BSR_ANYCRLF) - -IF(PCRE2_NEVER_BACKSLASH_C) - SET(NEVER_BACKSLASH_C 1) -ENDIF(PCRE2_NEVER_BACKSLASH_C) - -IF(PCRE2_SUPPORT_UNICODE) - SET(SUPPORT_UNICODE 1) -ENDIF(PCRE2_SUPPORT_UNICODE) - -IF(PCRE2_SUPPORT_JIT) - SET(SUPPORT_JIT 1) -ENDIF(PCRE2_SUPPORT_JIT) - -IF(PCRE2_SUPPORT_PCRE2GREP_JIT) - SET(SUPPORT_PCRE2GREP_JIT 1) -ENDIF(PCRE2_SUPPORT_PCRE2GREP_JIT) - -IF(PCRE2_SUPPORT_VALGRIND) - SET(SUPPORT_VALGRIND 1) -ENDIF(PCRE2_SUPPORT_VALGRIND) - -# This next one used to reference ${READLINE_LIBRARY}) -# but I was advised to add the NCURSES test as well, along with -# some modifications to cmake/FindReadline.cmake which should -# make it possible to override the default if necessary. PH - -IF(PCRE2_SUPPORT_LIBREADLINE) - SET(SUPPORT_LIBREADLINE 1) - SET(PCRE2TEST_LIBS ${READLINE_LIBRARY} ${NCURSES_LIBRARY}) -ENDIF(PCRE2_SUPPORT_LIBREADLINE) - -# libedit is a plug-compatible alternative to libreadline - -IF(PCRE2_SUPPORT_LIBEDIT) - SET(SUPPORT_LIBEDIT 1) - SET(PCRE2TEST_LIBS ${EDITLINE_LIBRARY} ${NCURSES_LIBRARY}) -ENDIF(PCRE2_SUPPORT_LIBEDIT) - -IF(PCRE2_SUPPORT_LIBZ) - SET(SUPPORT_LIBZ 1) - SET(PCRE2GREP_LIBS ${PCRE2GREP_LIBS} ${ZLIB_LIBRARIES}) -ENDIF(PCRE2_SUPPORT_LIBZ) - -IF(PCRE2_SUPPORT_LIBBZ2) - SET(SUPPORT_LIBBZ2 1) - SET(PCRE2GREP_LIBS ${PCRE2GREP_LIBS} ${BZIP2_LIBRARIES}) -ENDIF(PCRE2_SUPPORT_LIBBZ2) - -SET(NEWLINE_DEFAULT "") - -IF(PCRE2_NEWLINE STREQUAL "CR") - SET(NEWLINE_DEFAULT "1") -ENDIF(PCRE2_NEWLINE STREQUAL "CR") -IF(PCRE2_NEWLINE STREQUAL "LF") - SET(NEWLINE_DEFAULT "2") -ENDIF(PCRE2_NEWLINE STREQUAL "LF") -IF(PCRE2_NEWLINE STREQUAL "CRLF") - SET(NEWLINE_DEFAULT "3") -ENDIF(PCRE2_NEWLINE STREQUAL "CRLF") -IF(PCRE2_NEWLINE STREQUAL "ANY") - SET(NEWLINE_DEFAULT "4") -ENDIF(PCRE2_NEWLINE STREQUAL "ANY") -IF(PCRE2_NEWLINE STREQUAL "ANYCRLF") - SET(NEWLINE_DEFAULT "5") -ENDIF(PCRE2_NEWLINE STREQUAL "ANYCRLF") - -IF(NEWLINE_DEFAULT STREQUAL "") - MESSAGE(FATAL_ERROR "The PCRE2_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") -ENDIF(NEWLINE_DEFAULT STREQUAL "") - -IF(PCRE2_EBCDIC) - SET(EBCDIC 1) -ENDIF(PCRE2_EBCDIC) - -IF(PCRE2_EBCDIC_NL25) - SET(EBCDIC 1) - SET(EBCDIC_NL25 1) -ENDIF(PCRE2_EBCDIC_NL25) - -IF(PCRE2_HEAP_MATCH_RECURSE) - SET(HEAP_MATCH_RECURSE 1) -ENDIF(PCRE2_HEAP_MATCH_RECURSE) - -# Output files - -CONFIGURE_FILE(config-cmake.h.in - ${PROJECT_BINARY_DIR}/config.h - @ONLY) - -# Parse version numbers and date out of configure.ac - -file(STRINGS ${PROJECT_SOURCE_DIR}/configure.ac - configure_lines - LIMIT_COUNT 50 # Read only the first 50 lines of the file -) - -set(SEARCHED_VARIABLES "pcre2_major" "pcre2_minor" "pcre2_prerelease" "pcre2_date") -foreach(configure_line ${configure_lines}) - foreach(_substitution_variable ${SEARCHED_VARIABLES}) - string(TOUPPER ${_substitution_variable} _substitution_variable_upper) - if (NOT ${_substitution_variable_upper}) - string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MACTHED_STRING ${configure_line}) - if (CMAKE_MATCH_1) - set(${_substitution_variable_upper} ${CMAKE_MATCH_1}) - endif() - endif() - endforeach() -endforeach() - -CONFIGURE_FILE(src/pcre2.h.in - ${PROJECT_BINARY_DIR}/pcre2.h - @ONLY) - -# What about pcre2-config and libpcre2.pc? - -# Character table generation - -OPTION(PCRE2_REBUILD_CHARTABLES "Rebuild char tables" OFF) -IF(PCRE2_REBUILD_CHARTABLES) - ADD_EXECUTABLE(dftables src/dftables.c) - ADD_CUSTOM_COMMAND( - COMMENT "Generating character tables (pcre2_chartables.c) for current locale" - DEPENDS dftables - COMMAND dftables - ARGS ${PROJECT_BINARY_DIR}/pcre2_chartables.c - OUTPUT ${PROJECT_BINARY_DIR}/pcre2_chartables.c - ) -ELSE(PCRE2_REBUILD_CHARTABLES) - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/src/pcre2_chartables.c.dist - ${PROJECT_BINARY_DIR}/pcre2_chartables.c - COPYONLY) -ENDIF(PCRE2_REBUILD_CHARTABLES) - -# Source code - -SET(PCRE2_HEADERS ${PROJECT_BINARY_DIR}/pcre2.h) - -SET(PCRE2_SOURCES - src/pcre2_auto_possess.c - ${PROJECT_BINARY_DIR}/pcre2_chartables.c - src/pcre2_compile.c - src/pcre2_config.c - src/pcre2_context.c - src/pcre2_dfa_match.c - src/pcre2_error.c - src/pcre2_find_bracket.c - src/pcre2_jit_compile.c - src/pcre2_maketables.c - src/pcre2_match.c - src/pcre2_match_data.c - src/pcre2_newline.c - src/pcre2_ord2utf.c - src/pcre2_pattern_info.c - src/pcre2_serialize.c - src/pcre2_string_utils.c - src/pcre2_study.c - src/pcre2_substitute.c - src/pcre2_substring.c - src/pcre2_tables.c - src/pcre2_ucd.c - src/pcre2_valid_utf.c - src/pcre2_xclass.c -) - -SET(PCRE2POSIX_HEADERS src/pcre2posix.h) -SET(PCRE2POSIX_SOURCES src/pcre2posix.c) - -IF(MINGW AND NOT PCRE2_STATIC) -IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) -ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre2.o -PRE-LINK -COMMAND windres ARGS pcre2.rc pcre2.o -WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} -COMMENT Using pcre2 coff info in mingw build) -SET(PCRE2_SOURCES - ${PCRE2_SOURCES} ${PROJECT_SOURCE_DIR}/pcre2.o -) -ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) -IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) -ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre2posix.o -PRE-LINK -COMMAND windres ARGS pcre2posix.rc pcre2posix.o -WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} -COMMENT Using pcre2posix coff info in mingw build) -SET(PCRE2POSIX_SOURCES - ${PCRE2POSIX_SOURCES} ${PROJECT_SOURCE_DIR}/pcre2posix.o -) -ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) -ENDIF(MINGW AND NOT PCRE2_STATIC) - -IF(MSVC AND NOT PCRE2_STATIC) -IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) -SET(PCRE2_SOURCES - ${PCRE2_SOURCES} pcre2.rc) -ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre2.rc) -IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) -SET(PCRE2POSIX_SOURCES - ${PCRE2POSIX_SOURCES} pcre2posix.rc) -ENDIF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) -ENDIF(MSVC AND NOT PCRE2_STATIC) - -# Build setup - -ADD_DEFINITIONS(-DHAVE_CONFIG_H) - -IF(MSVC) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) -ENDIF(MSVC) - -SET(CMAKE_INCLUDE_CURRENT_DIR 1) -# needed to make sure to not link debug libs -# against release libs and vice versa -IF(WIN32) - SET(CMAKE_DEBUG_POSTFIX "d") -ENDIF(WIN32) - -SET(targets) - -# 8-bit library - -IF(PCRE2_BUILD_PCRE2_8) -ADD_LIBRARY(pcre2-8 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) -SET_PROPERTY(TARGET pcre2-8 - PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) -SET(targets ${targets} pcre2-8) -ADD_LIBRARY(pcre2posix ${PCRE2POSIX_HEADERS} ${PCRE2POSIX_SOURCES}) -SET_PROPERTY(TARGET pcre2posix - PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) -SET(targets ${targets} pcre2posix) -TARGET_LINK_LIBRARIES(pcre2posix pcre2-8) - -IF(MINGW AND NOT PCRE2_STATIC) - IF(NON_STANDARD_LIB_PREFIX) - SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES PREFIX "") - ENDIF(NON_STANDARD_LIB_PREFIX) - IF(NON_STANDARD_LIB_SUFFIX) - SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES SUFFIX "-0.dll") - ENDIF(NON_STANDARD_LIB_SUFFIX) -ENDIF(MINGW AND NOT PCRE2_STATIC) -ENDIF(PCRE2_BUILD_PCRE2_8) - -# 16-bit library - -IF(PCRE2_BUILD_PCRE2_16) -ADD_LIBRARY(pcre2-16 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) -SET_PROPERTY(TARGET pcre2-16 - PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=16) -SET(targets ${targets} pcre2-16) - -IF(MINGW AND NOT PCRE2_STATIC) - IF(NON_STANDARD_LIB_PREFIX) - SET_TARGET_PROPERTIES(pcre2-16 PROPERTIES PREFIX "") - ENDIF(NON_STANDARD_LIB_PREFIX) - IF(NON_STANDARD_LIB_SUFFIX) - SET_TARGET_PROPERTIES(pcre2-16 PROPERTIES SUFFIX "-0.dll") - ENDIF(NON_STANDARD_LIB_SUFFIX) -ENDIF(MINGW AND NOT PCRE2_STATIC) -ENDIF(PCRE2_BUILD_PCRE2_16) - -# 32-bit library - -IF(PCRE2_BUILD_PCRE2_32) -ADD_LIBRARY(pcre2-32 ${PCRE2_HEADERS} ${PCRE2_SOURCES} ${PROJECT_BINARY_DIR}/config.h) -SET_PROPERTY(TARGET pcre2-32 - PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=32) -SET(targets ${targets} pcre2-32) - -IF(MINGW AND NOT PCRE2_STATIC) - IF(NON_STANDARD_LIB_PREFIX) - SET_TARGET_PROPERTIES(pcre2-32 PROPERTIES PREFIX "") - ENDIF(NON_STANDARD_LIB_PREFIX) - IF(NON_STANDARD_LIB_SUFFIX) - SET_TARGET_PROPERTIES(pcre2-32 PROPERTIES SUFFIX "-0.dll") - ENDIF(NON_STANDARD_LIB_SUFFIX) -ENDIF(MINGW AND NOT PCRE2_STATIC) -ENDIF(PCRE2_BUILD_PCRE2_32) - -# Executables - -IF(PCRE2_BUILD_PCRE2GREP) - ADD_EXECUTABLE(pcre2grep src/pcre2grep.c) - SET_PROPERTY(TARGET pcre2grep - PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8) - SET(targets ${targets} pcre2grep) - TARGET_LINK_LIBRARIES(pcre2grep pcre2posix ${PCRE2GREP_LIBS}) -ENDIF(PCRE2_BUILD_PCRE2GREP) - -# Testing - -IF(PCRE2_BUILD_TESTS) - ENABLE_TESTING() - - SET(PCRE2TEST_SOURCES src/pcre2test.c) - - ADD_EXECUTABLE(pcre2test ${PCRE2TEST_SOURCES}) - SET(targets ${targets} pcre2test) - IF(PCRE2_BUILD_PCRE2_8) - LIST(APPEND PCRE2TEST_LIBS pcre2posix pcre2-8) - ENDIF(PCRE2_BUILD_PCRE2_8) - IF(PCRE2_BUILD_PCRE2_16) - LIST(APPEND PCRE2TEST_LIBS pcre2-16) - ENDIF(PCRE2_BUILD_PCRE2_16) - IF(PCRE2_BUILD_PCRE2_32) - LIST(APPEND PCRE2TEST_LIBS pcre2-32) - ENDIF(PCRE2_BUILD_PCRE2_32) - TARGET_LINK_LIBRARIES(pcre2test ${PCRE2TEST_LIBS}) - - IF(PCRE2_SUPPORT_JIT) - ADD_EXECUTABLE(pcre2_jit_test src/pcre2_jit_test.c) - SET(targets ${targets} pcre2_jit_test) - SET(PCRE2_JIT_TEST_LIBS ) - IF(PCRE2_BUILD_PCRE2_8) - LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-8) - ENDIF(PCRE2_BUILD_PCRE2_8) - IF(PCRE2_BUILD_PCRE2_16) - LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-16) - ENDIF(PCRE2_BUILD_PCRE2_16) - IF(PCRE2_BUILD_PCRE2_32) - LIST(APPEND PCRE2_JIT_TEST_LIBS pcre2-32) - ENDIF(PCRE2_BUILD_PCRE2_32) - TARGET_LINK_LIBRARIES(pcre2_jit_test ${PCRE2_JIT_TEST_LIBS}) - ENDIF(PCRE2_SUPPORT_JIT) - - # exes in Debug location tested by the RunTest shell script - # via "make test" - - IF(PCRE2_BUILD_PCRE2GREP) - GET_TARGET_PROPERTY(PCRE2GREP_EXE pcre2grep DEBUG_LOCATION) - ENDIF(PCRE2_BUILD_PCRE2GREP) - - GET_TARGET_PROPERTY(PCRE2TEST_EXE pcre2test DEBUG_LOCATION) - -# ================================================= - # Write out a CTest configuration file - # - FILE(WRITE ${PROJECT_BINARY_DIR}/CTestCustom.ctest - "# This is a generated file. -MESSAGE(\"When testing is complete, review test output in the -\\\"${PROJECT_BINARY_DIR}/Testing/Temporary\\\" folder.\") -MESSAGE(\" \") -") - - FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_test.sh - "#! /bin/sh -# This is a generated file. -. ${PROJECT_SOURCE_DIR}/RunTest -if test \"$?\" != \"0\"; then exit 1; fi -# End -") - - IF(UNIX) - ADD_TEST(pcre2_test sh ${PROJECT_BINARY_DIR}/pcre2_test.sh) - ENDIF(UNIX) - - IF(PCRE2_BUILD_PCRE2GREP) - FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh - "#! /bin/sh -# This is a generated file. -. ${PROJECT_SOURCE_DIR}/RunGrepTest -if test \"$?\" != \"0\"; then exit 1; fi -# End -") - - IF(UNIX) - ADD_TEST(pcre2_grep_test sh ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh) - ENDIF(UNIX) - ENDIF(PCRE2_BUILD_PCRE2GREP) - - IF(WIN32) - # Provide environment for executing the bat file version of RunTest - FILE(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} winsrc) - FILE(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} winbin) - FILE(TO_NATIVE_PATH ${PCRE2TEST_EXE} winexe) - - FILE(WRITE ${PROJECT_BINARY_DIR}/pcre2_test.bat - "\@REM This is a generated file. -\@echo off -setlocal -SET srcdir=\"${winsrc}\" -SET pcre2test=\"${winexe}\" -if not [%CMAKE_CONFIG_TYPE%]==[] SET pcre2test=\"${winbin}\\%CMAKE_CONFIG_TYPE%\\pcre2test.exe\" -call %srcdir%\\RunTest.Bat -if errorlevel 1 exit /b 1 -echo RunTest.bat tests successfully completed -") - - ADD_TEST(NAME pcre2_test_bat - COMMAND pcre2_test.bat) - SET_TESTS_PROPERTIES(pcre2_test_bat PROPERTIES - PASS_REGULAR_EXPRESSION "RunTest\\.bat tests successfully completed") - - IF("$ENV{OSTYPE}" STREQUAL "msys") - # Both the sh and bat file versions of RunTest are run if make test is used - # in msys - ADD_TEST(pcre2_test_sh sh.exe ${PROJECT_BINARY_DIR}/pcre2_test.sh) - IF(PCRE2_BUILD_PCRE2GREP) - ADD_TEST(pcre2_grep_test sh.exe ${PROJECT_BINARY_DIR}/pcre2_grep_test.sh) - ENDIF(PCRE2_BUILD_PCRE2GREP) - ENDIF("$ENV{OSTYPE}" STREQUAL "msys") - ENDIF(WIN32) - - # Changed to accommodate testing whichever location was just built - - IF(PCRE2_SUPPORT_JIT) - ADD_TEST(pcre2_jit_test pcre2_jit_test) - ENDIF(PCRE2_SUPPORT_JIT) - -ENDIF(PCRE2_BUILD_TESTS) - -# Installation - -SET(CMAKE_INSTALL_ALWAYS 1) - -INSTALL(TARGETS ${targets} - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - -INSTALL(FILES ${PCRE2_HEADERS} ${PCRE2POSIX_HEADERS} DESTINATION include) - -FILE(GLOB html ${PROJECT_SOURCE_DIR}/doc/html/*.html) -FILE(GLOB man1 ${PROJECT_SOURCE_DIR}/doc/*.1) -FILE(GLOB man3 ${PROJECT_SOURCE_DIR}/doc/*.3) - -FOREACH(man ${man3}) - GET_FILENAME_COMPONENT(man_tmp ${man} NAME) - SET(man3_new ${man3} ${man}) -ENDFOREACH(man ${man3}) -SET(man3 ${man3_new}) - -INSTALL(FILES ${man1} DESTINATION man/man1) -INSTALL(FILES ${man3} DESTINATION man/man3) -INSTALL(FILES ${html} DESTINATION share/doc/pcre2/html) - -IF(MSVC AND INSTALL_MSVC_PDB) - INSTALL(FILES ${PROJECT_BINARY_DIR}/pcre2.pdb - ${PROJECT_BINARY_DIR}/pcre2posix.pdb - DESTINATION bin - CONFIGURATIONS RelWithDebInfo) - INSTALL(FILES ${PROJECT_BINARY_DIR}/pcre2d.pdb - ${PROJECT_BINARY_DIR}/pcre2posixd.pdb - DESTINATION bin - CONFIGURATIONS Debug) -ENDIF(MSVC AND INSTALL_MSVC_PDB) - -# Help, only for nice output -IF(BUILD_SHARED_LIBS) - SET(BUILD_STATIC_LIBS OFF) -ELSE(BUILD_SHARED_LIBS) - SET(BUILD_STATIC_LIBS ON) -ENDIF(BUILD_SHARED_LIBS) - -IF(PCRE2_SHOW_REPORT) - STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) - IF (CMAKE_C_FLAGS) - SET(cfsp " ") - ENDIF(CMAKE_C_FLAGS) - MESSAGE(STATUS "") - MESSAGE(STATUS "") - MESSAGE(STATUS "PCRE2 configuration summary:") - MESSAGE(STATUS "") - MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}") - MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}") - MESSAGE(STATUS " C compiler flags ................ : ${CMAKE_C_FLAGS}${cfsp}${CMAKE_C_FLAGS_${buildtype}}") - MESSAGE(STATUS "") - MESSAGE(STATUS " Build 8 bit PCRE2 library ....... : ${PCRE2_BUILD_PCRE2_8}") - MESSAGE(STATUS " Build 16 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_16}") - MESSAGE(STATUS " Build 32 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_32}") - MESSAGE(STATUS " Enable JIT compiling support .... : ${PCRE2_SUPPORT_JIT}") - MESSAGE(STATUS " Enable Unicode support .......... : ${PCRE2_SUPPORT_UNICODE}") - MESSAGE(STATUS " Newline char/sequence ........... : ${PCRE2_NEWLINE}") - MESSAGE(STATUS " \\R matches only ANYCRLF ......... : ${PCRE2_SUPPORT_BSR_ANYCRLF}") - MESSAGE(STATUS " \\C is disabled .................. : ${PCRE2_NEVER_BACKSLASH_C}") - MESSAGE(STATUS " EBCDIC coding ................... : ${PCRE2_EBCDIC}") - MESSAGE(STATUS " EBCDIC coding with NL=0x25 ...... : ${PCRE2_EBCDIC_NL25}") - MESSAGE(STATUS " Rebuild char tables ............. : ${PCRE2_REBUILD_CHARTABLES}") - MESSAGE(STATUS " Use heap recursion .............. : ${PCRE2_HEAP_MATCH_RECURSE}") - MESSAGE(STATUS " Internal link size .............. : ${PCRE2_LINK_SIZE}") - MESSAGE(STATUS " Parentheses nest limit .......... : ${PCRE2_PARENS_NEST_LIMIT}") - MESSAGE(STATUS " Match limit ..................... : ${PCRE2_MATCH_LIMIT}") - MESSAGE(STATUS " Match limit recursion ........... : ${PCRE2_MATCH_LIMIT_RECURSION}") - MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") - MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") - MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}") - MESSAGE(STATUS " Enable JIT in pcre2grep ......... : ${PCRE2_SUPPORT_PCRE2GREP_JIT}") - MESSAGE(STATUS " Buffer size for pcre2grep ....... : ${PCRE2GREP_BUFSIZE}") - MESSAGE(STATUS " Build tests (implies pcre2test . : ${PCRE2_BUILD_TESTS}") - MESSAGE(STATUS " and pcre2grep)") - IF(ZLIB_FOUND) - MESSAGE(STATUS " Link pcre2grep with libz ........ : ${PCRE2_SUPPORT_LIBZ}") - ELSE(ZLIB_FOUND) - MESSAGE(STATUS " Link pcre2grep with libz ........ : Library not found" ) - ENDIF(ZLIB_FOUND) - IF(BZIP2_FOUND) - MESSAGE(STATUS " Link pcre2grep with libbz2 ...... : ${PCRE2_SUPPORT_LIBBZ2}") - ELSE(BZIP2_FOUND) - MESSAGE(STATUS " Link pcre2grep with libbz2 ...... : Library not found" ) - ENDIF(BZIP2_FOUND) - IF(EDITLINE_FOUND) - MESSAGE(STATUS " Link pcre2test with libeditline . : ${PCRE2_SUPPORT_LIBEDIT}") - ELSE(EDITLINE_FOUND) - MESSAGE(STATUS " Link pcre2test with libeditline . : Library not found" ) - ENDIF(EDITLINE_FOUND) - IF(READLINE_FOUND) - MESSAGE(STATUS " Link pcre2test with libreadline . : ${PCRE2_SUPPORT_LIBREADLINE}") - ELSE(READLINE_FOUND) - MESSAGE(STATUS " Link pcre2test with libreadline . : Library not found" ) - ENDIF(READLINE_FOUND) - MESSAGE(STATUS " Support Valgrind .................: ${PCRE2_SUPPORT_VALGRIND}") - - IF(MINGW AND NOT PCRE2_STATIC) - MESSAGE(STATUS " Non-standard dll names (prefix) . : ${NON_STANDARD_LIB_PREFIX}") - MESSAGE(STATUS " Non-standard dll names (suffix) . : ${NON_STANDARD_LIB_SUFFIX}") - ENDIF(MINGW AND NOT PCRE2_STATIC) - - IF(MSVC) - MESSAGE(STATUS " Install MSVC .pdb files ..........: ${INSTALL_MSVC_PDB}") - ENDIF(MSVC) - - MESSAGE(STATUS "") -ENDIF(PCRE2_SHOW_REPORT) - -# end CMakeLists.txt diff --git a/pcre2/COPYING b/pcre2/COPYING deleted file mode 100644 index c233950f6..000000000 --- a/pcre2/COPYING +++ /dev/null @@ -1,5 +0,0 @@ -PCRE2 LICENCE - -Please see the file LICENCE in the PCRE2 distribution for licensing details. - -End diff --git a/pcre2/ChangeLog b/pcre2/ChangeLog deleted file mode 100644 index 2035490c6..000000000 --- a/pcre2/ChangeLog +++ /dev/null @@ -1,758 +0,0 @@ -Change Log for PCRE2 --------------------- - -Version 10.21 12-January-2016 ------------------------------ - -1. Improve matching speed of patterns starting with + or * in JIT. - -2. Use memchr() to find the first character in an unanchored match in 8-bit -mode in the interpreter. This gives a significant speed improvement. - -3. Removed a redundant copy of the opcode_possessify table in the -pcre2_auto_possessify.c source. - -4. Fix typos in dftables.c for z/OS. - -5. Change 36 for 10.20 broke the handling of [[:>:]] and [[:<:]] in that -processing them could involve a buffer overflow if the following character was -an opening parenthesis. - -6. Change 36 for 10.20 also introduced a bug in processing this pattern: -/((?x)(*:0))#(?'/. Specifically: if a setting of (?x) was followed by a (*MARK) -setting (which (*:0) is), then (?x) did not get unset at the end of its group -during the scan for named groups, and hence the external # was incorrectly -treated as a comment and the invalid (?' at the end of the pattern was not -diagnosed. This caused a buffer overflow during the real compile. This bug was -discovered by Karl Skomski with the LLVM fuzzer. - -7. Moved the pcre2_find_bracket() function from src/pcre2_compile.c into its -own source module to avoid a circular dependency between src/pcre2_compile.c -and src/pcre2_study.c - -8. A callout with a string argument containing an opening square bracket, for -example /(?C$[$)(?<]/, was incorrectly processed and could provoke a buffer -overflow. This bug was discovered by Karl Skomski with the LLVM fuzzer. - -9. The handling of callouts during the pre-pass for named group identification -has been tightened up. - -10. The quantifier {1} can be ignored, whether greedy, non-greedy, or -possessive. This is a very minor optimization. - -11. A possessively repeated conditional group that could match an empty string, -for example, /(?(R))*+/, was incorrectly compiled. - -12. The Unicode tables have been updated to Unicode 8.0.0 (thanks to Christian -Persch). - -13. An empty comment (?#) in a pattern was incorrectly processed and could -provoke a buffer overflow. This bug was discovered by Karl Skomski with the -LLVM fuzzer. - -14. Fix infinite recursion in the JIT compiler when certain patterns such as -/(?:|a|){100}x/ are analysed. - -15. Some patterns with character classes involving [: and \\ were incorrectly -compiled and could cause reading from uninitialized memory or an incorrect -error diagnosis. Examples are: /[[:\\](?<[::]/ and /[[:\\](?'abc')[a:]. The -first of these bugs was discovered by Karl Skomski with the LLVM fuzzer. - -16. Pathological patterns containing many nested occurrences of [: caused -pcre2_compile() to run for a very long time. This bug was found by the LLVM -fuzzer. - -17. A missing closing parenthesis for a callout with a string argument was not -being diagnosed, possibly leading to a buffer overflow. This bug was found by -the LLVM fuzzer. - -18. A conditional group with only one branch has an implicit empty alternative -branch and must therefore be treated as potentially matching an empty string. - -19. If (?R was followed by - or + incorrect behaviour happened instead of a -diagnostic. This bug was discovered by Karl Skomski with the LLVM fuzzer. - -20. Another bug that was introduced by change 36 for 10.20: conditional groups -whose condition was an assertion preceded by an explicit callout with a string -argument might be incorrectly processed, especially if the string contained \Q. -This bug was discovered by Karl Skomski with the LLVM fuzzer. - -21. Compiling PCRE2 with the sanitize options of clang showed up a number of -very pedantic coding infelicities and a buffer overflow while checking a UTF-8 -string if the final multi-byte UTF-8 character was truncated. - -22. For Perl compatibility in EBCDIC environments, ranges such as a-z in a -class, where both values are literal letters in the same case, omit the -non-letter EBCDIC code points within the range. - -23. Finding the minimum matching length of complex patterns with back -references and/or recursions can take a long time. There is now a cut-off that -gives up trying to find a minimum length when things get too complex. - -24. An optimization has been added that speeds up finding the minimum matching -length for patterns containing repeated capturing groups or recursions. - -25. If a pattern contained a back reference to a group whose number was -duplicated as a result of appearing in a (?|...) group, the computation of the -minimum matching length gave a wrong result, which could cause incorrect "no -match" errors. For such patterns, a minimum matching length cannot at present -be computed. - -26. Added a check for integer overflow in conditions (?() and -(?(R). This omission was discovered by Karl Skomski with the LLVM -fuzzer. - -27. Fixed an issue when \p{Any} inside an xclass did not read the current -character. - -28. If pcre2grep was given the -q option with -c or -l, or when handling a -binary file, it incorrectly wrote output to stdout. - -29. The JIT compiler did not restore the control verb head in case of *THEN -control verbs. This issue was found by Karl Skomski with a custom LLVM fuzzer. - -30. The way recursive references such as (?3) are compiled has been re-written -because the old way was the cause of many issues. Now, conversion of the group -number into a pattern offset does not happen until the pattern has been -completely compiled. This does mean that detection of all infinitely looping -recursions is postponed till match time. In the past, some easy ones were -detected at compile time. This re-writing was done in response to yet another -bug found by the LLVM fuzzer. - -31. A test for a back reference to a non-existent group was missing for items -such as \987. This caused incorrect code to be compiled. This issue was found -by Karl Skomski with a custom LLVM fuzzer. - -32. Error messages for syntax errors following \g and \k were giving inaccurate -offsets in the pattern. - -33. Improve the performance of starting single character repetitions in JIT. - -34. (*LIMIT_MATCH=) now gives an error instead of setting the value to 0. - -35. Error messages for syntax errors in *LIMIT_MATCH and *LIMIT_RECURSION now -give the right offset instead of zero. - -36. The JIT compiler should not check repeats after a {0,1} repeat byte code. -This issue was found by Karl Skomski with a custom LLVM fuzzer. - -37. The JIT compiler should restore the control chain for empty possessive -repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer. - -38. A bug which was introduced by the single character repetition optimization -was fixed. - -39. Match limit check added to recursion. This issue was found by Karl Skomski -with a custom LLVM fuzzer. - -40. Arrange for the UTF check in pcre2_match() and pcre2_dfa_match() to look -only at the part of the subject that is relevant when the starting offset is -non-zero. - -41. Improve first character match in JIT with SSE2 on x86. - -42. Fix two assertion fails in JIT. These issues were found by Karl Skomski -with a custom LLVM fuzzer. - -43. Correct the setting of CMAKE_C_FLAGS in CMakeLists.txt (patch from Roy Ivy -III). - -44. Fix bug in RunTest.bat for new test 14, and adjust the script for the added -test (there are now 20 in total). - -45. Fixed a corner case of range optimization in JIT. - -46. Add the ${*MARK} facility to pcre2_substitute(). - -47. Modifier lists in pcre2test were splitting at spaces without the required -commas. - -48. Implemented PCRE2_ALT_VERBNAMES. - -49. Fixed two issues in JIT. These were found by Karl Skomski with a custom -LLVM fuzzer. - -50. The pcre2test program has been extended by adding the #newline_default -command. This has made it possible to run the standard tests when PCRE2 is -compiled with either CR or CRLF as the default newline convention. As part of -this work, the new command was added to several test files and the testing -scripts were modified. The pcre2grep tests can now also be run when there is no -LF in the default newline convention. - -51. The RunTest script has been modified so that, when JIT is used and valgrind -is specified, a valgrind suppressions file is set up to ignore "Invalid read of -size 16" errors because these are false positives when the hardware supports -the SSE2 instruction set. - -52. It is now possible to have comment lines amid the subject strings in -pcre2test (and perltest.sh) input. - -53. Implemented PCRE2_USE_OFFSET_LIMIT and pcre2_set_offset_limit(). - -54. Add the null_context modifier to pcre2test so that calling pcre2_compile() -and the matching functions with NULL contexts can be tested. - -55. Implemented PCRE2_SUBSTITUTE_EXTENDED. - -56. In a character class such as [\W\p{Any}] where both a negative-type escape -("not a word character") and a property escape were present, the property -escape was being ignored. - -57. Fixed integer overflow for patterns whose minimum matching length is very, -very large. - -58. Implemented --never-backslash-C. - -59. Change 55 above introduced a bug by which certain patterns provoked the -erroneous error "\ at end of pattern". - -60. The special sequences [[:<:]] and [[:>:]] gave rise to incorrect compiling -errors or other strange effects if compiled in UCP mode. Found with libFuzzer -and AddressSanitizer. - -61. Whitespace at the end of a pcre2test pattern line caused a spurious error -message if there were only single-character modifiers. It should be ignored. - -62. The use of PCRE2_NO_AUTO_CAPTURE could cause incorrect compilation results -or segmentation errors for some patterns. Found with libFuzzer and -AddressSanitizer. - -63. Very long names in (*MARK) or (*THEN) etc. items could provoke a buffer -overflow. - -64. Improve error message for overly-complicated patterns. - -65. Implemented an optional replication feature for patterns in pcre2test, to -make it easier to test long repetitive patterns. The tests for 63 above are -converted to use the new feature. - -66. In the POSIX wrapper, if regerror() was given too small a buffer, it could -misbehave. - -67. In pcre2_substitute() in UTF mode, the UTF validity check on the -replacement string was happening before the length setting when the replacement -string was zero-terminated. - -68. In pcre2_substitute() in UTF mode, PCRE2_NO_UTF_CHECK can be set for the -second and subsequent calls to pcre2_match(). - -69. There was no check for integer overflow for a replacement group number in -pcre2_substitute(). An added check for a number greater than the largest group -number in the pattern means this is not now needed. - -70. The PCRE2-specific VERSION condition didn't work correctly if only one -digit was given after the decimal point, or if more than two digits were given. -It now works with one or two digits, and gives a compile time error if more are -given. - -71. In pcre2_substitute() there was the possibility of reading one code unit -beyond the end of the replacement string. - -72. The code for checking a subject's UTF-32 validity for a pattern with a -lookbehind involved an out-of-bounds pointer, which could potentially cause -trouble in some environments. - -73. The maximum lookbehind length was incorrectly calculated for patterns such -as /(?<=(a)(?-1))x/ which have a recursion within a backreference. - -74. Give an error if a lookbehind assertion is longer than 65535 code units. - -75. Give an error in pcre2_substitute() if a match ends before it starts (as a -result of the use of \K). - -76. Check the length of subpattern names and the names in (*MARK:xx) etc. -dynamically to avoid the possibility of integer overflow. - -77. Implement pcre2_set_max_pattern_length() so that programs can restrict the -size of patterns that they are prepared to handle. - -78. (*NO_AUTO_POSSESS) was not working. - -79. Adding group information caching improves the speed of compiling when -checking whether a group has a fixed length and/or could match an empty string, -especially when recursion or subroutine calls are involved. However, this -cannot be used when (?| is present in the pattern because the same number may -be used for groups of different sizes. To catch runaway patterns in this -situation, counts have been introduced to the functions that scan for empty -branches or compute fixed lengths. - -80. Allow for the possibility of the size of the nest_save structure not being -a factor of the size of the compiling workspace (it currently is). - -81. Check for integer overflow in minimum length calculation and cap it at -65535. - -82. Small optimizations in code for finding the minimum matching length. - -83. Lock out configuring for EBCDIC with non-8-bit libraries. - -84. Test for error code <= 0 in regerror(). - -85. Check for too many replacements (more than INT_MAX) in pcre2_substitute(). - -86. Avoid the possibility of computing with an out-of-bounds pointer (though -not dereferencing it) while handling lookbehind assertions. - -87. Failure to get memory for the match data in regcomp() is now given as a -regcomp() error instead of waiting for regexec() to pick it up. - -88. In pcre2_substitute(), ensure that CRLF is not split when it is a valid -newline sequence. - -89. Paranoid check in regcomp() for bad error code from pcre2_compile(). - -90. Run test 8 (internal offsets and code sizes) for link sizes 3 and 4 as well -as for link size 2. - -91. Document that JIT has a limit on pattern size, and give more information -about JIT compile failures in pcre2test. - -92. Implement PCRE2_INFO_HASBACKSLASHC. - -93. Re-arrange valgrind support code in pcre2test to avoid spurious reports -with JIT (possibly caused by SSE2?). - -94. Support offset_limit in JIT. - -95. A sequence such as [[:punct:]b] that is, a POSIX character class followed -by a single ASCII character in a class item, was incorrectly compiled in UCP -mode. The POSIX class got lost, but only if the single character followed it. - -96. [:punct:] in UCP mode was matching some characters in the range 128-255 -that should not have been matched. - -97. If [:^ascii:] or [:^xdigit:] are present in a non-negated class, all -characters with code points greater than 255 are in the class. When a Unicode -property was also in the class (if PCRE2_UCP is set, escapes such as \w are -turned into Unicode properties), wide characters were not correctly handled, -and could fail to match. - -98. In pcre2test, make the "startoffset" modifier a synonym of "offset", -because it sets the "startoffset" parameter for pcre2_match(). - -99. If PCRE2_AUTO_CALLOUT was set on a pattern that had a (?# comment between -an item and its qualifier (for example, A(?#comment)?B) pcre2_compile() -misbehaved. This bug was found by the LLVM fuzzer. - -100. The error for an invalid UTF pattern string always gave the code unit -offset as zero instead of where the invalidity was found. - -101. Further to 97 above, negated classes such as [^[:^ascii:]\d] were also not -working correctly in UCP mode. - -102. Similar to 99 above, if an isolated \E was present between an item and its -qualifier when PCRE2_AUTO_CALLOUT was set, pcre2_compile() misbehaved. This bug -was found by the LLVM fuzzer. - -103. The POSIX wrapper function regexec() crashed if the option REG_STARTEND -was set when the pmatch argument was NULL. It now returns REG_INVARG. - -104. Allow for up to 32-bit numbers in the ordin() function in pcre2grep. - -105. An empty \Q\E sequence between an item and its qualifier caused -pcre2_compile() to misbehave when auto callouts were enabled. This bug -was found by the LLVM fuzzer. - -106. If both PCRE2_ALT_VERBNAMES and PCRE2_EXTENDED were set, and a (*MARK) or -other verb "name" ended with whitespace immediately before the closing -parenthesis, pcre2_compile() misbehaved. Example: /(*:abc )/, but only when -both those options were set. - -107. In a number of places pcre2_compile() was not handling NULL characters -correctly, and pcre2test with the "bincode" modifier was not always correctly -displaying fields containing NULLS: - - (a) Within /x extended #-comments - (b) Within the "name" part of (*MARK) and other *verbs - (c) Within the text argument of a callout - -108. If a pattern that was compiled with PCRE2_EXTENDED started with white -space or a #-type comment that was followed by (?-x), which turns off -PCRE2_EXTENDED, and there was no subsequent (?x) to turn it on again, -pcre2_compile() assumed that (?-x) applied to the whole pattern and -consequently mis-compiled it. This bug was found by the LLVM fuzzer. The fix -for this bug means that a setting of any of the (?imsxU) options at the start -of a pattern is no longer transferred to the options that are returned by -PCRE2_INFO_ALLOPTIONS. In fact, this was an anachronism that should have -changed when the effects of those options were all moved to compile time. - -109. An escaped closing parenthesis in the "name" part of a (*verb) when -PCRE2_ALT_VERBNAMES was set caused pcre2_compile() to malfunction. This bug -was found by the LLVM fuzzer. - -110. Implemented PCRE2_SUBSTITUTE_UNSET_EMPTY, and updated pcre2test to make it -possible to test it. - -111. "Harden" pcre2test against ridiculously large values in modifiers and -command line arguments. - -112. Implemented PCRE2_SUBSTITUTE_UNKNOWN_UNSET and PCRE2_SUBSTITUTE_OVERFLOW_ -LENGTH. - -113. Fix printing of *MARK names that contain binary zeroes in pcre2test. - - -Version 10.20 30-June-2015 --------------------------- - -1. Callouts with string arguments have been added. - -2. Assertion code generator in JIT has been optimized. - -3. The invalid pattern (?(?C) has a missing assertion condition at the end. The -pcre2_compile() function read past the end of the input before diagnosing an -error. This bug was discovered by the LLVM fuzzer. - -4. Implemented pcre2_callout_enumerate(). - -5. Fix JIT compilation of conditional blocks whose assertion is converted to -(*FAIL). E.g: /(?(?!))/. - -6. The pattern /(?(?!)^)/ caused references to random memory. This bug was -discovered by the LLVM fuzzer. - -7. The assertion (?!) is optimized to (*FAIL). This was not handled correctly -when this assertion was used as a condition, for example (?(?!)a|b). In -pcre2_match() it worked by luck; in pcre2_dfa_match() it gave an incorrect -error about an unsupported item. - -8. For some types of pattern, for example /Z*(|d*){216}/, the auto- -possessification code could take exponential time to complete. A recursion -depth limit of 1000 has been imposed to limit the resources used by this -optimization. This infelicity was discovered by the LLVM fuzzer. - -9. A pattern such as /(*UTF)[\S\V\H]/, which contains a negated special class -such as \S in non-UCP mode, explicit wide characters (> 255) can be ignored -because \S ensures they are all in the class. The code for doing this was -interacting badly with the code for computing the amount of space needed to -compile the pattern, leading to a buffer overflow. This bug was discovered by -the LLVM fuzzer. - -10. A pattern such as /((?2)+)((?1))/ which has mutual recursion nested inside -other kinds of group caused stack overflow at compile time. This bug was -discovered by the LLVM fuzzer. - -11. A pattern such as /(?1)(?#?'){8}(a)/ which had a parenthesized comment -between a subroutine call and its quantifier was incorrectly compiled, leading -to buffer overflow or other errors. This bug was discovered by the LLVM fuzzer. - -12. The illegal pattern /(?(?.*!.*)?)/ was not being diagnosed as missing an -assertion after (?(. The code was failing to check the character after (?(?< -for the ! or = that would indicate a lookbehind assertion. This bug was -discovered by the LLVM fuzzer. - -13. A pattern such as /X((?2)()*+){2}+/ which has a possessive quantifier with -a fixed maximum following a group that contains a subroutine reference was -incorrectly compiled and could trigger buffer overflow. This bug was discovered -by the LLVM fuzzer. - -14. Negative relative recursive references such as (?-7) to non-existent -subpatterns were not being diagnosed and could lead to unpredictable behaviour. -This bug was discovered by the LLVM fuzzer. - -15. The bug fixed in 14 was due to an integer variable that was unsigned when -it should have been signed. Some other "int" variables, having been checked, -have either been changed to uint32_t or commented as "must be signed". - -16. A mutual recursion within a lookbehind assertion such as (?<=((?2))((?1))) -caused a stack overflow instead of the diagnosis of a non-fixed length -lookbehind assertion. This bug was discovered by the LLVM fuzzer. - -17. The use of \K in a positive lookbehind assertion in a non-anchored pattern -(e.g. /(?<=\Ka)/) could make pcre2grep loop. - -18. There was a similar problem to 17 in pcre2test for global matches, though -the code there did catch the loop. - -19. If a greedy quantified \X was preceded by \C in UTF mode (e.g. \C\X*), -and a subsequent item in the pattern caused a non-match, backtracking over the -repeated \X did not stop, but carried on past the start of the subject, causing -reference to random memory and/or a segfault. There were also some other cases -where backtracking after \C could crash. This set of bugs was discovered by the -LLVM fuzzer. - -20. The function for finding the minimum length of a matching string could take -a very long time if mutual recursion was present many times in a pattern, for -example, /((?2){73}(?2))((?1))/. A better mutual recursion detection method has -been implemented. This infelicity was discovered by the LLVM fuzzer. - -21. Implemented PCRE2_NEVER_BACKSLASH_C. - -22. The feature for string replication in pcre2test could read from freed -memory if the replication required a buffer to be extended, and it was not -working properly in 16-bit and 32-bit modes. This issue was discovered by a -fuzzer: see http://lcamtuf.coredump.cx/afl/. - -23. Added the PCRE2_ALT_CIRCUMFLEX option. - -24. Adjust the treatment of \8 and \9 to be the same as the current Perl -behaviour. - -25. Static linking against the PCRE2 library using the pkg-config module was -failing on missing pthread symbols. - -26. If a group that contained a recursive back reference also contained a -forward reference subroutine call followed by a non-forward-reference -subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to -compile correct code, leading to undefined behaviour or an internally detected -error. This bug was discovered by the LLVM fuzzer. - -27. Quantification of certain items (e.g. atomic back references) could cause -incorrect code to be compiled when recursive forward references were involved. -For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/. This bug was -discovered by the LLVM fuzzer. - -28. A repeated conditional group whose condition was a reference by name caused -a buffer overflow if there was more than one group with the given name. This -bug was discovered by the LLVM fuzzer. - -29. A recursive back reference by name within a group that had the same name as -another group caused a buffer overflow. For example: /(?J)(?'d'(?'d'\g{d}))/. -This bug was discovered by the LLVM fuzzer. - -30. A forward reference by name to a group whose number is the same as the -current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused a -buffer overflow at compile time. This bug was discovered by the LLVM fuzzer. - -31. Fix -fsanitize=undefined warnings for left shifts of 1 by 31 (it treats 1 -as an int; fixed by writing it as 1u). - -32. Fix pcre2grep compile when -std=c99 is used with gcc, though it still gives -a warning for "fileno" unless -std=gnu99 us used. - -33. A lookbehind assertion within a set of mutually recursive subpatterns could -provoke a buffer overflow. This bug was discovered by the LLVM fuzzer. - -34. Give an error for an empty subpattern name such as (?''). - -35. Make pcre2test give an error if a pattern that follows #forbud_utf contains -\P, \p, or \X. - -36. The way named subpatterns are handled has been refactored. There is now a -pre-pass over the regex which does nothing other than identify named -subpatterns and count the total captures. This means that information about -named patterns is known before the rest of the compile. In particular, it means -that forward references can be checked as they are encountered. Previously, the -code for handling forward references was contorted and led to several errors in -computing the memory requirements for some patterns, leading to buffer -overflows. - -37. There was no check for integer overflow in subroutine calls such as (?123). - -38. The table entry for \l in EBCDIC environments was incorrect, leading to its -being treated as a literal 'l' instead of causing an error. - -39. If a non-capturing group containing a conditional group that could match -an empty string was repeated, it was not identified as matching an empty string -itself. For example: /^(?:(?(1)x|)+)+$()/. - -40. In an EBCDIC environment, pcretest was mishandling the escape sequences -\a and \e in test subject lines. - -41. In an EBCDIC environment, \a in a pattern was converted to the ASCII -instead of the EBCDIC value. - -42. The handling of \c in an EBCDIC environment has been revised so that it is -now compatible with the specification in Perl's perlebcdic page. - -43. Single character repetition in JIT has been improved. 20-30% speedup -was achieved on certain patterns. - -44. The EBCDIC character 0x41 is a non-breaking space, equivalent to 0xa0 in -ASCII/Unicode. This has now been added to the list of characters that are -recognized as white space in EBCDIC. - -45. When PCRE2 was compiled without Unicode support, the use of \p and \P gave -an error (correctly) when used outside a class, but did not give an error -within a class. - -46. \h within a class was incorrectly compiled in EBCDIC environments. - -47. JIT should return with error when the compiled pattern requires -more stack space than the maximum. - -48. Fixed a memory leak in pcre2grep when a locale is set. - - -Version 10.10 06-March-2015 ---------------------------- - -1. When a pattern is compiled, it remembers the highest back reference so that -when matching, if the ovector is too small, extra memory can be obtained to -use instead. A conditional subpattern whose condition is a check on a capture -having happened, such as, for example in the pattern /^(?:(a)|b)(?(1)A|B)/, is -another kind of back reference, but it was not setting the highest -backreference number. This mattered only if pcre2_match() was called with an -ovector that was too small to hold the capture, and there was no other kind of -back reference (a situation which is probably quite rare). The effect of the -bug was that the condition was always treated as FALSE when the capture could -not be consulted, leading to a incorrect behaviour by pcre2_match(). This bug -has been fixed. - -2. Functions for serialization and deserialization of sets of compiled patterns -have been added. - -3. The value that is returned by PCRE2_INFO_SIZE has been corrected to remove -excess code units at the end of the data block that may occasionally occur if -the code for calculating the size over-estimates. This change stops the -serialization code copying uninitialized data, to which valgrind objects. The -documentation of PCRE2_INFO_SIZE was incorrect in stating that the size did not -include the general overhead. This has been corrected. - -4. All code units in every slot in the table of group names are now set, again -in order to avoid accessing uninitialized data when serializing. - -5. The (*NO_JIT) feature is implemented. - -6. If a bug that caused pcre2_compile() to use more memory than allocated was -triggered when using valgrind, the code in (3) above passed a stupidly large -value to valgrind. This caused a crash instead of an "internal error" return. - -7. A reference to a duplicated named group (either a back reference or a test -for being set in a conditional) that occurred in a part of the pattern where -PCRE2_DUPNAMES was not set caused the amount of memory needed for the pattern -to be incorrectly calculated, leading to overwriting. - -8. A mutually recursive set of back references such as (\2)(\1) caused a -segfault at compile time (while trying to find the minimum matching length). -The infinite loop is now broken (with the minimum length unset, that is, zero). - -9. If an assertion that was used as a condition was quantified with a minimum -of zero, matching went wrong. In particular, if the whole group had unlimited -repetition and could match an empty string, a segfault was likely. The pattern -(?(?=0)?)+ is an example that caused this. Perl allows assertions to be -quantified, but not if they are being used as conditions, so the above pattern -is faulted by Perl. PCRE2 has now been changed so that it also rejects such -patterns. - -10. The error message for an invalid quantifier has been changed from "nothing -to repeat" to "quantifier does not follow a repeatable item". - -11. If a bad UTF string is compiled with NO_UTF_CHECK, it may succeed, but -scanning the compiled pattern in subsequent auto-possessification can get out -of step and lead to an unknown opcode. Previously this could have caused an -infinite loop. Now it generates an "internal error" error. This is a tidyup, -not a bug fix; passing bad UTF with NO_UTF_CHECK is documented as having an -undefined outcome. - -12. A UTF pattern containing a "not" match of a non-ASCII character and a -subroutine reference could loop at compile time. Example: /[^\xff]((?1))/. - -13. The locale test (RunTest 3) has been upgraded. It now checks that a locale -that is found in the output of "locale -a" can actually be set by pcre2test -before it is accepted. Previously, in an environment where a locale was listed -but would not set (an example does exist), the test would "pass" without -actually doing anything. Also the fr_CA locale has been added to the list of -locales that can be used. - -14. Fixed a bug in pcre2_substitute(). If a replacement string ended in a -capturing group number without parentheses, the last character was incorrectly -literally included at the end of the replacement string. - -15. A possessive capturing group such as (a)*+ with a minimum repeat of zero -failed to allow the zero-repeat case if pcre2_match() was called with an -ovector too small to capture the group. - -16. Improved error message in pcre2test when setting the stack size (-S) fails. - -17. Fixed two bugs in CMakeLists.txt: (1) Some lines had got lost in the -transfer from PCRE1, meaning that CMake configuration failed if "build tests" -was selected. (2) The file src/pcre2_serialize.c had not been added to the list -of PCRE2 sources, which caused a failure to build pcre2test. - -18. Fixed typo in pcre2_serialize.c (DECL instead of DEFN) that causes problems -only on Windows. - -19. Use binary input when reading back saved serialized patterns in pcre2test. - -20. Added RunTest.bat for running the tests under Windows. - -21. "make distclean" was not removing config.h, a file that may be created for -use with CMake. - -22. A pattern such as "((?2){0,1999}())?", which has a group containing a -forward reference repeated a large (but limited) number of times within a -repeated outer group that has a zero minimum quantifier, caused incorrect code -to be compiled, leading to the error "internal error: previously-checked -referenced subpattern not found" when an incorrect memory address was read. -This bug was reported as "heap overflow", discovered by Kai Lu of Fortinet's -FortiGuard Labs. (Added 24-March-2015: CVE-2015-2325 was given to this.) - -23. A pattern such as "((?+1)(\1))/" containing a forward reference subroutine -call within a group that also contained a recursive back reference caused -incorrect code to be compiled. This bug was reported as "heap overflow", -discovered by Kai Lu of Fortinet's FortiGuard Labs. (Added 24-March-2015: -CVE-2015-2326 was given to this.) - -24. Computing the size of the JIT read-only data in advance has been a source -of various issues, and new ones are still appear unfortunately. To fix -existing and future issues, size computation is eliminated from the code, -and replaced by on-demand memory allocation. - -25. A pattern such as /(?i)[A-`]/, where characters in the other case are -adjacent to the end of the range, and the range contained characters with more -than one other case, caused incorrect behaviour when compiled in UTF mode. In -that example, the range a-j was left out of the class. - - -Version 10.00 05-January-2015 ------------------------------ - -Version 10.00 is the first release of PCRE2, a revised API for the PCRE -library. Changes prior to 10.00 are logged in the ChangeLog file for the old -API, up to item 20 for release 8.36. - -The code of the library was heavily revised as part of the new API -implementation. Details of each and every modification were not individually -logged. In addition to the API changes, the following changes were made. They -are either new functionality, or bug fixes and other noticeable changes of -behaviour that were implemented after the code had been forked. - -1. Including Unicode support at build time is now enabled by default, but it -can optionally be disabled. It is not enabled by default at run time (no -change). - -2. The test program, now called pcre2test, was re-specified and almost -completely re-written. Its input is not compatible with input for pcretest. - -3. Patterns may start with (*NOTEMPTY) or (*NOTEMPTY_ATSTART) to set the -PCRE2_NOTEMPTY or PCRE2_NOTEMPTY_ATSTART options for every subject line that is -matched by that pattern. - -4. For the benefit of those who use PCRE2 via some other application, that is, -not writing the function calls themselves, it is possible to check the PCRE2 -version by matching a pattern such as /(?(VERSION>=10)yes|no)/ against a -string such as "yesno". - -5. There are case-equivalent Unicode characters whose encodings use different -numbers of code units in UTF-8. U+023A and U+2C65 are one example. (It is -theoretically possible for this to happen in UTF-16 too.) If a backreference to -a group containing one of these characters was greedily repeated, and during -the match a backtrack occurred, the subject might be backtracked by the wrong -number of code units. For example, if /^(\x{23a})\1*(.)/ is matched caselessly -(and in UTF-8 mode) against "\x{23a}\x{2c65}\x{2c65}\x{2c65}", group 2 should -capture the final character, which is the three bytes E2, B1, and A5 in UTF-8. -Incorrect backtracking meant that group 2 captured only the last two bytes. -This bug has been fixed; the new code is slower, but it is used only when the -strings matched by the repetition are not all the same length. - -6. A pattern such as /()a/ was not setting the "first character must be 'a'" -information. This applied to any pattern with a group that matched no -characters, for example: /(?:(?=.)|(? 0) - { - $line = 0; - $file = shift @ARGV; - - open (IN, $file) || die "Failed to open $file\n"; - - while () - { - $line++; - if (/^\s*$/) - { - printf "Empty line $line of $file\n"; - $yield = 1; - } - elsif (/^\./) - { - if (!/^\.\s*$| - ^\.B\s+\S| - ^\.TH\s\S| - ^\.SH\s\S| - ^\.SS\s\S| - ^\.TP(?:\s?\d+)?\s*$| - ^\.SM\s*$| - ^\.br\s*$| - ^\.rs\s*$| - ^\.sp\s*$| - ^\.nf\s*$| - ^\.fi\s*$| - ^\.P\s*$| - ^\.PP\s*$| - ^\.\\"(?:\ HREF)?\s*$| - ^\.\\"\sHTML\s\s*$| - ^\.\\"\sHTML\s<\/a>\s*$| - ^\.\\"\s<\/a>\s*$| - ^\.\\"\sJOINSH\s*$| - ^\.\\"\sJOIN\s*$/x - ) - { - printf "Bad control line $line of $file\n"; - $yield = 1; - } - } - else - { - if (/\\[^ef]|\\f[^IBP]/) - { - printf "Bad backslash in line $line of $file\n"; - $yield = 1; - } - } - } - - close(IN); - } - -exit $yield; -# End diff --git a/pcre2/CleanTxt b/pcre2/CleanTxt deleted file mode 100755 index 1f42519c8..000000000 --- a/pcre2/CleanTxt +++ /dev/null @@ -1,113 +0,0 @@ -#! /usr/bin/perl -w - -# Script to take the output of nroff -man and remove all the backspacing and -# the page footers and the screen commands etc so that it is more usefully -# readable online. In fact, in the latest nroff, intermediate footers don't -# seem to be generated any more. - -$blankcount = 0; -$lastwascut = 0; -$firstheader = 1; - -# Input on STDIN; output to STDOUT. - -while () - { - s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" - s/.\x8//g; # Remove "char, backspace" - - # Handle header lines. Retain only the first one we encounter, but remove - # the blank line that follows. Any others (e.g. at end of document) and the - # following blank line are dropped. - - if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/) - { - if ($firstheader) - { - $firstheader = 0; - print; - $lastprinted = $_; - $lastwascut = 0; - } - $_=; # Remove a blank that follows - next; - } - - # Count runs of empty lines - - if (/^\s*$/) - { - $blankcount++; - $lastwascut = 0; - next; - } - - # If a chunk of lines has been cut out (page footer) and the next line - # has a different indentation, put back one blank line. - - if ($lastwascut && $blankcount < 1 && defined($lastprinted)) - { - ($a) = $lastprinted =~ /^(\s*)/; - ($b) = $_ =~ /^(\s*)/; - $blankcount++ if ($a ne $b); - } - - # We get here only when we have a non-blank line in hand. If it was preceded - # by 3 or more blank lines, read the next 3 lines and see if they are blank. - # If so, remove all 7 lines, and remember that we have just done a cut. - - if ($blankcount >= 3) - { - for ($i = 0; $i < 3; $i++) - { - $next[$i] = ; - $next[$i] = "" if !defined $next[$i]; - $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" - $next[$i] =~ s/.\x8//g; # Remove "char, backspace" - } - - # Cut out chunks of the form <3 blanks><3 blanks> - - if ($next[0] =~ /^\s*$/ && - $next[1] =~ /^\s*$/ && - $next[2] =~ /^\s*$/) - { - $blankcount -= 3; - $lastwascut = 1; - } - - # Otherwise output the saved blanks, the current, and the next three - # lines. Remember the last printed line. - - else - { - for ($i = 0; $i < $blankcount; $i++) { print "\n"; } - print; - for ($i = 0; $i < 3; $i++) - { - $next[$i] =~ s/.\x8//g; - print $next[$i]; - $lastprinted = $_; - } - $lastwascut = 0; - $blankcount = 0; - } - } - - # This non-blank line is not preceded by 3 or more blank lines. Output - # any blanks there are, and the line. Remember it. Force two blank lines - # before headings. - - else - { - $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ && - defined($lastprinted); - for ($i = 0; $i < $blankcount; $i++) { print "\n"; } - print; - $lastprinted = $_; - $lastwascut = 0; - $blankcount = 0; - } - } - -# End diff --git a/pcre2/Detrail b/pcre2/Detrail deleted file mode 100755 index 1c5c7e9ca..000000000 --- a/pcre2/Detrail +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl - -# This is a script for removing trailing whitespace from lines in files that -# are listed on the command line. - -# This subroutine does the work for one file. - -sub detrail { -my($file) = $_[0]; -my($changed) = 0; -open(IN, "$file") || die "Can't open $file for input"; -@lines = ; -close(IN); -foreach (@lines) - { - if (/\s+\n$/) - { - s/\s+\n$/\n/; - $changed = 1; - } - } -if ($changed) - { - open(OUT, ">$file") || die "Can't open $file for output"; - print OUT @lines; - close(OUT); - } -} - -# This is the main program - -$, = ""; # Output field separator -for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); } - -# End diff --git a/pcre2/HACKING b/pcre2/HACKING deleted file mode 100644 index 051520c28..000000000 --- a/pcre2/HACKING +++ /dev/null @@ -1,604 +0,0 @@ -Technical Notes about PCRE2 ---------------------------- - -These are very rough technical notes that record potentially useful information -about PCRE2 internals. PCRE2 is a library based on the original PCRE library, -but with a revised (and incompatible) API. To avoid confusion, the original -library is referred to as PCRE1 below. For information about testing PCRE2, see -the pcre2test documentation and the comment at the head of the RunTest file. - -PCRE1 releases were up to 8.3x when PCRE2 was developed. The 8.xx series will -continue for bugfixes if necessary. PCRE2 releases started at 10.00 to avoid -confusion with PCRE1. - - -Historical note 1 ------------------ - -Many years ago I implemented some regular expression functions to an algorithm -suggested by Martin Richards. These were not Unix-like in form, and were quite -restricted in what they could do by comparison with Perl. The interesting part -about the algorithm was that the amount of space required to hold the compiled -form of an expression was known in advance. The code to apply an expression did -not operate by backtracking, as the original Henry Spencer code and current -PCRE2 and Perl code does, but instead checked all possibilities simultaneously -by keeping a list of current states and checking all of them as it advanced -through the subject string. In the terminology of Jeffrey Friedl's book, it was -a "DFA algorithm", though it was not a traditional Finite State Machine (FSM). -When the pattern was all used up, all remaining states were possible matches, -and the one matching the longest subset of the subject string was chosen. This -did not necessarily maximize the individual wild portions of the pattern, as is -expected in Unix and Perl-style regular expressions. - - -Historical note 2 ------------------ - -By contrast, the code originally written by Henry Spencer (which was -subsequently heavily modified for Perl) compiles the expression twice: once in -a dummy mode in order to find out how much store will be needed, and then for -real. (The Perl version probably doesn't do this any more; I'm talking about -the original library.) The execution function operates by backtracking and -maximizing (or, optionally, minimizing, in Perl) the amount of the subject that -matches individual wild portions of the pattern. This is an "NFA algorithm" in -Friedl's terminology. - - -OK, here's the real stuff -------------------------- - -For the set of functions that formed the original PCRE1 library (which are -unrelated to those mentioned above), I tried at first to invent an algorithm -that used an amount of store bounded by a multiple of the number of characters -in the pattern, to save on compiling time. However, because of the greater -complexity in Perl regular expressions, I couldn't do this. In any case, a -first pass through the pattern is helpful for other reasons. - - -Support for 16-bit and 32-bit data strings -------------------------------------------- - -The library can be compiled in any combination of 8-bit, 16-bit or 32-bit -modes, creating up to three different libraries. In the description that -follows, the word "short" is used for a 16-bit data quantity, and the phrase -"code unit" is used for a quantity that is a byte in 8-bit mode, a short in -16-bit mode and a 32-bit word in 32-bit mode. The names of PCRE2 functions are -given in generic form, without the _8, _16, or _32 suffix. - - -Computing the memory requirement: how it was --------------------------------------------- - -Up to and including release 6.7, PCRE1 worked by running a very degenerate -first pass to calculate a maximum memory requirement, and then a second pass to -do the real compile - which might use a bit less than the predicted amount of -memory. The idea was that this would turn out faster than the Henry Spencer -code because the first pass is degenerate and the second pass can just store -stuff straight into memory, which it knows is big enough. - - -Computing the memory requirement: how it is -------------------------------------------- - -By the time I was working on a potential 6.8 release, the degenerate first pass -had become very complicated and hard to maintain. Indeed one of the early -things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then -I had a flash of inspiration as to how I could run the real compile function in -a "fake" mode that enables it to compute how much memory it would need, while -actually only ever using a few hundred bytes of working memory, and without too -many tests of the mode that might slow it down. So I refactored the compiling -functions to work this way. This got rid of about 600 lines of source. It -should make future maintenance and development easier. As this was such a major -change, I never released 6.8, instead upping the number to 7.0 (other quite -major changes were also present in the 7.0 release). - -A side effect of this work was that the previous limit of 200 on the nesting -depth of parentheses was removed. However, there was a downside: compiling ran -more slowly than before (30% or more, depending on the pattern) because it now -did a full analysis of the pattern. My hope was that this would not be a big -issue, and in the event, nobody has commented on it. - -At release 8.34, a limit on the nesting depth of parentheses was re-introduced -(default 250, settable at build time) so as to put a limit on the amount of -system stack used by the compile function, which uses recursive function calls -for nested parenthesized groups. This is a safety feature for environments with -small stacks where the patterns are provided by users. - -History repeated itself for release 10.20. A number of bugs relating to named -subpatterns had been discovered by fuzzers. Most of these were related to the -handling of forward references when it was not known if the named pattern was -unique. (References to non-unique names use a different opcode and more -memory.) The use of duplicate group numbers (the (?| facility) also caused -issues. - -To get around these problems I adopted a new approach by adding a third pass, -really a "pre-pass", over the pattern, which does nothing other than identify -all the named subpatterns and their corresponding group numbers. This means -that the actual compile (both pre-pass and real compile) have full knowledge of -group names and numbers throughout. Several dozen lines of messy code were -eliminated, though the new pre-pass is not short (skipping over [] classes is -complicated). - - -Traditional matching function ------------------------------ - -The "traditional", and original, matching function is called pcre2_match(), and -it implements an NFA algorithm, similar to the original Henry Spencer algorithm -and the way that Perl works. This is not surprising, since it is intended to be -as compatible with Perl as possible. This is the function most users of PCRE2 -will use most of the time. If PCRE2 is compiled with just-in-time (JIT) -support, and studying a compiled pattern with JIT is successful, the JIT code -is run instead of the normal pcre2_match() code, but the result is the same. - - -Supplementary matching function -------------------------------- - -There is also a supplementary matching function called pcre2_dfa_match(). This -implements a DFA matching algorithm that searches simultaneously for all -possible matches that start at one point in the subject string. (Going back to -my roots: see Historical Note 1 above.) This function intreprets the same -compiled pattern data as pcre2_match(); however, not all the facilities are -available, and those that are do not always work in quite the same way. See the -user documentation for details. - -The algorithm that is used for pcre2_dfa_match() is not a traditional FSM, -because it may have a number of states active at one time. More work would be -needed at compile time to produce a traditional FSM where only one state is -ever active at once. I believe some other regex matchers work this way. JIT -support is not available for this kind of matching. - - -Changeable options ------------------- - -The /i, /m, or /s options (PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and -some others) may change in the middle of patterns. Their processing is handled -entirely at compile time by generating different opcodes for the different -settings. The runtime functions do not need to keep track of an options state. - - -Format of compiled patterns ---------------------------- - -The compiled form of a pattern is a vector of unsigned code units (bytes in -8-bit mode, shorts in 16-bit mode, 32-bit words in 32-bit mode), containing -items of variable length. The first code unit in an item contains an opcode, -and the length of the item is either implicit in the opcode or contained in the -data that follows it. - -In many cases listed below, LINK_SIZE data values are specified for offsets -within the compiled pattern. LINK_SIZE always specifies a number of bytes. The -default value for LINK_SIZE is 2, except for the 32-bit library, where it can -only be 4. The 8-bit library can be compiled to used 3-byte or 4-byte values, -and the 16-bit library can be compiled to use 4-byte values, though this -impairs performance. Specifing a LINK_SIZE larger than 2 for these libraries is -necessary only when patterns whose compiled length is greater than 64K code -units are going to be processed. When a LINK_SIZE value uses more than one code -unit, the most significant unit is first. - -In this description, we assume the "normal" compilation options. Data values -that are counts (e.g. quantifiers) are always two bytes long in 8-bit mode -(most significant byte first), or one code unit in 16-bit and 32-bit modes. - - -Opcodes with no following data ------------------------------- - -These items are all just one unit long - - OP_END end of pattern - OP_ANY match any one character other than newline - OP_ALLANY match any one character, including newline - OP_ANYBYTE match any single code unit, even in UTF-8/16 mode - OP_SOD match start of data: \A - OP_SOM, start of match (subject + offset): \G - OP_SET_SOM, set start of match (\K) - OP_CIRC ^ (start of data) - OP_CIRCM ^ multiline mode (start of data or after newline) - OP_NOT_WORD_BOUNDARY \W - OP_WORD_BOUNDARY \w - OP_NOT_DIGIT \D - OP_DIGIT \d - OP_NOT_HSPACE \H - OP_HSPACE \h - OP_NOT_WHITESPACE \S - OP_WHITESPACE \s - OP_NOT_VSPACE \V - OP_VSPACE \v - OP_NOT_WORDCHAR \W - OP_WORDCHAR \w - OP_EODN match end of data or newline at end: \Z - OP_EOD match end of data: \z - OP_DOLL $ (end of data, or before final newline) - OP_DOLLM $ multiline mode (end of data or before newline) - OP_EXTUNI match an extended Unicode grapheme cluster - OP_ANYNL match any Unicode newline sequence - - OP_ASSERT_ACCEPT ) - OP_ACCEPT ) These are Perl 5.10's "backtracking control - OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing - OP_FAIL ) parentheses, it may be preceded by one or more - OP_PRUNE ) OP_CLOSE, each followed by a count that - OP_SKIP ) indicates which parentheses must be closed. - OP_THEN ) - -OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion. -This ends the assertion, not the entire pattern match. The assertion (?!) is -always optimized to OP_FAIL. - - -Backtracking control verbs with optional data ---------------------------------------------- - -(*THEN) without an argument generates the opcode OP_THEN and no following data. -OP_MARK is followed by the mark name, preceded by a length in one code unit, -and followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with -arguments, the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, -with the name following in the same format as OP_MARK. - - -Matching literal characters ---------------------------- - -The OP_CHAR opcode is followed by a single character that is to be matched -casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, -the character may be more than one code unit long. In UTF-32 mode, characters -are always exactly one code unit long. - -If there is only one character in a character class, OP_CHAR or OP_CHARI is -used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is, -for something like [^a]). - - -Repeating single characters ---------------------------- - -The common repeats (*, +, ?), when applied to a single character, use the -following opcodes, which come in caseful and caseless versions: - - Caseful Caseless - OP_STAR OP_STARI - OP_MINSTAR OP_MINSTARI - OP_POSSTAR OP_POSSTARI - OP_PLUS OP_PLUSI - OP_MINPLUS OP_MINPLUSI - OP_POSPLUS OP_POSPLUSI - OP_QUERY OP_QUERYI - OP_MINQUERY OP_MINQUERYI - OP_POSQUERY OP_POSQUERYI - -Each opcode is followed by the character that is to be repeated. In ASCII or -UTF-32 modes, these are two-code-unit items; in UTF-8 or UTF-16 modes, the -length is variable. Those with "MIN" in their names are the minimizing -versions. Those with "POS" in their names are possessive versions. Other kinds -of repeat make use of these opcodes: - - Caseful Caseless - OP_UPTO OP_UPTOI - OP_MINUPTO OP_MINUPTOI - OP_POSUPTO OP_POSUPTOI - OP_EXACT OP_EXACTI - -Each of these is followed by a count and then the repeated character. The count -is two bytes long in 8-bit mode (most significant byte first), or one code unit -in 16-bit and 32-bit modes. - -OP_UPTO matches from 0 to the given number. A repeat with a non-zero minimum -and a fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or -OP_MINUPTO or OPT_POSUPTO). - -Another set of matching repeating opcodes (called OP_NOTSTAR, OP_NOTSTARI, -etc.) are used for repeated, negated, single-character classes such as [^a]*. -The normal single-character opcodes (OP_STAR, etc.) are used for repeated -positive single-character classes. - - -Repeating character types -------------------------- - -Repeats of things like \d are done exactly as for single characters, except -that instead of a character, the opcode for the type (e.g. OP_DIGIT) is stored -in the next code unit. The opcodes are: - - OP_TYPESTAR - OP_TYPEMINSTAR - OP_TYPEPOSSTAR - OP_TYPEPLUS - OP_TYPEMINPLUS - OP_TYPEPOSPLUS - OP_TYPEQUERY - OP_TYPEMINQUERY - OP_TYPEPOSQUERY - OP_TYPEUPTO - OP_TYPEMINUPTO - OP_TYPEPOSUPTO - OP_TYPEEXACT - - -Match by Unicode property -------------------------- - -OP_PROP and OP_NOTPROP are used for positive and negative matches of a -character by testing its Unicode property (the \p and \P escape sequences). -Each is followed by two code units that encode the desired property as a type -and a value. The types are a set of #defines of the form PT_xxx, and the values -are enumerations of the form ucp_xx, defined in the pcre2_ucp.h source file. -The value is relevant only for PT_GC (General Category), PT_PC (Particular -Category), and PT_SC (Script). - -Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by -three code units: OP_PROP or OP_NOTPROP, and then the desired property type and -value. - - -Character classes ------------------ - -If there is only one character in a class, OP_CHAR or OP_CHARI is used for a -positive class, and OP_NOT or OP_NOTI for a negative one (that is, for -something like [^a]). - -A set of repeating opcodes (called OP_NOTSTAR etc.) are used for repeated, -negated, single-character classes. The normal single-character opcodes -(OP_STAR, etc.) are used for repeated positive single-character classes. - -When there is more than one character in a class, and all the code points are -less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a -negative one. In either case, the opcode is followed by a 32-byte (16-short, -8-word) bit map containing a 1 bit for every character that is acceptable. The -bits are counted from the least significant end of each unit. In caseless mode, -bits for both cases are set. - -The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 and -16-bit and 32-bit modes, subject characters with values greater than 255 can be -handled correctly. For OP_CLASS they do not match, whereas for OP_NCLASS they -do. - -For classes containing characters with values greater than 255 or that contain -\p or \P, OP_XCLASS is used. It optionally uses a bit map if any acceptable -code points are less than 256, followed by a list of pairs (for a range) and/or -single characters and/or properties. In caseless mode, both cases are -explicitly listed. - -OP_XCLASS is followed by a LINK_SIZE value containing the total length of the -opcode and its data. This is followed by a code unit containing flag bits: -XCL_NOT indicates that this is a negative class, and XCL_MAP indicates that a -bit map is present. There follows the bit map, if XCL_MAP is set, and then a -sequence of items coded as follows: - - XCL_END marks the end of the list - XCL_SINGLE one character follows - XCL_RANGE two characters follow - XCL_PROP a Unicode property (type, value) follows - XCL_NOTPROP a Unicode property (type, value) follows - -If a range starts with a code point less than 256 and ends with one greater -than 255, it is split into two ranges, with characters less than 256 being -indicated in the bit map, and the rest with XCL_RANGE. - -When XCL_NOT is set, the bit map, if present, contains bits for characters that -are allowed (exactly as for OP_NCLASS), but the list of items that follow it -specifies characters and properties that are not allowed. - - -Back references ---------------- - -OP_REF (caseful) or OP_REFI (caseless) is followed by a count containing the -reference number when the reference is to a unique capturing group (either by -number or by name). When named groups are used, there may be more than one -group with the same name. In this case, a reference to such a group by name -generates OP_DNREF or OP_DNREFI. These are followed by two counts: the index -(not the byte offset) in the group name table of the first entry for the -required name, followed by the number of groups with the same name. The -matching code can then search for the first one that is set. - - -Repeating character classes and back references ------------------------------------------------ - -Single-character classes are handled specially (see above). This section -applies to other classes and also to back references. In both cases, the repeat -information follows the base item. The matching code looks at the following -opcode to see if it is one of these: - - OP_CRSTAR - OP_CRMINSTAR - OP_CRPOSSTAR - OP_CRPLUS - OP_CRMINPLUS - OP_CRPOSPLUS - OP_CRQUERY - OP_CRMINQUERY - OP_CRPOSQUERY - OP_CRRANGE - OP_CRMINRANGE - OP_CRPOSRANGE - -All but the last three are single-code-unit items, with no data. The others are -followed by the minimum and maximum repeat counts. - - -Brackets and alternation ------------------------- - -A pair of non-capturing round brackets is wrapped round each expression at -compile time, so alternation always happens in the context of brackets. - -[Note for North Americans: "bracket" to some English speakers, including -myself, can be round, square, curly, or pointy. Hence this usage rather than -"parentheses".] - -Non-capturing brackets use the opcode OP_BRA, capturing brackets use OP_CBRA. A -bracket opcode is followed by a LINK_SIZE value which gives the offset to the -next alternative OP_ALT or, if there aren't any branches, to the matching -OP_KET opcode. Each OP_ALT is followed by a LINK_SIZE value giving the offset -to the next one, or to the OP_KET opcode. For capturing brackets, the bracket -number is a count that immediately follows the offset. - -OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN -and OP_KETRMAX are used for indefinite repetitions, minimally or maximally -respectively (see below for possessive repetitions). All three are followed by -a LINK_SIZE value giving (as a positive number) the offset back to the matching -bracket opcode. - -If a subpattern is quantified such that it is permitted to match zero times, it -is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are -single-unit opcodes that tell the matcher that skipping the following -subpattern entirely is a valid match. In the case of the first two, not -skipping the pattern is also valid (greedy and non-greedy). The third is used -when a pattern has the quantifier {0,0}. It cannot be entirely discarded, -because it may be called as a subroutine from elsewhere in the pattern. - -A subpattern with an indefinite maximum repetition is replicated in the -compiled data its minimum number of times (or once with OP_BRAZERO if the -minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX -as appropriate. - -A subpattern with a bounded maximum repetition is replicated in a nested -fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO -before each replication after the minimum, so that, for example, (abc){2,5} is -compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group -has the same number. - -When a repeated subpattern has an unbounded upper limit, it is checked to see -whether it could match an empty string. If this is the case, the opcode in the -final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher -that it needs to check for matching an empty string when it hits OP_KETRMIN or -OP_KETRMAX, and if so, to break the loop. - - -Possessive brackets -------------------- - -When a repeated group (capturing or non-capturing) is marked as possessive by -the "+" notation, e.g. (abc)++, different opcodes are used. Their names all -have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCBRAPOS instead -of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum -repetition is zero, the group is preceded by OP_BRAPOSZERO. - - -Once-only (atomic) groups -------------------------- - -These are just like other subpatterns, but they start with the opcode -OP_ONCE or OP_ONCE_NC. The former is used when there are no capturing brackets -within the atomic group; the latter when there are. The distinction is needed -for when there is a backtrack to before the group - any captures within the -group must be reset, so it is necessary to retain backtracking points inside -the group, even after it is complete, in order to do this. When there are no -captures in an atomic group, all the backtracking can be discarded when it is -complete. This is more efficient, and also uses less stack. - -The check for matching an empty string in an unbounded repeat is handled -entirely at runtime, so there are just these two opcodes for atomic groups. - - -Assertions ----------- - -Forward assertions are also just like other subpatterns, but starting with one -of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes -OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion -is OP_REVERSE, followed by a count of the number of characters to move back the -pointer in the subject string. In ASCII or UTF-32 mode, the count is also the -number of code units, but in UTF-8/16 mode each character may occupy more than -one code unit. A separate count is present in each alternative of a lookbehind -assertion, allowing them to have different (but fixed) lengths. - - -Conditional subpatterns ------------------------ - -These are like other subpatterns, but they start with the opcode OP_COND, or -OP_SCOND for one that might match an empty string in an unbounded repeat. - -If the condition is a back reference, this is stored at the start of the -subpattern using the opcode OP_CREF followed by a count containing the -reference number, provided that the reference is to a unique capturing group. -If the reference was by name and there is more than one group with that name, -OP_DNCREF is used instead. It is followed by two counts: the index in the group -names table, and the number of groups with the same name. The allows the -matcher to check if any group with the given name is set. - -If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of -group x" (coded as "(?(Rx)"), the group number is stored at the start of the -subpattern using the opcode OP_RREF (with a value of RREF_ANY (0xffff) for "the -whole pattern") or OP_DNRREF (with data as for OP_DNCREF). - -For a DEFINE condition, OP_FALSE is used (with no associated data). During -compilation, however, a DEFINE condition is coded as OP_DEFINE so that, when -the conditional group is complete, there can be a check to ensure that it -contains only one top-level branch. Once this has happened, the opcode is -changed to OP_FALSE, so the matcher never sees OP_DEFINE. - -There is a special PCRE2-specific condition of the form (VERSION[>]=x.y), which -tests the PCRE2 version number. This compiles into one of the opcodes OP_TRUE -or OP_FALSE. - -If a condition is not a back reference, recursion test, DEFINE, or VERSION, it -must start with an assertion, whose opcode normally immediately follows OP_COND -or OP_SCOND. However, if automatic callouts are enabled, a callout is inserted -immediately before the assertion. It is also possible to insert a manual -callout at this point. Only assertion conditions may have callouts preceding -the condition. - -A condition that is the negative assertion (?!) is optimized to OP_FAIL in all -parts of the pattern, so this is another opcode that may appear as a condition. -It is treated the same as OP_FALSE. - - -Recursion ---------- - -Recursion either matches the current pattern, or some subexpression. The opcode -OP_RECURSE is followed by a LINK_SIZE value that is the offset to the starting -bracket from the start of the whole pattern. OP_RECURSE is also used for -"subroutine" calls, even though they are not strictly a recursion. Repeated -recursions are automatically wrapped inside OP_ONCE brackets, because otherwise -some patterns broke them. A non-repeated recursion is not wrapped in OP_ONCE -brackets, but it is nevertheless still treated as an atomic group. - - -Callout -------- - -A callout can nowadays have either a numerical argument or a string argument. -These use OP_CALLOUT or OP_CALLOUT_STR, respectively. In each case these are -followed by two LINK_SIZE values giving the offset in the pattern string to the -start of the following item, and another count giving the length of this item. -These values make it possible for pcre2test to output useful tracing -information using callouts. - -In the case of a numeric callout, after these two values there is a single code -unit containing the callout number, in the range 0-255, with 255 being used for -callouts that are automatically inserted as a result of the PCRE2_AUTO_CALLOUT -option. Thus, this opcode item is of fixed length: - - [OP_CALLOUT] [PATTERN_OFFSET] [PATTERN_LENGTH] [NUMBER] - -For callouts with string arguments, OP_CALLOUT_STR has three more data items: -a LINK_SIZE value giving the complete length of the entire opcode item, a -LINK_SIZE item containing the offset within the pattern string to the start of -the string argument, and the string itself, preceded by its starting delimiter -and followed by a binary zero. When a callout function is called, a pointer to -the actual string is passed, but the delimiter can be accessed as string[-1] if -the application needs it. In the 8-bit library, the callout in /X(?C'abc')Y/ is -compiled as the following bytes (decimal numbers represent binary values): - - [OP_CALLOUT] [0] [10] [0] [1] [0] [14] [0] [5] ['] [a] [b] [c] [0] - -------- ------- -------- ------- - | | | | - ------- LINK_SIZE items ------ - -Opcode table checking ---------------------- - -The last opcode that is defined in pcre2_internal.h is OP_TABLE_LENGTH. This is -not a real opcode, but is used to check that tables indexed by opcode are the -correct length, in order to catch updating errors. - -Philip Hazel -June 2015 diff --git a/pcre2/INSTALL b/pcre2/INSTALL deleted file mode 100644 index 209984075..000000000 --- a/pcre2/INSTALL +++ /dev/null @@ -1,370 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell command `./configure && make && make install' -should configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: - - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. diff --git a/pcre2/LICENCE b/pcre2/LICENCE deleted file mode 100644 index 6600a6590..000000000 --- a/pcre2/LICENCE +++ /dev/null @@ -1,83 +0,0 @@ -PCRE2 LICENCE -------------- - -PCRE2 is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - -Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as -specified below. The documentation for PCRE2, supplied in the "doc" -directory, is distributed under the same terms as the software itself. The data -in the testdata directory is not copyrighted and is in the public domain. - -The basic library functions are written in C and are freestanding. Also -included in the distribution is a just-in-time compiler that can be used to -optimize pattern matching. This is an optional feature that can be omitted when -the library is built. - - -THE BASIC LIBRARY FUNCTIONS ---------------------------- - -Written by: Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk - -University of Cambridge Computing Service, -Cambridge, England. - -Copyright (c) 1997-2016 University of Cambridge -All rights reserved. - - -PCRE2 JUST-IN-TIME COMPILATION SUPPORT --------------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2010-2016 Zoltan Herczeg -All rights reserved. - - -STACK-LESS JUST-IN-TIME COMPILER --------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2009-2016 Zoltan Herczeg -All rights reserved. - - -THE "BSD" LICENCE ------------------ - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of any - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -End diff --git a/pcre2/Makefile.am b/pcre2/Makefile.am deleted file mode 100644 index 5977ba06b..000000000 --- a/pcre2/Makefile.am +++ /dev/null @@ -1,796 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -AUTOMAKE_OPTIONS = subdir-objects -ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src - -## Specify the documentation files that are distributed. - -dist_doc_DATA = \ - AUTHORS \ - COPYING \ - ChangeLog \ - LICENCE \ - NEWS \ - README \ - doc/pcre2.txt \ - doc/pcre2-config.txt \ - doc/pcre2grep.txt \ - doc/pcre2test.txt - -dist_html_DATA = \ - doc/html/NON-AUTOTOOLS-BUILD.txt \ - doc/html/README.txt \ - doc/html/index.html \ - doc/html/pcre2-config.html \ - doc/html/pcre2.html \ - doc/html/pcre2_callout_enumerate.html \ - doc/html/pcre2_code_free.html \ - doc/html/pcre2_compile.html \ - doc/html/pcre2_compile_context_copy.html \ - doc/html/pcre2_compile_context_create.html \ - doc/html/pcre2_compile_context_free.html \ - doc/html/pcre2_config.html \ - doc/html/pcre2_dfa_match.html \ - doc/html/pcre2_general_context_copy.html \ - doc/html/pcre2_general_context_create.html \ - doc/html/pcre2_general_context_free.html \ - doc/html/pcre2_get_error_message.html \ - doc/html/pcre2_get_mark.html \ - doc/html/pcre2_get_ovector_count.html \ - doc/html/pcre2_get_ovector_pointer.html \ - doc/html/pcre2_get_startchar.html \ - doc/html/pcre2_jit_compile.html \ - doc/html/pcre2_jit_free_unused_memory.html \ - doc/html/pcre2_jit_match.html \ - doc/html/pcre2_jit_stack_assign.html \ - doc/html/pcre2_jit_stack_create.html \ - doc/html/pcre2_jit_stack_free.html \ - doc/html/pcre2_maketables.html \ - doc/html/pcre2_match.html \ - doc/html/pcre2_match_context_copy.html \ - doc/html/pcre2_match_context_create.html \ - doc/html/pcre2_match_context_free.html \ - doc/html/pcre2_match_data_create.html \ - doc/html/pcre2_match_data_create_from_pattern.html \ - doc/html/pcre2_match_data_free.html \ - doc/html/pcre2_pattern_info.html \ - doc/html/pcre2_serialize_decode.html \ - doc/html/pcre2_serialize_encode.html \ - doc/html/pcre2_serialize_free.html \ - doc/html/pcre2_serialize_get_number_of_codes.html \ - doc/html/pcre2_set_bsr.html \ - doc/html/pcre2_set_callout.html \ - doc/html/pcre2_set_character_tables.html \ - doc/html/pcre2_set_compile_recursion_guard.html \ - doc/html/pcre2_set_match_limit.html \ - doc/html/pcre2_set_offset_limit.html \ - doc/html/pcre2_set_newline.html \ - doc/html/pcre2_set_parens_nest_limit.html \ - doc/html/pcre2_set_recursion_limit.html \ - doc/html/pcre2_set_recursion_memory_management.html \ - doc/html/pcre2_substitute.html \ - doc/html/pcre2_substring_copy_byname.html \ - doc/html/pcre2_substring_copy_bynumber.html \ - doc/html/pcre2_substring_free.html \ - doc/html/pcre2_substring_get_byname.html \ - doc/html/pcre2_substring_get_bynumber.html \ - doc/html/pcre2_substring_length_byname.html \ - doc/html/pcre2_substring_length_bynumber.html \ - doc/html/pcre2_substring_list_free.html \ - doc/html/pcre2_substring_list_get.html \ - doc/html/pcre2_substring_nametable_scan.html \ - doc/html/pcre2_substring_number_from_name.html \ - doc/html/pcre2api.html \ - doc/html/pcre2build.html \ - doc/html/pcre2callout.html \ - doc/html/pcre2compat.html \ - doc/html/pcre2demo.html \ - doc/html/pcre2grep.html \ - doc/html/pcre2jit.html \ - doc/html/pcre2limits.html \ - doc/html/pcre2matching.html \ - doc/html/pcre2partial.html \ - doc/html/pcre2pattern.html \ - doc/html/pcre2perform.html \ - doc/html/pcre2posix.html \ - doc/html/pcre2sample.html \ - doc/html/pcre2serialize.html \ - doc/html/pcre2stack.html \ - doc/html/pcre2syntax.html \ - doc/html/pcre2test.html \ - doc/html/pcre2unicode.html - -dist_man_MANS = \ - doc/pcre2-config.1 \ - doc/pcre2.3 \ - doc/pcre2_callout_enumerate.3 \ - doc/pcre2_code_free.3 \ - doc/pcre2_compile.3 \ - doc/pcre2_compile_context_copy.3 \ - doc/pcre2_compile_context_create.3 \ - doc/pcre2_compile_context_free.3 \ - doc/pcre2_config.3 \ - doc/pcre2_dfa_match.3 \ - doc/pcre2_general_context_copy.3 \ - doc/pcre2_general_context_create.3 \ - doc/pcre2_general_context_free.3 \ - doc/pcre2_get_error_message.3 \ - doc/pcre2_get_mark.3 \ - doc/pcre2_get_ovector_count.3 \ - doc/pcre2_get_ovector_pointer.3 \ - doc/pcre2_get_startchar.3 \ - doc/pcre2_jit_compile.3 \ - doc/pcre2_jit_free_unused_memory.3 \ - doc/pcre2_jit_match.3 \ - doc/pcre2_jit_stack_assign.3 \ - doc/pcre2_jit_stack_create.3 \ - doc/pcre2_jit_stack_free.3 \ - doc/pcre2_maketables.3 \ - doc/pcre2_match.3 \ - doc/pcre2_match_context_copy.3 \ - doc/pcre2_match_context_create.3 \ - doc/pcre2_match_context_free.3 \ - doc/pcre2_match_data_create.3 \ - doc/pcre2_match_data_create_from_pattern.3 \ - doc/pcre2_match_data_free.3 \ - doc/pcre2_pattern_info.3 \ - doc/pcre2_serialize_decode.3 \ - doc/pcre2_serialize_encode.3 \ - doc/pcre2_serialize_free.3 \ - doc/pcre2_serialize_get_number_of_codes.3 \ - doc/pcre2_set_bsr.3 \ - doc/pcre2_set_callout.3 \ - doc/pcre2_set_character_tables.3 \ - doc/pcre2_set_compile_recursion_guard.3 \ - doc/pcre2_set_match_limit.3 \ - doc/pcre2_set_offset_limit.3 \ - doc/pcre2_set_newline.3 \ - doc/pcre2_set_parens_nest_limit.3 \ - doc/pcre2_set_recursion_limit.3 \ - doc/pcre2_set_recursion_memory_management.3 \ - doc/pcre2_substitute.3 \ - doc/pcre2_substring_copy_byname.3 \ - doc/pcre2_substring_copy_bynumber.3 \ - doc/pcre2_substring_free.3 \ - doc/pcre2_substring_get_byname.3 \ - doc/pcre2_substring_get_bynumber.3 \ - doc/pcre2_substring_length_byname.3 \ - doc/pcre2_substring_length_bynumber.3 \ - doc/pcre2_substring_list_free.3 \ - doc/pcre2_substring_list_get.3 \ - doc/pcre2_substring_nametable_scan.3 \ - doc/pcre2_substring_number_from_name.3 \ - doc/pcre2api.3 \ - doc/pcre2build.3 \ - doc/pcre2callout.3 \ - doc/pcre2compat.3 \ - doc/pcre2demo.3 \ - doc/pcre2grep.1 \ - doc/pcre2jit.3 \ - doc/pcre2limits.3 \ - doc/pcre2matching.3 \ - doc/pcre2partial.3 \ - doc/pcre2pattern.3 \ - doc/pcre2perform.3 \ - doc/pcre2posix.3 \ - doc/pcre2sample.3 \ - doc/pcre2serialize.3 \ - doc/pcre2stack.3 \ - doc/pcre2syntax.3 \ - doc/pcre2test.1 \ - doc/pcre2unicode.3 - -# The Libtool libraries to install. We'll add to this later. - -lib_LTLIBRARIES = - -# Unit tests you want to run when people type 'make check'. -# TESTS is for binary unit tests, check_SCRIPTS for script-based tests - -TESTS = -check_SCRIPTS = -dist_noinst_SCRIPTS = - -# Some of the binaries we make are to be installed, and others are -# (non-user-visible) helper programs needed to build the libraries. - -bin_PROGRAMS = -noinst_PROGRAMS = - -# Additional files to delete on 'make clean', 'make distclean', -# and 'make maintainer-clean'. - -CLEANFILES = -DISTCLEANFILES = src/config.h.in~ config.h -MAINTAINERCLEANFILES = - -# Additional files to bundle with the distribution, over and above what -# the Autotools include by default. - -EXTRA_DIST = - -# These files contain additional m4 macros that are used by autoconf. - -EXTRA_DIST += \ - m4/ax_pthread.m4 m4/pcre2_visibility.m4 - -# These files contain maintenance information - -EXTRA_DIST += \ - NON-AUTOTOOLS-BUILD \ - HACKING - -# These files are used in the preparation of a release - -EXTRA_DIST += \ - PrepareRelease \ - CheckMan \ - CleanTxt \ - Detrail \ - 132html \ - doc/index.html.src - -# These files are usable versions of pcre2.h and config.h that are distributed -# for the benefit of people who are building PCRE2 manually, without the -# Autotools support. - -EXTRA_DIST += \ - src/pcre2.h.generic \ - src/config.h.generic - -# The only difference between pcre2.h.in and pcre2.h is the setting of the PCRE -# version number. Therefore, we can create the generic version just by copying. - -src/pcre2.h.generic: src/pcre2.h.in configure.ac - rm -f $@ - cp -p src/pcre2.h $@ - -# It is more complicated for config.h.generic. We need the version that results -# from a default configuration so as to get all the default values for PCRE -# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by -# doing a configure in a temporary directory. However, some trickery is needed, -# because the source directory may already be configured. If you just try -# running configure in a new directory, it complains. For this reason, we move -# config.status out of the way while doing the default configuration. The -# resulting config.h is munged by perl to put #ifdefs round any #defines for -# macros with values, and to #undef all boolean macros such as HAVE_xxx and -# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make -# sure that PCRE2_EXP_DEFN is unset (in case it has visibility settings). - -src/config.h.generic: configure.ac - rm -rf $@ _generic - mkdir _generic - cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside - cd _generic && $(abs_top_srcdir)/configure || : - cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs - test -f _generic/src/config.h - perl -n \ - -e 'BEGIN{$$blank=0;}' \ - -e 'if(/PCRE2_EXP_DEFN/){print"/* #undef PCRE2_EXP_DEFN */\n";$$blank=0;next;}' \ - -e 'if(/to make a symbol visible/){next;}' \ - -e 'if(/__attribute__ \(\(visibility/){next;}' \ - -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ - -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ - -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ - -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ - _generic/src/config.h >$@ - rm -rf _generic - -MAINTAINERCLEANFILES += src/pcre2.h.generic src/config.h.generic - -# These are the header files we'll install. We do not distribute pcre2.h -# because it is generated from pcre2.h.in. - -nodist_include_HEADERS = src/pcre2.h -include_HEADERS = src/pcre2posix.h - -# This is the "config" script. - -bin_SCRIPTS = pcre2-config - -## --------------------------------------------------------------- -## The dftables program is used to rebuild character tables before compiling -## PCRE2, if --enable-rebuild-chartables is specified. It is not a user-visible -## program. The default (when --enable-rebuild-chartables is not specified) is -## to copy a distributed set of tables that are defined for ASCII code. In this -## case, dftables is not needed. - -if WITH_REBUILD_CHARTABLES -noinst_PROGRAMS += dftables -dftables_SOURCES = src/dftables.c -src/pcre2_chartables.c: dftables$(EXEEXT) - rm -f $@ - ./dftables$(EXEEXT) $@ -else -src/pcre2_chartables.c: $(srcdir)/src/pcre2_chartables.c.dist - rm -f $@ - $(LN_S) $(abs_srcdir)/src/pcre2_chartables.c.dist $(abs_builddir)/src/pcre2_chartables.c -endif # WITH_REBUILD_CHARTABLES - -BUILT_SOURCES = src/pcre2_chartables.c -NODIST_SOURCES = src/pcre2_chartables.c - -## Define the list of common sources, then arrange to build whichever of the -## 8-, 16-, or 32-bit libraries are configured. - -COMMON_SOURCES = \ - src/pcre2_auto_possess.c \ - src/pcre2_compile.c \ - src/pcre2_config.c \ - src/pcre2_context.c \ - src/pcre2_dfa_match.c \ - src/pcre2_error.c \ - src/pcre2_find_bracket.c \ - src/pcre2_internal.h \ - src/pcre2_intmodedep.h \ - src/pcre2_jit_compile.c \ - src/pcre2_maketables.c \ - src/pcre2_match.c \ - src/pcre2_match_data.c \ - src/pcre2_newline.c \ - src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c \ - src/pcre2_serialize.c \ - src/pcre2_string_utils.c \ - src/pcre2_study.c \ - src/pcre2_substitute.c \ - src/pcre2_substring.c \ - src/pcre2_tables.c \ - src/pcre2_ucd.c \ - src/pcre2_ucp.h \ - src/pcre2_valid_utf.c \ - src/pcre2_xclass.c - -if WITH_PCRE2_8 -lib_LTLIBRARIES += libpcre2-8.la -libpcre2_8_la_SOURCES = \ - $(COMMON_SOURCES) -nodist_libpcre2_8_la_SOURCES = \ - $(NODIST_SOURCES) -libpcre2_8_la_CFLAGS = \ - -DPCRE2_CODE_UNIT_WIDTH=8 \ - $(VISIBILITY_CFLAGS) \ - $(AM_CFLAGS) -libpcre2_8_la_LIBADD = -endif # WITH_PCRE2_8 - -if WITH_PCRE2_16 -lib_LTLIBRARIES += libpcre2-16.la -libpcre2_16_la_SOURCES = \ - $(COMMON_SOURCES) -nodist_libpcre2_16_la_SOURCES = \ - $(NODIST_SOURCES) -libpcre2_16_la_CFLAGS = \ - -DPCRE2_CODE_UNIT_WIDTH=16 \ - $(VISIBILITY_CFLAGS) \ - $(AM_CFLAGS) -libpcre2_16_la_LIBADD = -endif # WITH_PCRE2_16 - -if WITH_PCRE2_32 -lib_LTLIBRARIES += libpcre2-32.la -libpcre2_32_la_SOURCES = \ - $(COMMON_SOURCES) -nodist_libpcre2_32_la_SOURCES = \ - $(NODIST_SOURCES) -libpcre2_32_la_CFLAGS = \ - -DPCRE2_CODE_UNIT_WIDTH=32 \ - $(VISIBILITY_CFLAGS) \ - $(AM_CFLAGS) -libpcre2_32_la_LIBADD = -endif # WITH_PCRE2_32 - -# The pcre2_chartables.c.dist file is the default version of -# pcre2_chartables.c, used unless --enable-rebuild-chartables is specified. - -EXTRA_DIST += src/pcre2_chartables.c.dist -CLEANFILES += src/pcre2_chartables.c - -# The JIT compiler lives in a separate directory, but its files are #included -# when pcre2_jit_compile.c is processed, so they must be distributed. - -EXTRA_DIST += \ - src/sljit/sljitConfig.h \ - src/sljit/sljitConfigInternal.h \ - src/sljit/sljitExecAllocator.c \ - src/sljit/sljitLir.c \ - src/sljit/sljitLir.h \ - src/sljit/sljitNativeARM_32.c \ - src/sljit/sljitNativeARM_64.c \ - src/sljit/sljitNativeARM_T2_32.c \ - src/sljit/sljitNativeMIPS_32.c \ - src/sljit/sljitNativeMIPS_64.c \ - src/sljit/sljitNativeMIPS_common.c \ - src/sljit/sljitNativePPC_32.c \ - src/sljit/sljitNativePPC_64.c \ - src/sljit/sljitNativePPC_common.c \ - src/sljit/sljitNativeSPARC_32.c \ - src/sljit/sljitNativeSPARC_common.c \ - src/sljit/sljitNativeTILEGX-encoder.c \ - src/sljit/sljitNativeTILEGX_64.c \ - src/sljit/sljitNativeX86_32.c \ - src/sljit/sljitNativeX86_64.c \ - src/sljit/sljitNativeX86_common.c \ - src/sljit/sljitUtils.c - -# Some of the JIT sources are also in separate files that are #included. - -EXTRA_DIST += \ - src/pcre2_jit_match.c \ - src/pcre2_jit_misc.c - -if WITH_PCRE2_8 -libpcre2_8_la_LDFLAGS = $(EXTRA_LIBPCRE2_8_LDFLAGS) -endif # WITH_PCRE2_8 -if WITH_PCRE2_16 -libpcre2_16_la_LDFLAGS = $(EXTRA_LIBPCRE2_16_LDFLAGS) -endif # WITH_PCRE2_16 -if WITH_PCRE2_32 -libpcre2_32_la_LDFLAGS = $(EXTRA_LIBPCRE2_32_LDFLAGS) -endif # WITH_PCRE2_32 - -if WITH_VALGRIND -if WITH_PCRE2_8 -libpcre2_8_la_CFLAGS += $(VALGRIND_CFLAGS) -endif # WITH_PCRE2_8 -if WITH_PCRE2_16 -libpcre2_16_la_CFLAGS += $(VALGRIND_CFLAGS) -endif # WITH_PCRE2_16 -if WITH_PCRE2_32 -libpcre2_32_la_CFLAGS += $(VALGRIND_CFLAGS) -endif # WITH_PCRE2_32 -endif # WITH_VALGRIND - -if WITH_GCOV -if WITH_PCRE2_8 -libpcre2_8_la_CFLAGS += $(GCOV_CFLAGS) -endif # WITH_PCRE2_8 -if WITH_PCRE2_16 -libpcre2_16_la_CFLAGS += $(GCOV_CFLAGS) -endif # WITH_PCRE2_16 -if WITH_PCRE2_32 -libpcre2_32_la_CFLAGS += $(GCOV_CFLAGS) -endif # WITH_PCRE2_32 -endif # WITH_GCOV - -## A version of the 8-bit library that has a POSIX API. - -if WITH_PCRE2_8 -lib_LTLIBRARIES += libpcre2-posix.la -libpcre2_posix_la_SOURCES = src/pcre2posix.c -libpcre2_posix_la_CFLAGS = \ - -DPCRE2_CODE_UNIT_WIDTH=8 \ - $(VISIBILITY_CFLAGS) $(AM_CFLAGS) -libpcre2_posix_la_LDFLAGS = $(EXTRA_LIBPCRE2_POSIX_LDFLAGS) -libpcre2_posix_la_LIBADD = libpcre2-8.la -if WITH_GCOV -libpcre2_posix_la_CFLAGS += $(GCOV_CFLAGS) -endif # WITH_GCOV -endif # WITH_PCRE2_8 - -## Build pcre2grep if the 8-bit library is enabled - -if WITH_PCRE2_8 -bin_PROGRAMS += pcre2grep -pcre2grep_SOURCES = src/pcre2grep.c -pcre2grep_CFLAGS = $(AM_CFLAGS) -pcre2grep_LDADD = $(LIBZ) $(LIBBZ2) -pcre2grep_LDADD += libpcre2-8.la -if WITH_GCOV -pcre2grep_CFLAGS += $(GCOV_CFLAGS) -pcre2grep_LDADD += $(GCOV_LIBS) -endif # WITH_GCOV -endif # WITH_PCRE2_8 - -## -------- Testing ---------- - -## If JIT support is enabled, arrange for the JIT test program to run. - -if WITH_JIT -TESTS += pcre2_jit_test -noinst_PROGRAMS += pcre2_jit_test -pcre2_jit_test_SOURCES = src/pcre2_jit_test.c -pcre2_jit_test_CFLAGS = $(AM_CFLAGS) -pcre2_jit_test_LDADD = -if WITH_PCRE2_8 -pcre2_jit_test_LDADD += libpcre2-8.la -endif # WITH_PCRE2_8 -if WITH_PCRE2_16 -pcre2_jit_test_LDADD += libpcre2-16.la -endif # WITH_PCRE2_16 -if WITH_PCRE2_32 -pcre2_jit_test_LDADD += libpcre2-32.la -endif # WITH_PCRE2_32 -if WITH_GCOV -pcre2_jit_test_CFLAGS += $(GCOV_CFLAGS) -pcre2_jit_test_LDADD += $(GCOV_LIBS) -endif # WITH_GCOV -endif # WITH_JIT - -# Build the general pcre2test program. The file src/pcre2_printint.c is -# #included by pcre2test as many times as needed, at different code unit -# widths. - -bin_PROGRAMS += pcre2test -EXTRA_DIST += src/pcre2_printint.c -pcre2test_SOURCES = src/pcre2test.c -pcre2test_CFLAGS = $(AM_CFLAGS) -pcre2test_LDADD = $(LIBREADLINE) - -if WITH_PCRE2_8 -pcre2test_LDADD += libpcre2-8.la libpcre2-posix.la -endif # WITH_PCRE2_8 - -if WITH_PCRE2_16 -pcre2test_LDADD += libpcre2-16.la -endif # WITH_PCRE2_16 - -if WITH_PCRE2_32 -pcre2test_LDADD += libpcre2-32.la -endif # WITH_PCRE2_32 - -if WITH_VALGRIND -pcre2test_CFLAGS += $(VALGRIND_CFLAGS) -endif # WITH_VALGRIND - -if WITH_GCOV -pcre2test_CFLAGS += $(GCOV_CFLAGS) -pcre2test_LDADD += $(GCOV_LIBS) -endif # WITH_GCOV - -## The main library tests. Each test is a binary plus a script that runs that -## binary in various ways. We install these test binaries in case folks find it -## helpful. - -TESTS += RunTest -dist_noinst_SCRIPTS += RunTest - -EXTRA_DIST += RunTest.bat - -## When the 8-bit library is configured, pcre2grep will have been built. - -if WITH_PCRE2_8 -TESTS += RunGrepTest -dist_noinst_SCRIPTS += RunGrepTest -endif # WITH_PCRE2_8 - -## Distribute all the test data files - -EXTRA_DIST += \ - testdata/grepbinary \ - testdata/grepfilelist \ - testdata/grepinput \ - testdata/grepinput3 \ - testdata/grepinput8 \ - testdata/grepinputv \ - testdata/grepinputx \ - testdata/greplist \ - testdata/grepoutput \ - testdata/grepoutput8 \ - testdata/grepoutputN \ - testdata/greppatN4 \ - testdata/testinput1 \ - testdata/testinput2 \ - testdata/testinput3 \ - testdata/testinput4 \ - testdata/testinput5 \ - testdata/testinput6 \ - testdata/testinput7 \ - testdata/testinput8 \ - testdata/testinput9 \ - testdata/testinput10 \ - testdata/testinput11 \ - testdata/testinput12 \ - testdata/testinput13 \ - testdata/testinput14 \ - testdata/testinput15 \ - testdata/testinput16 \ - testdata/testinput17 \ - testdata/testinput18 \ - testdata/testinput19 \ - testdata/testinput20 \ - testdata/testinput21 \ - testdata/testinput22 \ - testdata/testinput23 \ - testdata/testinputEBC \ - testdata/testoutput1 \ - testdata/testoutput2 \ - testdata/testoutput3 \ - testdata/testoutput3A \ - testdata/testoutput3B \ - testdata/testoutput4 \ - testdata/testoutput5 \ - testdata/testoutput6 \ - testdata/testoutput7 \ - testdata/testoutput8-16-2 \ - testdata/testoutput8-16-3 \ - testdata/testoutput8-16-3 \ - testdata/testoutput8-32-2 \ - testdata/testoutput8-32-3 \ - testdata/testoutput8-32-4 \ - testdata/testoutput8-8-2 \ - testdata/testoutput8-8-3 \ - testdata/testoutput8-8-4 \ - testdata/testoutput9 \ - testdata/testoutput10 \ - testdata/testoutput11-16 \ - testdata/testoutput11-32 \ - testdata/testoutput12-16 \ - testdata/testoutput12-32 \ - testdata/testoutput13 \ - testdata/testoutput14-16 \ - testdata/testoutput14-32 \ - testdata/testoutput14-8 \ - testdata/testoutput15 \ - testdata/testoutput16 \ - testdata/testoutput17 \ - testdata/testoutput18 \ - testdata/testoutput19 \ - testdata/testoutput20 \ - testdata/testoutput21 \ - testdata/testoutput22-16 \ - testdata/testoutput22-32 \ - testdata/testoutput22-8 \ - testdata/testoutput23 \ - testdata/testoutputEBC \ - testdata/valgrind-jit.supp \ - testdata/wintestinput3 \ - testdata/wintestoutput3 \ - perltest.sh - -# RunTest and RunGrepTest should clean up after themselves, but just in case -# they don't, add their working files to CLEANFILES. - -CLEANFILES += \ - testSinput \ - test3input \ - test3output \ - test3outputA \ - test3outputB \ - testtry \ - teststdout \ - teststderr \ - teststderrgrep \ - testtemp1grep \ - testtemp2grep \ - testtrygrep \ - testNinputgrep - -## ------------ End of testing ------------- - - -# PCRE2 demonstration program. Not built automatcally. The point is that the -# users should build it themselves. So just distribute the source. - -EXTRA_DIST += src/pcre2demo.c - - -# We have .pc files for pkg-config users. - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = - -if WITH_PCRE2_8 -pkgconfig_DATA += libpcre2-8.pc libpcre2-posix.pc -endif - -if WITH_PCRE2_16 -pkgconfig_DATA += libpcre2-16.pc -endif - -if WITH_PCRE2_32 -pkgconfig_DATA += libpcre2-32.pc -endif - - -# gcov/lcov code coverage reporting -# -# Coverage reporting targets: -# -# coverage: Create a coverage report from 'make check' -# coverage-baseline: Capture baseline coverage information -# coverage-reset: This zeros the coverage counters only -# coverage-report: This creates the coverage report only -# coverage-clean-report: This removes the generated coverage report -# without cleaning the coverage data itself -# coverage-clean-data: This removes the captured coverage data without -# removing the coverage files created at compile time (*.gcno) -# coverage-clean: This cleans all coverage data including the generated -# coverage report. - -if WITH_GCOV -COVERAGE_TEST_NAME = $(PACKAGE) -COVERAGE_NAME = $(PACKAGE)-$(VERSION) -COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info -COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage -COVERAGE_LCOV_EXTRA_FLAGS = -COVERAGE_GENHTML_EXTRA_FLAGS = - -coverage_quiet = $(coverage_quiet_$(V)) -coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -coverage_quiet_0 = --quiet - -coverage-check: all - -$(MAKE) $(AM_MAKEFLAGS) -k check - -coverage-baseline: - $(LCOV) $(coverage_quiet) \ - --directory $(top_builddir) \ - --output-file "$(COVERAGE_OUTPUT_FILE)" \ - --capture \ - --initial - -coverage-report: - $(LCOV) $(coverage_quiet) \ - --directory $(top_builddir) \ - --capture \ - --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ - --test-name "$(COVERAGE_TEST_NAME)" \ - --no-checksum \ - --compat-libtool \ - $(COVERAGE_LCOV_EXTRA_FLAGS) - $(LCOV) $(coverage_quiet) \ - --directory $(top_builddir) \ - --output-file "$(COVERAGE_OUTPUT_FILE)" \ - --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ - "/tmp/*" \ - "/usr/include/*" \ - "$(includedir)/*" - -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" - LANG=C $(GENHTML) $(coverage_quiet) \ - --prefix $(top_builddir) \ - --output-directory "$(COVERAGE_OUTPUT_DIR)" \ - --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ - --show-details "$(COVERAGE_OUTPUT_FILE)" \ - --legend \ - $(COVERAGE_GENHTML_EXTRA_FLAGS) - @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" - -coverage-reset: - -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) - -coverage-clean-report: - -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" - -rm -rf "$(COVERAGE_OUTPUT_DIR)" - -coverage-clean-data: - -find $(top_builddir) -name "*.gcda" -delete - -coverage-clean: coverage-reset coverage-clean-report coverage-clean-data - -find $(top_builddir) -name "*.gcno" -delete - -coverage-distclean: coverage-clean - -coverage: coverage-reset coverage-baseline coverage-check coverage-report -clean-local: coverage-clean -distclean-local: coverage-distclean - -.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean - -# Without coverage support, still arrange for 'make distclean' to get rid of -# any coverage files that may have been left from a different configuration. - -else - -coverage: - @echo "Configuring with --enable-coverage is required to generate code coverage report." - -DISTCLEANFILES += src/*.gcda src/*.gcno - -distclean-local: - rm -rf $(PACKAGE)-$(VERSION)-coverage* - -endif # WITH_GCOV - -## CMake support - -EXTRA_DIST += \ - cmake/COPYING-CMAKE-SCRIPTS \ - cmake/FindPackageHandleStandardArgs.cmake \ - cmake/FindReadline.cmake \ - cmake/FindEditline.cmake \ - CMakeLists.txt \ - config-cmake.h.in - -## end Makefile.am diff --git a/pcre2/Makefile.in b/pcre2/Makefile.in deleted file mode 100644 index fd07c58cb..000000000 --- a/pcre2/Makefile.in +++ /dev/null @@ -1,3136 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -TESTS = $(am__EXEEXT_3) RunTest $(am__append_29) -bin_PROGRAMS = $(am__EXEEXT_1) pcre2test$(EXEEXT) -noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) -@WITH_REBUILD_CHARTABLES_TRUE@am__append_1 = dftables -@WITH_PCRE2_8_TRUE@am__append_2 = libpcre2-8.la -@WITH_PCRE2_16_TRUE@am__append_3 = libpcre2-16.la -@WITH_PCRE2_32_TRUE@am__append_4 = libpcre2-32.la -@WITH_PCRE2_8_TRUE@@WITH_VALGRIND_TRUE@am__append_5 = $(VALGRIND_CFLAGS) -@WITH_PCRE2_16_TRUE@@WITH_VALGRIND_TRUE@am__append_6 = $(VALGRIND_CFLAGS) -@WITH_PCRE2_32_TRUE@@WITH_VALGRIND_TRUE@am__append_7 = $(VALGRIND_CFLAGS) -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_8 = $(GCOV_CFLAGS) -@WITH_GCOV_TRUE@@WITH_PCRE2_16_TRUE@am__append_9 = $(GCOV_CFLAGS) -@WITH_GCOV_TRUE@@WITH_PCRE2_32_TRUE@am__append_10 = $(GCOV_CFLAGS) -@WITH_PCRE2_8_TRUE@am__append_11 = libpcre2-posix.la -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_12 = $(GCOV_CFLAGS) -@WITH_PCRE2_8_TRUE@am__append_13 = pcre2grep -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_14 = $(GCOV_CFLAGS) -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_15 = $(GCOV_LIBS) -@WITH_JIT_TRUE@am__append_16 = pcre2_jit_test -@WITH_JIT_TRUE@am__append_17 = pcre2_jit_test -@WITH_JIT_TRUE@@WITH_PCRE2_8_TRUE@am__append_18 = libpcre2-8.la -@WITH_JIT_TRUE@@WITH_PCRE2_16_TRUE@am__append_19 = libpcre2-16.la -@WITH_JIT_TRUE@@WITH_PCRE2_32_TRUE@am__append_20 = libpcre2-32.la -@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_21 = $(GCOV_CFLAGS) -@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_22 = $(GCOV_LIBS) -@WITH_PCRE2_8_TRUE@am__append_23 = libpcre2-8.la libpcre2-posix.la -@WITH_PCRE2_16_TRUE@am__append_24 = libpcre2-16.la -@WITH_PCRE2_32_TRUE@am__append_25 = libpcre2-32.la -@WITH_VALGRIND_TRUE@am__append_26 = $(VALGRIND_CFLAGS) -@WITH_GCOV_TRUE@am__append_27 = $(GCOV_CFLAGS) -@WITH_GCOV_TRUE@am__append_28 = $(GCOV_LIBS) -@WITH_PCRE2_8_TRUE@am__append_29 = RunGrepTest -@WITH_PCRE2_8_TRUE@am__append_30 = RunGrepTest -@WITH_PCRE2_8_TRUE@am__append_31 = libpcre2-8.pc libpcre2-posix.pc -@WITH_PCRE2_16_TRUE@am__append_32 = libpcre2-16.pc -@WITH_PCRE2_32_TRUE@am__append_33 = libpcre2-32.pc -@WITH_GCOV_FALSE@am__append_34 = src/*.gcda src/*.gcno -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/pcre2_visibility.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__dist_noinst_SCRIPTS_DIST) \ - $(dist_doc_DATA) $(dist_html_DATA) $(include_HEADERS) \ - $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc \ - libpcre2-posix.pc pcre2-config src/pcre2.h -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libpcre2_16_la_DEPENDENCIES = -am__libpcre2_16_la_SOURCES_DIST = src/pcre2_auto_possess.c \ - src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ - src/pcre2_dfa_match.c src/pcre2_error.c \ - src/pcre2_find_bracket.c src/pcre2_internal.h \ - src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ - src/pcre2_maketables.c src/pcre2_match.c \ - src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c src/pcre2_serialize.c \ - src/pcre2_string_utils.c src/pcre2_study.c \ - src/pcre2_substitute.c src/pcre2_substring.c \ - src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ - src/pcre2_valid_utf.c src/pcre2_xclass.c -am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = src/libpcre2_16_la-pcre2_auto_possess.lo \ - src/libpcre2_16_la-pcre2_compile.lo \ - src/libpcre2_16_la-pcre2_config.lo \ - src/libpcre2_16_la-pcre2_context.lo \ - src/libpcre2_16_la-pcre2_dfa_match.lo \ - src/libpcre2_16_la-pcre2_error.lo \ - src/libpcre2_16_la-pcre2_find_bracket.lo \ - src/libpcre2_16_la-pcre2_jit_compile.lo \ - src/libpcre2_16_la-pcre2_maketables.lo \ - src/libpcre2_16_la-pcre2_match.lo \ - src/libpcre2_16_la-pcre2_match_data.lo \ - src/libpcre2_16_la-pcre2_newline.lo \ - src/libpcre2_16_la-pcre2_ord2utf.lo \ - src/libpcre2_16_la-pcre2_pattern_info.lo \ - src/libpcre2_16_la-pcre2_serialize.lo \ - src/libpcre2_16_la-pcre2_string_utils.lo \ - src/libpcre2_16_la-pcre2_study.lo \ - src/libpcre2_16_la-pcre2_substitute.lo \ - src/libpcre2_16_la-pcre2_substring.lo \ - src/libpcre2_16_la-pcre2_tables.lo \ - src/libpcre2_16_la-pcre2_ucd.lo \ - src/libpcre2_16_la-pcre2_valid_utf.lo \ - src/libpcre2_16_la-pcre2_xclass.lo -@WITH_PCRE2_16_TRUE@am_libpcre2_16_la_OBJECTS = $(am__objects_1) -am__objects_2 = src/libpcre2_16_la-pcre2_chartables.lo -@WITH_PCRE2_16_TRUE@nodist_libpcre2_16_la_OBJECTS = $(am__objects_2) -libpcre2_16_la_OBJECTS = $(am_libpcre2_16_la_OBJECTS) \ - $(nodist_libpcre2_16_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libpcre2_16_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libpcre2_16_la_CFLAGS) $(CFLAGS) $(libpcre2_16_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -@WITH_PCRE2_16_TRUE@am_libpcre2_16_la_rpath = -rpath $(libdir) -libpcre2_32_la_DEPENDENCIES = -am__libpcre2_32_la_SOURCES_DIST = src/pcre2_auto_possess.c \ - src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ - src/pcre2_dfa_match.c src/pcre2_error.c \ - src/pcre2_find_bracket.c src/pcre2_internal.h \ - src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ - src/pcre2_maketables.c src/pcre2_match.c \ - src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c src/pcre2_serialize.c \ - src/pcre2_string_utils.c src/pcre2_study.c \ - src/pcre2_substitute.c src/pcre2_substring.c \ - src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ - src/pcre2_valid_utf.c src/pcre2_xclass.c -am__objects_3 = src/libpcre2_32_la-pcre2_auto_possess.lo \ - src/libpcre2_32_la-pcre2_compile.lo \ - src/libpcre2_32_la-pcre2_config.lo \ - src/libpcre2_32_la-pcre2_context.lo \ - src/libpcre2_32_la-pcre2_dfa_match.lo \ - src/libpcre2_32_la-pcre2_error.lo \ - src/libpcre2_32_la-pcre2_find_bracket.lo \ - src/libpcre2_32_la-pcre2_jit_compile.lo \ - src/libpcre2_32_la-pcre2_maketables.lo \ - src/libpcre2_32_la-pcre2_match.lo \ - src/libpcre2_32_la-pcre2_match_data.lo \ - src/libpcre2_32_la-pcre2_newline.lo \ - src/libpcre2_32_la-pcre2_ord2utf.lo \ - src/libpcre2_32_la-pcre2_pattern_info.lo \ - src/libpcre2_32_la-pcre2_serialize.lo \ - src/libpcre2_32_la-pcre2_string_utils.lo \ - src/libpcre2_32_la-pcre2_study.lo \ - src/libpcre2_32_la-pcre2_substitute.lo \ - src/libpcre2_32_la-pcre2_substring.lo \ - src/libpcre2_32_la-pcre2_tables.lo \ - src/libpcre2_32_la-pcre2_ucd.lo \ - src/libpcre2_32_la-pcre2_valid_utf.lo \ - src/libpcre2_32_la-pcre2_xclass.lo -@WITH_PCRE2_32_TRUE@am_libpcre2_32_la_OBJECTS = $(am__objects_3) -am__objects_4 = src/libpcre2_32_la-pcre2_chartables.lo -@WITH_PCRE2_32_TRUE@nodist_libpcre2_32_la_OBJECTS = $(am__objects_4) -libpcre2_32_la_OBJECTS = $(am_libpcre2_32_la_OBJECTS) \ - $(nodist_libpcre2_32_la_OBJECTS) -libpcre2_32_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libpcre2_32_la_CFLAGS) $(CFLAGS) $(libpcre2_32_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -@WITH_PCRE2_32_TRUE@am_libpcre2_32_la_rpath = -rpath $(libdir) -libpcre2_8_la_DEPENDENCIES = -am__libpcre2_8_la_SOURCES_DIST = src/pcre2_auto_possess.c \ - src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \ - src/pcre2_dfa_match.c src/pcre2_error.c \ - src/pcre2_find_bracket.c src/pcre2_internal.h \ - src/pcre2_intmodedep.h src/pcre2_jit_compile.c \ - src/pcre2_maketables.c src/pcre2_match.c \ - src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c src/pcre2_serialize.c \ - src/pcre2_string_utils.c src/pcre2_study.c \ - src/pcre2_substitute.c src/pcre2_substring.c \ - src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \ - src/pcre2_valid_utf.c src/pcre2_xclass.c -am__objects_5 = src/libpcre2_8_la-pcre2_auto_possess.lo \ - src/libpcre2_8_la-pcre2_compile.lo \ - src/libpcre2_8_la-pcre2_config.lo \ - src/libpcre2_8_la-pcre2_context.lo \ - src/libpcre2_8_la-pcre2_dfa_match.lo \ - src/libpcre2_8_la-pcre2_error.lo \ - src/libpcre2_8_la-pcre2_find_bracket.lo \ - src/libpcre2_8_la-pcre2_jit_compile.lo \ - src/libpcre2_8_la-pcre2_maketables.lo \ - src/libpcre2_8_la-pcre2_match.lo \ - src/libpcre2_8_la-pcre2_match_data.lo \ - src/libpcre2_8_la-pcre2_newline.lo \ - src/libpcre2_8_la-pcre2_ord2utf.lo \ - src/libpcre2_8_la-pcre2_pattern_info.lo \ - src/libpcre2_8_la-pcre2_serialize.lo \ - src/libpcre2_8_la-pcre2_string_utils.lo \ - src/libpcre2_8_la-pcre2_study.lo \ - src/libpcre2_8_la-pcre2_substitute.lo \ - src/libpcre2_8_la-pcre2_substring.lo \ - src/libpcre2_8_la-pcre2_tables.lo \ - src/libpcre2_8_la-pcre2_ucd.lo \ - src/libpcre2_8_la-pcre2_valid_utf.lo \ - src/libpcre2_8_la-pcre2_xclass.lo -@WITH_PCRE2_8_TRUE@am_libpcre2_8_la_OBJECTS = $(am__objects_5) -am__objects_6 = src/libpcre2_8_la-pcre2_chartables.lo -@WITH_PCRE2_8_TRUE@nodist_libpcre2_8_la_OBJECTS = $(am__objects_6) -libpcre2_8_la_OBJECTS = $(am_libpcre2_8_la_OBJECTS) \ - $(nodist_libpcre2_8_la_OBJECTS) -libpcre2_8_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre2_8_la_CFLAGS) \ - $(CFLAGS) $(libpcre2_8_la_LDFLAGS) $(LDFLAGS) -o $@ -@WITH_PCRE2_8_TRUE@am_libpcre2_8_la_rpath = -rpath $(libdir) -@WITH_PCRE2_8_TRUE@libpcre2_posix_la_DEPENDENCIES = libpcre2-8.la -am__libpcre2_posix_la_SOURCES_DIST = src/pcre2posix.c -@WITH_PCRE2_8_TRUE@am_libpcre2_posix_la_OBJECTS = \ -@WITH_PCRE2_8_TRUE@ src/libpcre2_posix_la-pcre2posix.lo -libpcre2_posix_la_OBJECTS = $(am_libpcre2_posix_la_OBJECTS) -libpcre2_posix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libpcre2_posix_la_CFLAGS) $(CFLAGS) \ - $(libpcre2_posix_la_LDFLAGS) $(LDFLAGS) -o $@ -@WITH_PCRE2_8_TRUE@am_libpcre2_posix_la_rpath = -rpath $(libdir) -@WITH_PCRE2_8_TRUE@am__EXEEXT_1 = pcre2grep$(EXEEXT) -@WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_2 = dftables$(EXEEXT) -@WITH_JIT_TRUE@am__EXEEXT_3 = pcre2_jit_test$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) -am__dftables_SOURCES_DIST = src/dftables.c -@WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS = \ -@WITH_REBUILD_CHARTABLES_TRUE@ src/dftables.$(OBJEXT) -dftables_OBJECTS = $(am_dftables_OBJECTS) -dftables_LDADD = $(LDADD) -am__pcre2_jit_test_SOURCES_DIST = src/pcre2_jit_test.c -@WITH_JIT_TRUE@am_pcre2_jit_test_OBJECTS = \ -@WITH_JIT_TRUE@ src/pcre2_jit_test-pcre2_jit_test.$(OBJEXT) -pcre2_jit_test_OBJECTS = $(am_pcre2_jit_test_OBJECTS) -am__DEPENDENCIES_1 = -@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__DEPENDENCIES_2 = \ -@WITH_GCOV_TRUE@@WITH_JIT_TRUE@ $(am__DEPENDENCIES_1) -@WITH_JIT_TRUE@pcre2_jit_test_DEPENDENCIES = $(am__append_18) \ -@WITH_JIT_TRUE@ $(am__append_19) $(am__append_20) \ -@WITH_JIT_TRUE@ $(am__DEPENDENCIES_2) -pcre2_jit_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(pcre2_jit_test_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ - $@ -am__pcre2grep_SOURCES_DIST = src/pcre2grep.c -@WITH_PCRE2_8_TRUE@am_pcre2grep_OBJECTS = \ -@WITH_PCRE2_8_TRUE@ src/pcre2grep-pcre2grep.$(OBJEXT) -pcre2grep_OBJECTS = $(am_pcre2grep_OBJECTS) -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__DEPENDENCIES_3 = \ -@WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_1) -@WITH_PCRE2_8_TRUE@pcre2grep_DEPENDENCIES = $(am__DEPENDENCIES_1) \ -@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_1) libpcre2-8.la \ -@WITH_PCRE2_8_TRUE@ $(am__DEPENDENCIES_3) -pcre2grep_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre2grep_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am_pcre2test_OBJECTS = src/pcre2test-pcre2test.$(OBJEXT) -pcre2test_OBJECTS = $(am_pcre2test_OBJECTS) -@WITH_GCOV_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) -pcre2test_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_23) \ - $(am__append_24) $(am__append_25) $(am__DEPENDENCIES_4) -pcre2test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre2test_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest -SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libpcre2_16_la_SOURCES) $(nodist_libpcre2_16_la_SOURCES) \ - $(libpcre2_32_la_SOURCES) $(nodist_libpcre2_32_la_SOURCES) \ - $(libpcre2_8_la_SOURCES) $(nodist_libpcre2_8_la_SOURCES) \ - $(libpcre2_posix_la_SOURCES) $(dftables_SOURCES) \ - $(pcre2_jit_test_SOURCES) $(pcre2grep_SOURCES) \ - $(pcre2test_SOURCES) -DIST_SOURCES = $(am__libpcre2_16_la_SOURCES_DIST) \ - $(am__libpcre2_32_la_SOURCES_DIST) \ - $(am__libpcre2_8_la_SOURCES_DIST) \ - $(am__libpcre2_posix_la_SOURCES_DIST) \ - $(am__dftables_SOURCES_DIST) \ - $(am__pcre2_jit_test_SOURCES_DIST) \ - $(am__pcre2grep_SOURCES_DIST) $(pcre2test_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -man1dir = $(mandir)/man1 -man3dir = $(mandir)/man3 -NROFF = nroff -MANS = $(dist_man_MANS) -DATA = $(dist_doc_DATA) $(dist_html_DATA) $(pkgconfig_DATA) -HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope check recheck -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - mgn=''; \ - brg=''; \ - std=''; \ - fi; \ -} -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver -LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ - $(srcdir)/libpcre2-16.pc.in $(srcdir)/libpcre2-32.pc.in \ - $(srcdir)/libpcre2-8.pc.in $(srcdir)/libpcre2-posix.pc.in \ - $(srcdir)/pcre2-config.in $(top_srcdir)/src/config.h.in \ - $(top_srcdir)/src/pcre2.h.in AUTHORS COPYING ChangeLog INSTALL \ - NEWS README ar-lib compile config.guess config.sub depcomp \ - install-sh ltmain.sh missing test-driver -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip -GZIP_ENV = --best -DIST_TARGETS = dist-bzip2 dist-gzip dist-zip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -EXTRA_LIBPCRE2_16_LDFLAGS = @EXTRA_LIBPCRE2_16_LDFLAGS@ -EXTRA_LIBPCRE2_32_LDFLAGS = @EXTRA_LIBPCRE2_32_LDFLAGS@ -EXTRA_LIBPCRE2_8_LDFLAGS = @EXTRA_LIBPCRE2_8_LDFLAGS@ -EXTRA_LIBPCRE2_POSIX_LDFLAGS = @EXTRA_LIBPCRE2_POSIX_LDFLAGS@ -FGREP = @FGREP@ -GCOV_CFLAGS = @GCOV_CFLAGS@ -GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ -GCOV_LIBS = @GCOV_LIBS@ -GENHTML = @GENHTML@ -GREP = @GREP@ -HAVE_VISIBILITY = @HAVE_VISIBILITY@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBBZ2 = @LIBBZ2@ -LIBOBJS = @LIBOBJS@ -LIBREADLINE = @LIBREADLINE@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBZ = @LIBZ@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PCRE2_DATE = @PCRE2_DATE@ -PCRE2_MAJOR = @PCRE2_MAJOR@ -PCRE2_MINOR = @PCRE2_MINOR@ -PCRE2_PRERELEASE = @PCRE2_PRERELEASE@ -PCRE2_STATIC_CFLAG = @PCRE2_STATIC_CFLAG@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SHTOOL = @SHTOOL@ -STRIP = @STRIP@ -VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ -VALGRIND_LIBS = @VALGRIND_LIBS@ -VERSION = @VERSION@ -VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ -VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -enable_pcre2_16 = @enable_pcre2_16@ -enable_pcre2_32 = @enable_pcre2_32@ -enable_pcre2_8 = @enable_pcre2_8@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = subdir-objects -ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src -dist_doc_DATA = \ - AUTHORS \ - COPYING \ - ChangeLog \ - LICENCE \ - NEWS \ - README \ - doc/pcre2.txt \ - doc/pcre2-config.txt \ - doc/pcre2grep.txt \ - doc/pcre2test.txt - -dist_html_DATA = \ - doc/html/NON-AUTOTOOLS-BUILD.txt \ - doc/html/README.txt \ - doc/html/index.html \ - doc/html/pcre2-config.html \ - doc/html/pcre2.html \ - doc/html/pcre2_callout_enumerate.html \ - doc/html/pcre2_code_free.html \ - doc/html/pcre2_compile.html \ - doc/html/pcre2_compile_context_copy.html \ - doc/html/pcre2_compile_context_create.html \ - doc/html/pcre2_compile_context_free.html \ - doc/html/pcre2_config.html \ - doc/html/pcre2_dfa_match.html \ - doc/html/pcre2_general_context_copy.html \ - doc/html/pcre2_general_context_create.html \ - doc/html/pcre2_general_context_free.html \ - doc/html/pcre2_get_error_message.html \ - doc/html/pcre2_get_mark.html \ - doc/html/pcre2_get_ovector_count.html \ - doc/html/pcre2_get_ovector_pointer.html \ - doc/html/pcre2_get_startchar.html \ - doc/html/pcre2_jit_compile.html \ - doc/html/pcre2_jit_free_unused_memory.html \ - doc/html/pcre2_jit_match.html \ - doc/html/pcre2_jit_stack_assign.html \ - doc/html/pcre2_jit_stack_create.html \ - doc/html/pcre2_jit_stack_free.html \ - doc/html/pcre2_maketables.html \ - doc/html/pcre2_match.html \ - doc/html/pcre2_match_context_copy.html \ - doc/html/pcre2_match_context_create.html \ - doc/html/pcre2_match_context_free.html \ - doc/html/pcre2_match_data_create.html \ - doc/html/pcre2_match_data_create_from_pattern.html \ - doc/html/pcre2_match_data_free.html \ - doc/html/pcre2_pattern_info.html \ - doc/html/pcre2_serialize_decode.html \ - doc/html/pcre2_serialize_encode.html \ - doc/html/pcre2_serialize_free.html \ - doc/html/pcre2_serialize_get_number_of_codes.html \ - doc/html/pcre2_set_bsr.html \ - doc/html/pcre2_set_callout.html \ - doc/html/pcre2_set_character_tables.html \ - doc/html/pcre2_set_compile_recursion_guard.html \ - doc/html/pcre2_set_match_limit.html \ - doc/html/pcre2_set_offset_limit.html \ - doc/html/pcre2_set_newline.html \ - doc/html/pcre2_set_parens_nest_limit.html \ - doc/html/pcre2_set_recursion_limit.html \ - doc/html/pcre2_set_recursion_memory_management.html \ - doc/html/pcre2_substitute.html \ - doc/html/pcre2_substring_copy_byname.html \ - doc/html/pcre2_substring_copy_bynumber.html \ - doc/html/pcre2_substring_free.html \ - doc/html/pcre2_substring_get_byname.html \ - doc/html/pcre2_substring_get_bynumber.html \ - doc/html/pcre2_substring_length_byname.html \ - doc/html/pcre2_substring_length_bynumber.html \ - doc/html/pcre2_substring_list_free.html \ - doc/html/pcre2_substring_list_get.html \ - doc/html/pcre2_substring_nametable_scan.html \ - doc/html/pcre2_substring_number_from_name.html \ - doc/html/pcre2api.html \ - doc/html/pcre2build.html \ - doc/html/pcre2callout.html \ - doc/html/pcre2compat.html \ - doc/html/pcre2demo.html \ - doc/html/pcre2grep.html \ - doc/html/pcre2jit.html \ - doc/html/pcre2limits.html \ - doc/html/pcre2matching.html \ - doc/html/pcre2partial.html \ - doc/html/pcre2pattern.html \ - doc/html/pcre2perform.html \ - doc/html/pcre2posix.html \ - doc/html/pcre2sample.html \ - doc/html/pcre2serialize.html \ - doc/html/pcre2stack.html \ - doc/html/pcre2syntax.html \ - doc/html/pcre2test.html \ - doc/html/pcre2unicode.html - -dist_man_MANS = \ - doc/pcre2-config.1 \ - doc/pcre2.3 \ - doc/pcre2_callout_enumerate.3 \ - doc/pcre2_code_free.3 \ - doc/pcre2_compile.3 \ - doc/pcre2_compile_context_copy.3 \ - doc/pcre2_compile_context_create.3 \ - doc/pcre2_compile_context_free.3 \ - doc/pcre2_config.3 \ - doc/pcre2_dfa_match.3 \ - doc/pcre2_general_context_copy.3 \ - doc/pcre2_general_context_create.3 \ - doc/pcre2_general_context_free.3 \ - doc/pcre2_get_error_message.3 \ - doc/pcre2_get_mark.3 \ - doc/pcre2_get_ovector_count.3 \ - doc/pcre2_get_ovector_pointer.3 \ - doc/pcre2_get_startchar.3 \ - doc/pcre2_jit_compile.3 \ - doc/pcre2_jit_free_unused_memory.3 \ - doc/pcre2_jit_match.3 \ - doc/pcre2_jit_stack_assign.3 \ - doc/pcre2_jit_stack_create.3 \ - doc/pcre2_jit_stack_free.3 \ - doc/pcre2_maketables.3 \ - doc/pcre2_match.3 \ - doc/pcre2_match_context_copy.3 \ - doc/pcre2_match_context_create.3 \ - doc/pcre2_match_context_free.3 \ - doc/pcre2_match_data_create.3 \ - doc/pcre2_match_data_create_from_pattern.3 \ - doc/pcre2_match_data_free.3 \ - doc/pcre2_pattern_info.3 \ - doc/pcre2_serialize_decode.3 \ - doc/pcre2_serialize_encode.3 \ - doc/pcre2_serialize_free.3 \ - doc/pcre2_serialize_get_number_of_codes.3 \ - doc/pcre2_set_bsr.3 \ - doc/pcre2_set_callout.3 \ - doc/pcre2_set_character_tables.3 \ - doc/pcre2_set_compile_recursion_guard.3 \ - doc/pcre2_set_match_limit.3 \ - doc/pcre2_set_offset_limit.3 \ - doc/pcre2_set_newline.3 \ - doc/pcre2_set_parens_nest_limit.3 \ - doc/pcre2_set_recursion_limit.3 \ - doc/pcre2_set_recursion_memory_management.3 \ - doc/pcre2_substitute.3 \ - doc/pcre2_substring_copy_byname.3 \ - doc/pcre2_substring_copy_bynumber.3 \ - doc/pcre2_substring_free.3 \ - doc/pcre2_substring_get_byname.3 \ - doc/pcre2_substring_get_bynumber.3 \ - doc/pcre2_substring_length_byname.3 \ - doc/pcre2_substring_length_bynumber.3 \ - doc/pcre2_substring_list_free.3 \ - doc/pcre2_substring_list_get.3 \ - doc/pcre2_substring_nametable_scan.3 \ - doc/pcre2_substring_number_from_name.3 \ - doc/pcre2api.3 \ - doc/pcre2build.3 \ - doc/pcre2callout.3 \ - doc/pcre2compat.3 \ - doc/pcre2demo.3 \ - doc/pcre2grep.1 \ - doc/pcre2jit.3 \ - doc/pcre2limits.3 \ - doc/pcre2matching.3 \ - doc/pcre2partial.3 \ - doc/pcre2pattern.3 \ - doc/pcre2perform.3 \ - doc/pcre2posix.3 \ - doc/pcre2sample.3 \ - doc/pcre2serialize.3 \ - doc/pcre2stack.3 \ - doc/pcre2syntax.3 \ - doc/pcre2test.1 \ - doc/pcre2unicode.3 - - -# The Libtool libraries to install. We'll add to this later. -lib_LTLIBRARIES = $(am__append_2) $(am__append_3) $(am__append_4) \ - $(am__append_11) -check_SCRIPTS = -dist_noinst_SCRIPTS = RunTest $(am__append_30) - -# Additional files to delete on 'make clean', 'make distclean', -# and 'make maintainer-clean'. - -# RunTest and RunGrepTest should clean up after themselves, but just in case -# they don't, add their working files to CLEANFILES. -CLEANFILES = src/pcre2_chartables.c testSinput test3input test3output \ - test3outputA test3outputB testtry teststdout teststderr \ - teststderrgrep testtemp1grep testtemp2grep testtrygrep \ - testNinputgrep -DISTCLEANFILES = src/config.h.in~ config.h $(am__append_34) -MAINTAINERCLEANFILES = src/pcre2.h.generic src/config.h.generic - -# Additional files to bundle with the distribution, over and above what -# the Autotools include by default. - -# These files contain additional m4 macros that are used by autoconf. - -# These files contain maintenance information - -# These files are used in the preparation of a release - -# These files are usable versions of pcre2.h and config.h that are distributed -# for the benefit of people who are building PCRE2 manually, without the -# Autotools support. - -# The pcre2_chartables.c.dist file is the default version of -# pcre2_chartables.c, used unless --enable-rebuild-chartables is specified. - -# The JIT compiler lives in a separate directory, but its files are #included -# when pcre2_jit_compile.c is processed, so they must be distributed. - -# Some of the JIT sources are also in separate files that are #included. - -# PCRE2 demonstration program. Not built automatcally. The point is that the -# users should build it themselves. So just distribute the source. -EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \ - NON-AUTOTOOLS-BUILD HACKING PrepareRelease CheckMan CleanTxt \ - Detrail 132html doc/index.html.src src/pcre2.h.generic \ - src/config.h.generic src/pcre2_chartables.c.dist \ - src/sljit/sljitConfig.h src/sljit/sljitConfigInternal.h \ - src/sljit/sljitExecAllocator.c src/sljit/sljitLir.c \ - src/sljit/sljitLir.h src/sljit/sljitNativeARM_32.c \ - src/sljit/sljitNativeARM_64.c src/sljit/sljitNativeARM_T2_32.c \ - src/sljit/sljitNativeMIPS_32.c src/sljit/sljitNativeMIPS_64.c \ - src/sljit/sljitNativeMIPS_common.c \ - src/sljit/sljitNativePPC_32.c src/sljit/sljitNativePPC_64.c \ - src/sljit/sljitNativePPC_common.c \ - src/sljit/sljitNativeSPARC_32.c \ - src/sljit/sljitNativeSPARC_common.c \ - src/sljit/sljitNativeTILEGX-encoder.c \ - src/sljit/sljitNativeTILEGX_64.c src/sljit/sljitNativeX86_32.c \ - src/sljit/sljitNativeX86_64.c \ - src/sljit/sljitNativeX86_common.c src/sljit/sljitUtils.c \ - src/pcre2_jit_match.c src/pcre2_jit_misc.c \ - src/pcre2_printint.c RunTest.bat testdata/grepbinary \ - testdata/grepfilelist testdata/grepinput testdata/grepinput3 \ - testdata/grepinput8 testdata/grepinputv testdata/grepinputx \ - testdata/greplist testdata/grepoutput testdata/grepoutput8 \ - testdata/grepoutputN testdata/greppatN4 testdata/testinput1 \ - testdata/testinput2 testdata/testinput3 testdata/testinput4 \ - testdata/testinput5 testdata/testinput6 testdata/testinput7 \ - testdata/testinput8 testdata/testinput9 testdata/testinput10 \ - testdata/testinput11 testdata/testinput12 testdata/testinput13 \ - testdata/testinput14 testdata/testinput15 testdata/testinput16 \ - testdata/testinput17 testdata/testinput18 testdata/testinput19 \ - testdata/testinput20 testdata/testinput21 testdata/testinput22 \ - testdata/testinput23 testdata/testinputEBC \ - testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \ - testdata/testoutput3A testdata/testoutput3B \ - testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ - testdata/testoutput7 testdata/testoutput8-16-2 \ - testdata/testoutput8-16-3 testdata/testoutput8-16-3 \ - testdata/testoutput8-32-2 testdata/testoutput8-32-3 \ - testdata/testoutput8-32-4 testdata/testoutput8-8-2 \ - testdata/testoutput8-8-3 testdata/testoutput8-8-4 \ - testdata/testoutput9 testdata/testoutput10 \ - testdata/testoutput11-16 testdata/testoutput11-32 \ - testdata/testoutput12-16 testdata/testoutput12-32 \ - testdata/testoutput13 testdata/testoutput14-16 \ - testdata/testoutput14-32 testdata/testoutput14-8 \ - testdata/testoutput15 testdata/testoutput16 \ - testdata/testoutput17 testdata/testoutput18 \ - testdata/testoutput19 testdata/testoutput20 \ - testdata/testoutput21 testdata/testoutput22-16 \ - testdata/testoutput22-32 testdata/testoutput22-8 \ - testdata/testoutput23 testdata/testoutputEBC \ - testdata/valgrind-jit.supp testdata/wintestinput3 \ - testdata/wintestoutput3 perltest.sh src/pcre2demo.c \ - cmake/COPYING-CMAKE-SCRIPTS \ - cmake/FindPackageHandleStandardArgs.cmake \ - cmake/FindReadline.cmake cmake/FindEditline.cmake \ - CMakeLists.txt config-cmake.h.in - -# These are the header files we'll install. We do not distribute pcre2.h -# because it is generated from pcre2.h.in. -nodist_include_HEADERS = src/pcre2.h -include_HEADERS = src/pcre2posix.h - -# This is the "config" script. -bin_SCRIPTS = pcre2-config -@WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = src/dftables.c -BUILT_SOURCES = src/pcre2_chartables.c -NODIST_SOURCES = src/pcre2_chartables.c -COMMON_SOURCES = \ - src/pcre2_auto_possess.c \ - src/pcre2_compile.c \ - src/pcre2_config.c \ - src/pcre2_context.c \ - src/pcre2_dfa_match.c \ - src/pcre2_error.c \ - src/pcre2_find_bracket.c \ - src/pcre2_internal.h \ - src/pcre2_intmodedep.h \ - src/pcre2_jit_compile.c \ - src/pcre2_maketables.c \ - src/pcre2_match.c \ - src/pcre2_match_data.c \ - src/pcre2_newline.c \ - src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c \ - src/pcre2_serialize.c \ - src/pcre2_string_utils.c \ - src/pcre2_study.c \ - src/pcre2_substitute.c \ - src/pcre2_substring.c \ - src/pcre2_tables.c \ - src/pcre2_ucd.c \ - src/pcre2_ucp.h \ - src/pcre2_valid_utf.c \ - src/pcre2_xclass.c - -@WITH_PCRE2_8_TRUE@libpcre2_8_la_SOURCES = \ -@WITH_PCRE2_8_TRUE@ $(COMMON_SOURCES) - -@WITH_PCRE2_8_TRUE@nodist_libpcre2_8_la_SOURCES = \ -@WITH_PCRE2_8_TRUE@ $(NODIST_SOURCES) - -@WITH_PCRE2_8_TRUE@libpcre2_8_la_CFLAGS = -DPCRE2_CODE_UNIT_WIDTH=8 \ -@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ -@WITH_PCRE2_8_TRUE@ $(am__append_5) $(am__append_8) -@WITH_PCRE2_8_TRUE@libpcre2_8_la_LIBADD = -@WITH_PCRE2_16_TRUE@libpcre2_16_la_SOURCES = \ -@WITH_PCRE2_16_TRUE@ $(COMMON_SOURCES) - -@WITH_PCRE2_16_TRUE@nodist_libpcre2_16_la_SOURCES = \ -@WITH_PCRE2_16_TRUE@ $(NODIST_SOURCES) - -@WITH_PCRE2_16_TRUE@libpcre2_16_la_CFLAGS = \ -@WITH_PCRE2_16_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=16 \ -@WITH_PCRE2_16_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ -@WITH_PCRE2_16_TRUE@ $(am__append_6) $(am__append_9) -@WITH_PCRE2_16_TRUE@libpcre2_16_la_LIBADD = -@WITH_PCRE2_32_TRUE@libpcre2_32_la_SOURCES = \ -@WITH_PCRE2_32_TRUE@ $(COMMON_SOURCES) - -@WITH_PCRE2_32_TRUE@nodist_libpcre2_32_la_SOURCES = \ -@WITH_PCRE2_32_TRUE@ $(NODIST_SOURCES) - -@WITH_PCRE2_32_TRUE@libpcre2_32_la_CFLAGS = \ -@WITH_PCRE2_32_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=32 \ -@WITH_PCRE2_32_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ -@WITH_PCRE2_32_TRUE@ $(am__append_7) $(am__append_10) -@WITH_PCRE2_32_TRUE@libpcre2_32_la_LIBADD = -@WITH_PCRE2_8_TRUE@libpcre2_8_la_LDFLAGS = $(EXTRA_LIBPCRE2_8_LDFLAGS) -@WITH_PCRE2_16_TRUE@libpcre2_16_la_LDFLAGS = $(EXTRA_LIBPCRE2_16_LDFLAGS) -@WITH_PCRE2_32_TRUE@libpcre2_32_la_LDFLAGS = $(EXTRA_LIBPCRE2_32_LDFLAGS) -@WITH_PCRE2_8_TRUE@libpcre2_posix_la_SOURCES = src/pcre2posix.c -@WITH_PCRE2_8_TRUE@libpcre2_posix_la_CFLAGS = \ -@WITH_PCRE2_8_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=8 \ -@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ -@WITH_PCRE2_8_TRUE@ $(am__append_12) -@WITH_PCRE2_8_TRUE@libpcre2_posix_la_LDFLAGS = $(EXTRA_LIBPCRE2_POSIX_LDFLAGS) -@WITH_PCRE2_8_TRUE@libpcre2_posix_la_LIBADD = libpcre2-8.la -@WITH_PCRE2_8_TRUE@pcre2grep_SOURCES = src/pcre2grep.c -@WITH_PCRE2_8_TRUE@pcre2grep_CFLAGS = $(AM_CFLAGS) $(am__append_14) -@WITH_PCRE2_8_TRUE@pcre2grep_LDADD = $(LIBZ) $(LIBBZ2) libpcre2-8.la \ -@WITH_PCRE2_8_TRUE@ $(am__append_15) -@WITH_JIT_TRUE@pcre2_jit_test_SOURCES = src/pcre2_jit_test.c -@WITH_JIT_TRUE@pcre2_jit_test_CFLAGS = $(AM_CFLAGS) $(am__append_21) -@WITH_JIT_TRUE@pcre2_jit_test_LDADD = $(am__append_18) \ -@WITH_JIT_TRUE@ $(am__append_19) $(am__append_20) \ -@WITH_JIT_TRUE@ $(am__append_22) -pcre2test_SOURCES = src/pcre2test.c -pcre2test_CFLAGS = $(AM_CFLAGS) $(am__append_26) $(am__append_27) -pcre2test_LDADD = $(LIBREADLINE) $(am__append_23) $(am__append_24) \ - $(am__append_25) $(am__append_28) - -# We have .pc files for pkg-config users. -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(am__append_31) $(am__append_32) $(am__append_33) - -# gcov/lcov code coverage reporting -# -# Coverage reporting targets: -# -# coverage: Create a coverage report from 'make check' -# coverage-baseline: Capture baseline coverage information -# coverage-reset: This zeros the coverage counters only -# coverage-report: This creates the coverage report only -# coverage-clean-report: This removes the generated coverage report -# without cleaning the coverage data itself -# coverage-clean-data: This removes the captured coverage data without -# removing the coverage files created at compile time (*.gcno) -# coverage-clean: This cleans all coverage data including the generated -# coverage report. -@WITH_GCOV_TRUE@COVERAGE_TEST_NAME = $(PACKAGE) -@WITH_GCOV_TRUE@COVERAGE_NAME = $(PACKAGE)-$(VERSION) -@WITH_GCOV_TRUE@COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info -@WITH_GCOV_TRUE@COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage -@WITH_GCOV_TRUE@COVERAGE_LCOV_EXTRA_FLAGS = -@WITH_GCOV_TRUE@COVERAGE_GENHTML_EXTRA_FLAGS = -@WITH_GCOV_TRUE@coverage_quiet = $(coverage_quiet_$(V)) -@WITH_GCOV_TRUE@coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -@WITH_GCOV_TRUE@coverage_quiet_0 = --quiet -all: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -src/config.h: src/stamp-h1 - @test -f $@ || rm -f src/stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1 - -src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status - @rm -f src/stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status src/config.h -$(top_srcdir)/src/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f src/stamp-h1 - touch $@ - -distclean-hdr: - -rm -f src/config.h src/stamp-h1 -libpcre2-8.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-8.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -libpcre2-16.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-16.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -libpcre2-32.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-32.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -libpcre2-posix.pc: $(top_builddir)/config.status $(srcdir)/libpcre2-posix.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -pcre2-config: $(top_builddir)/config.status $(srcdir)/pcre2-config.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -src/pcre2.h: $(top_builddir)/config.status $(top_srcdir)/src/pcre2.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -src/$(am__dirstamp): - @$(MKDIR_P) src - @: > src/$(am__dirstamp) -src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/$(DEPDIR) - @: > src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_config.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_context.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_error.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_maketables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_match_data.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_newline.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_serialize.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_study.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_substitute.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_substring.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_tables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_ucd.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_xclass.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_16_la-pcre2_chartables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -libpcre2-16.la: $(libpcre2_16_la_OBJECTS) $(libpcre2_16_la_DEPENDENCIES) $(EXTRA_libpcre2_16_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpcre2_16_la_LINK) $(am_libpcre2_16_la_rpath) $(libpcre2_16_la_OBJECTS) $(libpcre2_16_la_LIBADD) $(LIBS) -src/libpcre2_32_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_config.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_context.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_error.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_maketables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_match_data.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_newline.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_serialize.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_study.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_substitute.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_substring.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_tables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_ucd.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_xclass.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_32_la-pcre2_chartables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -libpcre2-32.la: $(libpcre2_32_la_OBJECTS) $(libpcre2_32_la_DEPENDENCIES) $(EXTRA_libpcre2_32_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpcre2_32_la_LINK) $(am_libpcre2_32_la_rpath) $(libpcre2_32_la_OBJECTS) $(libpcre2_32_la_LIBADD) $(LIBS) -src/libpcre2_8_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_config.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_context.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_error.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_maketables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_match.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_match_data.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_newline.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_ord2utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_pattern_info.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_serialize.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_string_utils.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_study.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_substitute.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_substring.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_tables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_ucd.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_valid_utf.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_xclass.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libpcre2_8_la-pcre2_chartables.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -libpcre2-8.la: $(libpcre2_8_la_OBJECTS) $(libpcre2_8_la_DEPENDENCIES) $(EXTRA_libpcre2_8_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpcre2_8_la_LINK) $(am_libpcre2_8_la_rpath) $(libpcre2_8_la_OBJECTS) $(libpcre2_8_la_LIBADD) $(LIBS) -src/libpcre2_posix_la-pcre2posix.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -libpcre2-posix.la: $(libpcre2_posix_la_OBJECTS) $(libpcre2_posix_la_DEPENDENCIES) $(EXTRA_libpcre2_posix_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpcre2_posix_la_LINK) $(am_libpcre2_posix_la_rpath) $(libpcre2_posix_la_OBJECTS) $(libpcre2_posix_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -src/dftables.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES) - @rm -f dftables$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) -src/pcre2_jit_test-pcre2_jit_test.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -pcre2_jit_test$(EXEEXT): $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_DEPENDENCIES) $(EXTRA_pcre2_jit_test_DEPENDENCIES) - @rm -f pcre2_jit_test$(EXEEXT) - $(AM_V_CCLD)$(pcre2_jit_test_LINK) $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_LDADD) $(LIBS) -src/pcre2grep-pcre2grep.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -pcre2grep$(EXEEXT): $(pcre2grep_OBJECTS) $(pcre2grep_DEPENDENCIES) $(EXTRA_pcre2grep_DEPENDENCIES) - @rm -f pcre2grep$(EXEEXT) - $(AM_V_CCLD)$(pcre2grep_LINK) $(pcre2grep_OBJECTS) $(pcre2grep_LDADD) $(LIBS) -src/pcre2test-pcre2test.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -pcre2test$(EXEEXT): $(pcre2test_OBJECTS) $(pcre2test_DEPENDENCIES) $(EXTRA_pcre2test_DEPENDENCIES) - @rm -f pcre2test$(EXEEXT) - $(AM_V_CCLD)$(pcre2test_LINK) $(pcre2test_OBJECTS) $(pcre2test_LDADD) $(LIBS) -install-binSCRIPTS: $(bin_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f src/*.$(OBJEXT) - -rm -f src/*.lo - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dftables.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2grep-pcre2grep.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2test-pcre2test.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -src/libpcre2_16_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_16_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_16_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c - -src/libpcre2_16_la-pcre2_compile.lo: src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Tpo -c -o src/libpcre2_16_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_16_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c - -src/libpcre2_16_la-pcre2_config.lo: src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Tpo -c -o src/libpcre2_16_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_16_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c - -src/libpcre2_16_la-pcre2_context.lo: src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Tpo -c -o src/libpcre2_16_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_16_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c - -src/libpcre2_16_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_16_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_16_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c - -src/libpcre2_16_la-pcre2_error.lo: src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Tpo -c -o src/libpcre2_16_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_16_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c - -src/libpcre2_16_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_16_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_16_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c - -src/libpcre2_16_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_16_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_16_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c - -src/libpcre2_16_la-pcre2_maketables.lo: src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Tpo -c -o src/libpcre2_16_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_16_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c - -src/libpcre2_16_la-pcre2_match.lo: src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Tpo -c -o src/libpcre2_16_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_16_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c - -src/libpcre2_16_la-pcre2_match_data.lo: src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Tpo -c -o src/libpcre2_16_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_match_data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_16_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c - -src/libpcre2_16_la-pcre2_newline.lo: src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Tpo -c -o src/libpcre2_16_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_newline.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_16_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c - -src/libpcre2_16_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_16_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_ord2utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_16_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c - -src/libpcre2_16_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_16_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_pattern_info.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_16_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c - -src/libpcre2_16_la-pcre2_serialize.lo: src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Tpo -c -o src/libpcre2_16_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_serialize.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_16_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c - -src/libpcre2_16_la-pcre2_string_utils.lo: src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Tpo -c -o src/libpcre2_16_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_string_utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_16_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c - -src/libpcre2_16_la-pcre2_study.lo: src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Tpo -c -o src/libpcre2_16_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_study.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_16_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c - -src/libpcre2_16_la-pcre2_substitute.lo: src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Tpo -c -o src/libpcre2_16_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_substitute.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_16_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c - -src/libpcre2_16_la-pcre2_substring.lo: src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Tpo -c -o src/libpcre2_16_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_substring.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_16_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c - -src/libpcre2_16_la-pcre2_tables.lo: src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Tpo -c -o src/libpcre2_16_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_tables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_16_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c - -src/libpcre2_16_la-pcre2_ucd.lo: src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Tpo -c -o src/libpcre2_16_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_ucd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_16_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c - -src/libpcre2_16_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_16_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_valid_utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_16_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c - -src/libpcre2_16_la-pcre2_xclass.lo: src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Tpo -c -o src/libpcre2_16_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_xclass.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_16_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c - -src/libpcre2_16_la-pcre2_chartables.lo: src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Tpo -c -o src/libpcre2_16_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_16_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c - -src/libpcre2_32_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_32_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_auto_possess.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_32_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c - -src/libpcre2_32_la-pcre2_compile.lo: src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Tpo -c -o src/libpcre2_32_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_32_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c - -src/libpcre2_32_la-pcre2_config.lo: src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Tpo -c -o src/libpcre2_32_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_32_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c - -src/libpcre2_32_la-pcre2_context.lo: src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Tpo -c -o src/libpcre2_32_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_32_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c - -src/libpcre2_32_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_32_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_32_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c - -src/libpcre2_32_la-pcre2_error.lo: src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Tpo -c -o src/libpcre2_32_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_32_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c - -src/libpcre2_32_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_32_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_32_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c - -src/libpcre2_32_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_32_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_32_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c - -src/libpcre2_32_la-pcre2_maketables.lo: src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Tpo -c -o src/libpcre2_32_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_32_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c - -src/libpcre2_32_la-pcre2_match.lo: src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Tpo -c -o src/libpcre2_32_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_32_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c - -src/libpcre2_32_la-pcre2_match_data.lo: src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Tpo -c -o src/libpcre2_32_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_match_data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_32_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c - -src/libpcre2_32_la-pcre2_newline.lo: src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Tpo -c -o src/libpcre2_32_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_newline.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_32_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c - -src/libpcre2_32_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_32_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_ord2utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_32_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c - -src/libpcre2_32_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_32_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_pattern_info.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_32_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c - -src/libpcre2_32_la-pcre2_serialize.lo: src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Tpo -c -o src/libpcre2_32_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_serialize.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_32_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c - -src/libpcre2_32_la-pcre2_string_utils.lo: src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Tpo -c -o src/libpcre2_32_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_string_utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_32_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c - -src/libpcre2_32_la-pcre2_study.lo: src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Tpo -c -o src/libpcre2_32_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_study.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_32_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c - -src/libpcre2_32_la-pcre2_substitute.lo: src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Tpo -c -o src/libpcre2_32_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_substitute.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_32_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c - -src/libpcre2_32_la-pcre2_substring.lo: src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Tpo -c -o src/libpcre2_32_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_substring.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_32_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c - -src/libpcre2_32_la-pcre2_tables.lo: src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Tpo -c -o src/libpcre2_32_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_tables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_32_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c - -src/libpcre2_32_la-pcre2_ucd.lo: src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Tpo -c -o src/libpcre2_32_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_ucd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_32_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c - -src/libpcre2_32_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_32_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_valid_utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_32_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c - -src/libpcre2_32_la-pcre2_xclass.lo: src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Tpo -c -o src/libpcre2_32_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_xclass.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_32_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c - -src/libpcre2_32_la-pcre2_chartables.lo: src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Tpo -c -o src/libpcre2_32_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_chartables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_32_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c - -src/libpcre2_8_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_8_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_auto_possess.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_auto_possess.c' object='src/libpcre2_8_la-pcre2_auto_possess.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c - -src/libpcre2_8_la-pcre2_compile.lo: src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Tpo -c -o src/libpcre2_8_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_compile.c' object='src/libpcre2_8_la-pcre2_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_compile.lo `test -f 'src/pcre2_compile.c' || echo '$(srcdir)/'`src/pcre2_compile.c - -src/libpcre2_8_la-pcre2_config.lo: src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_config.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Tpo -c -o src/libpcre2_8_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_config.c' object='src/libpcre2_8_la-pcre2_config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_config.lo `test -f 'src/pcre2_config.c' || echo '$(srcdir)/'`src/pcre2_config.c - -src/libpcre2_8_la-pcre2_context.lo: src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_context.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Tpo -c -o src/libpcre2_8_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_context.c' object='src/libpcre2_8_la-pcre2_context.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c - -src/libpcre2_8_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_8_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_dfa_match.c' object='src/libpcre2_8_la-pcre2_dfa_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c - -src/libpcre2_8_la-pcre2_error.lo: src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_error.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Tpo -c -o src/libpcre2_8_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_error.c' object='src/libpcre2_8_la-pcre2_error.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c - -src/libpcre2_8_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_8_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_find_bracket.c' object='src/libpcre2_8_la-pcre2_find_bracket.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c - -src/libpcre2_8_la-pcre2_jit_compile.lo: src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_jit_compile.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Tpo -c -o src/libpcre2_8_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_compile.c' object='src/libpcre2_8_la-pcre2_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_jit_compile.lo `test -f 'src/pcre2_jit_compile.c' || echo '$(srcdir)/'`src/pcre2_jit_compile.c - -src/libpcre2_8_la-pcre2_maketables.lo: src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_maketables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Tpo -c -o src/libpcre2_8_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_maketables.c' object='src/libpcre2_8_la-pcre2_maketables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_maketables.lo `test -f 'src/pcre2_maketables.c' || echo '$(srcdir)/'`src/pcre2_maketables.c - -src/libpcre2_8_la-pcre2_match.lo: src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Tpo -c -o src/libpcre2_8_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match.c' object='src/libpcre2_8_la-pcre2_match.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_match.lo `test -f 'src/pcre2_match.c' || echo '$(srcdir)/'`src/pcre2_match.c - -src/libpcre2_8_la-pcre2_match_data.lo: src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_match_data.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Tpo -c -o src/libpcre2_8_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_match_data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_match_data.c' object='src/libpcre2_8_la-pcre2_match_data.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_match_data.lo `test -f 'src/pcre2_match_data.c' || echo '$(srcdir)/'`src/pcre2_match_data.c - -src/libpcre2_8_la-pcre2_newline.lo: src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_newline.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Tpo -c -o src/libpcre2_8_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_newline.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_newline.c' object='src/libpcre2_8_la-pcre2_newline.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_newline.lo `test -f 'src/pcre2_newline.c' || echo '$(srcdir)/'`src/pcre2_newline.c - -src/libpcre2_8_la-pcre2_ord2utf.lo: src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_ord2utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Tpo -c -o src/libpcre2_8_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_ord2utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ord2utf.c' object='src/libpcre2_8_la-pcre2_ord2utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_ord2utf.lo `test -f 'src/pcre2_ord2utf.c' || echo '$(srcdir)/'`src/pcre2_ord2utf.c - -src/libpcre2_8_la-pcre2_pattern_info.lo: src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_pattern_info.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Tpo -c -o src/libpcre2_8_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_pattern_info.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_pattern_info.c' object='src/libpcre2_8_la-pcre2_pattern_info.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_pattern_info.lo `test -f 'src/pcre2_pattern_info.c' || echo '$(srcdir)/'`src/pcre2_pattern_info.c - -src/libpcre2_8_la-pcre2_serialize.lo: src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_serialize.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Tpo -c -o src/libpcre2_8_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_serialize.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_serialize.c' object='src/libpcre2_8_la-pcre2_serialize.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_serialize.lo `test -f 'src/pcre2_serialize.c' || echo '$(srcdir)/'`src/pcre2_serialize.c - -src/libpcre2_8_la-pcre2_string_utils.lo: src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_string_utils.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Tpo -c -o src/libpcre2_8_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_string_utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_string_utils.c' object='src/libpcre2_8_la-pcre2_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_string_utils.lo `test -f 'src/pcre2_string_utils.c' || echo '$(srcdir)/'`src/pcre2_string_utils.c - -src/libpcre2_8_la-pcre2_study.lo: src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_study.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Tpo -c -o src/libpcre2_8_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_study.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_study.c' object='src/libpcre2_8_la-pcre2_study.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_study.lo `test -f 'src/pcre2_study.c' || echo '$(srcdir)/'`src/pcre2_study.c - -src/libpcre2_8_la-pcre2_substitute.lo: src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_substitute.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Tpo -c -o src/libpcre2_8_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_substitute.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substitute.c' object='src/libpcre2_8_la-pcre2_substitute.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_substitute.lo `test -f 'src/pcre2_substitute.c' || echo '$(srcdir)/'`src/pcre2_substitute.c - -src/libpcre2_8_la-pcre2_substring.lo: src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_substring.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Tpo -c -o src/libpcre2_8_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_substring.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_substring.c' object='src/libpcre2_8_la-pcre2_substring.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_substring.lo `test -f 'src/pcre2_substring.c' || echo '$(srcdir)/'`src/pcre2_substring.c - -src/libpcre2_8_la-pcre2_tables.lo: src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_tables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Tpo -c -o src/libpcre2_8_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_tables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_tables.c' object='src/libpcre2_8_la-pcre2_tables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_tables.lo `test -f 'src/pcre2_tables.c' || echo '$(srcdir)/'`src/pcre2_tables.c - -src/libpcre2_8_la-pcre2_ucd.lo: src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_ucd.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Tpo -c -o src/libpcre2_8_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_ucd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_ucd.c' object='src/libpcre2_8_la-pcre2_ucd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_ucd.lo `test -f 'src/pcre2_ucd.c' || echo '$(srcdir)/'`src/pcre2_ucd.c - -src/libpcre2_8_la-pcre2_valid_utf.lo: src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_valid_utf.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Tpo -c -o src/libpcre2_8_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_valid_utf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_valid_utf.c' object='src/libpcre2_8_la-pcre2_valid_utf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_valid_utf.lo `test -f 'src/pcre2_valid_utf.c' || echo '$(srcdir)/'`src/pcre2_valid_utf.c - -src/libpcre2_8_la-pcre2_xclass.lo: src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_xclass.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Tpo -c -o src/libpcre2_8_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_xclass.c' object='src/libpcre2_8_la-pcre2_xclass.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_xclass.lo `test -f 'src/pcre2_xclass.c' || echo '$(srcdir)/'`src/pcre2_xclass.c - -src/libpcre2_8_la-pcre2_chartables.lo: src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_chartables.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Tpo -c -o src/libpcre2_8_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_chartables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_chartables.c' object='src/libpcre2_8_la-pcre2_chartables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_chartables.lo `test -f 'src/pcre2_chartables.c' || echo '$(srcdir)/'`src/pcre2_chartables.c - -src/libpcre2_posix_la-pcre2posix.lo: src/pcre2posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_posix_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_posix_la-pcre2posix.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Tpo -c -o src/libpcre2_posix_la-pcre2posix.lo `test -f 'src/pcre2posix.c' || echo '$(srcdir)/'`src/pcre2posix.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Tpo src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2posix.c' object='src/libpcre2_posix_la-pcre2posix.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_posix_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_posix_la-pcre2posix.lo `test -f 'src/pcre2posix.c' || echo '$(srcdir)/'`src/pcre2posix.c - -src/pcre2_jit_test-pcre2_jit_test.o: src/pcre2_jit_test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -MT src/pcre2_jit_test-pcre2_jit_test.o -MD -MP -MF src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo -c -o src/pcre2_jit_test-pcre2_jit_test.o `test -f 'src/pcre2_jit_test.c' || echo '$(srcdir)/'`src/pcre2_jit_test.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_test.c' object='src/pcre2_jit_test-pcre2_jit_test.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -c -o src/pcre2_jit_test-pcre2_jit_test.o `test -f 'src/pcre2_jit_test.c' || echo '$(srcdir)/'`src/pcre2_jit_test.c - -src/pcre2_jit_test-pcre2_jit_test.obj: src/pcre2_jit_test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -MT src/pcre2_jit_test-pcre2_jit_test.obj -MD -MP -MF src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo -c -o src/pcre2_jit_test-pcre2_jit_test.obj `if test -f 'src/pcre2_jit_test.c'; then $(CYGPATH_W) 'src/pcre2_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_jit_test.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Tpo src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2_jit_test.c' object='src/pcre2_jit_test-pcre2_jit_test.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -c -o src/pcre2_jit_test-pcre2_jit_test.obj `if test -f 'src/pcre2_jit_test.c'; then $(CYGPATH_W) 'src/pcre2_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_jit_test.c'; fi` - -src/pcre2grep-pcre2grep.o: src/pcre2grep.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -MT src/pcre2grep-pcre2grep.o -MD -MP -MF src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo -c -o src/pcre2grep-pcre2grep.o `test -f 'src/pcre2grep.c' || echo '$(srcdir)/'`src/pcre2grep.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo src/$(DEPDIR)/pcre2grep-pcre2grep.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2grep.c' object='src/pcre2grep-pcre2grep.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -c -o src/pcre2grep-pcre2grep.o `test -f 'src/pcre2grep.c' || echo '$(srcdir)/'`src/pcre2grep.c - -src/pcre2grep-pcre2grep.obj: src/pcre2grep.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -MT src/pcre2grep-pcre2grep.obj -MD -MP -MF src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo -c -o src/pcre2grep-pcre2grep.obj `if test -f 'src/pcre2grep.c'; then $(CYGPATH_W) 'src/pcre2grep.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2grep.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo src/$(DEPDIR)/pcre2grep-pcre2grep.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2grep.c' object='src/pcre2grep-pcre2grep.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -c -o src/pcre2grep-pcre2grep.obj `if test -f 'src/pcre2grep.c'; then $(CYGPATH_W) 'src/pcre2grep.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2grep.c'; fi` - -src/pcre2test-pcre2test.o: src/pcre2test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -MT src/pcre2test-pcre2test.o -MD -MP -MF src/$(DEPDIR)/pcre2test-pcre2test.Tpo -c -o src/pcre2test-pcre2test.o `test -f 'src/pcre2test.c' || echo '$(srcdir)/'`src/pcre2test.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2test-pcre2test.Tpo src/$(DEPDIR)/pcre2test-pcre2test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2test.c' object='src/pcre2test-pcre2test.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -c -o src/pcre2test-pcre2test.o `test -f 'src/pcre2test.c' || echo '$(srcdir)/'`src/pcre2test.c - -src/pcre2test-pcre2test.obj: src/pcre2test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -MT src/pcre2test-pcre2test.obj -MD -MP -MF src/$(DEPDIR)/pcre2test-pcre2test.Tpo -c -o src/pcre2test-pcre2test.obj `if test -f 'src/pcre2test.c'; then $(CYGPATH_W) 'src/pcre2test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2test.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2test-pcre2test.Tpo src/$(DEPDIR)/pcre2test-pcre2test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pcre2test.c' object='src/pcre2test-pcre2test.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2test_CFLAGS) $(CFLAGS) -c -o src/pcre2test-pcre2test.obj `if test -f 'src/pcre2test.c'; then $(CYGPATH_W) 'src/pcre2test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2test.c'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf src/.libs src/_libs - -distclean-libtool: - -rm -f libtool config.lt -install-man1: $(dist_man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(dist_man_MANS)'; \ - test -n "$(man1dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.1[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -install-man3: $(dist_man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(dist_man_MANS)'; \ - test -n "$(man3dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.3[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ - done; } - -uninstall-man3: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man3dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.3[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) -install-dist_docDATA: $(dist_doc_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-dist_docDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -install-dist_htmlDATA: $(dist_html_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ - done - -uninstall-dist_htmlDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir) -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) -install-nodist_includeHEADERS: $(nodist_include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-nodist_includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_SCRIPTS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -pcre2_jit_test.log: pcre2_jit_test$(EXEEXT) - @p='pcre2_jit_test$(EXEEXT)'; \ - b='pcre2_jit_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -RunTest.log: RunTest - @p='RunTest'; \ - b='RunTest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -RunGrepTest.log: RunGrepTest - @p='RunGrepTest'; \ - b='RunGrepTest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ - $(HEADERS) -install-binPROGRAMS: install-libLTLIBRARIES - -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f src/$(DEPDIR)/$(am__dirstamp) - -rm -f src/$(am__dirstamp) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -@WITH_GCOV_FALSE@clean-local: -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf src/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-local distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-dist_docDATA install-dist_htmlDATA \ - install-includeHEADERS install-man \ - install-nodist_includeHEADERS install-pkgconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS install-binSCRIPTS \ - install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: install-man1 install-man3 - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf src/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ - uninstall-dist_docDATA uninstall-dist_htmlDATA \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES \ - uninstall-man uninstall-nodist_includeHEADERS \ - uninstall-pkgconfigDATA - -uninstall-man: uninstall-man1 uninstall-man3 - -.MAKE: all check check-am install install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ - check-am clean clean-binPROGRAMS clean-cscope clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-local \ - clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-local distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-binSCRIPTS \ - install-data install-data-am install-dist_docDATA \ - install-dist_htmlDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-man1 install-man3 \ - install-nodist_includeHEADERS install-pdf install-pdf-am \ - install-pkgconfigDATA install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-binSCRIPTS \ - uninstall-dist_docDATA uninstall-dist_htmlDATA \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES \ - uninstall-man uninstall-man1 uninstall-man3 \ - uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA - -.PRECIOUS: Makefile - - -# The only difference between pcre2.h.in and pcre2.h is the setting of the PCRE -# version number. Therefore, we can create the generic version just by copying. - -src/pcre2.h.generic: src/pcre2.h.in configure.ac - rm -f $@ - cp -p src/pcre2.h $@ - -# It is more complicated for config.h.generic. We need the version that results -# from a default configuration so as to get all the default values for PCRE -# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by -# doing a configure in a temporary directory. However, some trickery is needed, -# because the source directory may already be configured. If you just try -# running configure in a new directory, it complains. For this reason, we move -# config.status out of the way while doing the default configuration. The -# resulting config.h is munged by perl to put #ifdefs round any #defines for -# macros with values, and to #undef all boolean macros such as HAVE_xxx and -# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make -# sure that PCRE2_EXP_DEFN is unset (in case it has visibility settings). - -src/config.h.generic: configure.ac - rm -rf $@ _generic - mkdir _generic - cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside - cd _generic && $(abs_top_srcdir)/configure || : - cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs - test -f _generic/src/config.h - perl -n \ - -e 'BEGIN{$$blank=0;}' \ - -e 'if(/PCRE2_EXP_DEFN/){print"/* #undef PCRE2_EXP_DEFN */\n";$$blank=0;next;}' \ - -e 'if(/to make a symbol visible/){next;}' \ - -e 'if(/__attribute__ \(\(visibility/){next;}' \ - -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ - -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ - -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ - -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ - _generic/src/config.h >$@ - rm -rf _generic -@WITH_REBUILD_CHARTABLES_TRUE@src/pcre2_chartables.c: dftables$(EXEEXT) -@WITH_REBUILD_CHARTABLES_TRUE@ rm -f $@ -@WITH_REBUILD_CHARTABLES_TRUE@ ./dftables$(EXEEXT) $@ -@WITH_REBUILD_CHARTABLES_FALSE@src/pcre2_chartables.c: $(srcdir)/src/pcre2_chartables.c.dist -@WITH_REBUILD_CHARTABLES_FALSE@ rm -f $@ -@WITH_REBUILD_CHARTABLES_FALSE@ $(LN_S) $(abs_srcdir)/src/pcre2_chartables.c.dist $(abs_builddir)/src/pcre2_chartables.c - -@WITH_GCOV_TRUE@coverage-check: all -@WITH_GCOV_TRUE@ -$(MAKE) $(AM_MAKEFLAGS) -k check - -@WITH_GCOV_TRUE@coverage-baseline: -@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ -@WITH_GCOV_TRUE@ --directory $(top_builddir) \ -@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ -@WITH_GCOV_TRUE@ --capture \ -@WITH_GCOV_TRUE@ --initial - -@WITH_GCOV_TRUE@coverage-report: -@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ -@WITH_GCOV_TRUE@ --directory $(top_builddir) \ -@WITH_GCOV_TRUE@ --capture \ -@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ -@WITH_GCOV_TRUE@ --test-name "$(COVERAGE_TEST_NAME)" \ -@WITH_GCOV_TRUE@ --no-checksum \ -@WITH_GCOV_TRUE@ --compat-libtool \ -@WITH_GCOV_TRUE@ $(COVERAGE_LCOV_EXTRA_FLAGS) -@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ -@WITH_GCOV_TRUE@ --directory $(top_builddir) \ -@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ -@WITH_GCOV_TRUE@ --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ -@WITH_GCOV_TRUE@ "/tmp/*" \ -@WITH_GCOV_TRUE@ "/usr/include/*" \ -@WITH_GCOV_TRUE@ "$(includedir)/*" -@WITH_GCOV_TRUE@ -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" -@WITH_GCOV_TRUE@ LANG=C $(GENHTML) $(coverage_quiet) \ -@WITH_GCOV_TRUE@ --prefix $(top_builddir) \ -@WITH_GCOV_TRUE@ --output-directory "$(COVERAGE_OUTPUT_DIR)" \ -@WITH_GCOV_TRUE@ --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ -@WITH_GCOV_TRUE@ --show-details "$(COVERAGE_OUTPUT_FILE)" \ -@WITH_GCOV_TRUE@ --legend \ -@WITH_GCOV_TRUE@ $(COVERAGE_GENHTML_EXTRA_FLAGS) -@WITH_GCOV_TRUE@ @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" - -@WITH_GCOV_TRUE@coverage-reset: -@WITH_GCOV_TRUE@ -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) - -@WITH_GCOV_TRUE@coverage-clean-report: -@WITH_GCOV_TRUE@ -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" -@WITH_GCOV_TRUE@ -rm -rf "$(COVERAGE_OUTPUT_DIR)" - -@WITH_GCOV_TRUE@coverage-clean-data: -@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcda" -delete - -@WITH_GCOV_TRUE@coverage-clean: coverage-reset coverage-clean-report coverage-clean-data -@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcno" -delete - -@WITH_GCOV_TRUE@coverage-distclean: coverage-clean - -@WITH_GCOV_TRUE@coverage: coverage-reset coverage-baseline coverage-check coverage-report -@WITH_GCOV_TRUE@clean-local: coverage-clean -@WITH_GCOV_TRUE@distclean-local: coverage-distclean - -@WITH_GCOV_TRUE@.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean - -# Without coverage support, still arrange for 'make distclean' to get rid of -# any coverage files that may have been left from a different configuration. - -@WITH_GCOV_FALSE@coverage: -@WITH_GCOV_FALSE@ @echo "Configuring with --enable-coverage is required to generate code coverage report." - -@WITH_GCOV_FALSE@distclean-local: -@WITH_GCOV_FALSE@ rm -rf $(PACKAGE)-$(VERSION)-coverage* - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/pcre2/NEWS b/pcre2/NEWS deleted file mode 100644 index aaeee5c24..000000000 --- a/pcre2/NEWS +++ /dev/null @@ -1,88 +0,0 @@ -News about PCRE2 releases -------------------------- - -Version 10.21 12-January-2016 ------------------------------ - -1. Many bugs have been fixed. A large number of them were provoked only by very -strange pattern input, and were discovered by fuzzers. Some others were -discovered by code auditing. See ChangeLog for details. - -2. The Unicode tables have been updated to Unicode version 8.0.0. - -3. For Perl compatibility in EBCDIC environments, ranges such as a-z in a -class, where both values are literal letters in the same case, omit the -non-letter EBCDIC code points within the range. - -4. There have been a number of enhancements to the pcre2_substitute() function, -giving more flexibility to replacement facilities. It is now also possible to -cause the function to return the needed buffer size if the one given is too -small. - -5. The PCRE2_ALT_VERBNAMES option causes the "name" parts of special verbs such -as (*THEN:name) to be processed for backslashes and to take note of -PCRE2_EXTENDED. - -6. PCRE2_INFO_HASBACKSLASHC makes it possible for a client to find out if a -pattern uses \C, and --never-backslash-C makes it possible to compile a version -PCRE2 in which the use of \C is always forbidden. - -7. A limit to the length of pattern that can be handled can now be set by -calling pcre2_set_max_pattern_length(). - -8. When matching an unanchored pattern, a match can be required to begin within -a given number of code units after the start of the subject by calling -pcre2_set_offset_limit(). - -9. The pcre2test program has been extended to test new facilities, and it can -now run the tests when LF on its own is not a valid newline sequence. - -10. The RunTest script has also been updated to enable more tests to be run. - -11. There have been some minor performance enhancements. - - -Version 10.20 30-June-2015 --------------------------- - -1. Callouts with string arguments and the pcre2_callout_enumerate() function -have been implemented. - -2. The PCRE2_NEVER_BACKSLASH_C option, which locks out the use of \C, is added. - -3. The PCRE2_ALT_CIRCUMFLEX option lets ^ match after a newline at the end of a -subject in multiline mode. - -4. The way named subpatterns are handled has been refactored. The previous -approach had several bugs. - -5. The handling of \c in EBCDIC environments has been changed to conform to the -perlebcdic document. This is an incompatible change. - -6. Bugs have been mended, many of them discovered by fuzzers. - - -Version 10.10 06-March-2015 ---------------------------- - -1. Serialization and de-serialization functions have been added to the API, -making it possible to save and restore sets of compiled patterns, though -restoration must be done in the same environment that was used for compilation. - -2. The (*NO_JIT) feature has been added; this makes it possible for a pattern -creator to specify that JIT is not to be used. - -3. A number of bugs have been fixed. In particular, bugs that caused building -on Windows using CMake to fail have been mended. - - -Version 10.00 05-January-2015 ------------------------------ - -Version 10.00 is the first release of PCRE2, a revised API for the PCRE -library. Changes prior to 10.00 are logged in the ChangeLog file for the old -API, up to item 20 for release 8.36. New programs are recommended to use the -new library. Programs that use the original (PCRE1) API will need changing -before linking with the new library. - -**** diff --git a/pcre2/NON-AUTOTOOLS-BUILD b/pcre2/NON-AUTOTOOLS-BUILD deleted file mode 100644 index ceb92450c..000000000 --- a/pcre2/NON-AUTOTOOLS-BUILD +++ /dev/null @@ -1,392 +0,0 @@ -Building PCRE2 without using autotools --------------------------------------- - -This document has been converted from the PCRE1 document. I have removed a -number of sections about building in various environments, as they applied only -to PCRE1 and are probably out of date. - -This document contains the following sections: - - General - Generic instructions for the PCRE2 C library - Stack size in Windows environments - Linking programs in Windows environments - Calling conventions in Windows environments - Comments about Win32 builds - Building PCRE2 on Windows with CMake - Testing with RunTest.bat - Building PCRE2 on native z/OS and z/VM - - -GENERAL - -The basic PCRE2 library consists entirely of code written in Standard C, and so -should compile successfully on any system that has a Standard C compiler and -library. - -The PCRE2 distribution includes a "configure" file for use by the -configure/make (autotools) build system, as found in many Unix-like -environments. The README file contains information about the options for -"configure". - -There is also support for CMake, which some users prefer, especially in Windows -environments, though it can also be run in Unix-like environments. See the -section entitled "Building PCRE2 on Windows with CMake" below. - -Versions of src/config.h and src/pcre2.h are distributed in the PCRE2 tarballs -under the names src/config.h.generic and src/pcre2.h.generic. These are -provided for those who build PCRE2 without using "configure" or CMake. If you -use "configure" or CMake, the .generic versions are not used. - - -GENERIC INSTRUCTIONS FOR THE PCRE2 C LIBRARY - -The following are generic instructions for building the PCRE2 C library "by -hand". If you are going to use CMake, this section does not apply to you; you -can skip ahead to the CMake section. - - (1) Copy or rename the file src/config.h.generic as src/config.h, and edit the - macro settings that it contains to whatever is appropriate for your - environment. In particular, you can alter the definition of the NEWLINE - macro to specify what character(s) you want to be interpreted as line - terminators. - - When you compile any of the PCRE2 modules, you must specify - -DHAVE_CONFIG_H to your compiler so that src/config.h is included in the - sources. - - An alternative approach is not to edit src/config.h, but to use -D on the - compiler command line to make any changes that you need to the - configuration options. In this case -DHAVE_CONFIG_H must not be set. - - NOTE: There have been occasions when the way in which certain parameters - in src/config.h are used has changed between releases. (In the - configure/make world, this is handled automatically.) When upgrading to a - new release, you are strongly advised to review src/config.h.generic - before re-using what you had previously. - - (2) Copy or rename the file src/pcre2.h.generic as src/pcre2.h. - - (3) EITHER: - Copy or rename file src/pcre2_chartables.c.dist as - src/pcre2_chartables.c. - - OR: - Compile src/dftables.c as a stand-alone program (using -DHAVE_CONFIG_H - if you have set up src/config.h), and then run it with the single - argument "src/pcre2_chartables.c". This generates a set of standard - character tables and writes them to that file. The tables are generated - using the default C locale for your system. If you want to use a locale - that is specified by LC_xxx environment variables, add the -L option to - the dftables command. You must use this method if you are building on a - system that uses EBCDIC code. - - The tables in src/pcre2_chartables.c are defaults. The caller of PCRE2 can - specify alternative tables at run time. - - (4) For an 8-bit library, compile the following source files from the src - directory, setting -DPCRE2_CODE_UNIT_WIDTH=8 as a compiler option. Also - set -DHAVE_CONFIG_H if you have set up src/config.h with your - configuration, or else use other -D settings to change the configuration - as required. - - pcre2_auto_possess.c - pcre2_chartables.c - pcre2_compile.c - pcre2_config.c - pcre2_context.c - pcre2_dfa_match.c - pcre2_error.c - pcre2_find_bracket.c - pcre2_jit_compile.c - pcre2_maketables.c - pcre2_match.c - pcre2_match_data.c - pcre2_newline.c - pcre2_ord2utf.c - pcre2_pattern_info.c - pcre2_serialize.c - pcre2_string_utils.c - pcre2_study.c - pcre2_substitute.c - pcre2_substring.c - pcre2_tables.c - pcre2_ucd.c - pcre2_valid_utf.c - pcre2_xclass.c - - Make sure that you include -I. in the compiler command (or equivalent for - an unusual compiler) so that all included PCRE2 header files are first - sought in the src directory under the current directory. Otherwise you run - the risk of picking up a previously-installed file from somewhere else. - - Note that you must compile pcre2_jit_compile.c, even if you have not - defined SUPPORT_JIT in src/config.h, because when JIT support is not - configured, dummy functions are compiled. When JIT support IS configured, - pcre2_compile.c #includes other files from the sljit subdirectory, where - there should be 16 files, all of whose names begin with "sljit". It also - #includes src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should - not compile these yourself. - - (5) Now link all the compiled code into an object library in whichever form - your system keeps such libraries. This is the basic PCRE2 C 8-bit library. - If your system has static and shared libraries, you may have to do this - once for each type. - - (6) If you want to build a 16-bit library or 32-bit library (as well as, or - instead of the 8-bit library) just supply 16 or 32 as the value of - -DPCRE2_CODE_UNIT_WIDTH when you are compiling. - - (7) If you want to build the POSIX wrapper functions (which apply only to the - 8-bit library), ensure that you have the src/pcre2posix.h file and then - compile src/pcre2posix.c. Link the result (on its own) as the pcre2posix - library. - - (8) The pcre2test program can be linked with any combination of the 8-bit, - 16-bit and 32-bit libraries (depending on what you selected in - src/config.h). Compile src/pcre2test.c; don't forget -DHAVE_CONFIG_H if - necessary, but do NOT define PCRE2_CODE_UNIT_WIDTH. Then link with the - appropriate library/ies. If you compiled an 8-bit library, pcre2test also - needs the pcre2posix wrapper library. - - (9) Run pcre2test on the testinput files in the testdata directory, and check - that the output matches the corresponding testoutput files. There are - comments about what each test does in the section entitled "Testing PCRE2" - in the README file. If you compiled more than one of the 8-bit, 16-bit and - 32-bit libraries, you need to run pcre2test with the -16 option to do - 16-bit tests and with the -32 option to do 32-bit tests. - - Some tests are relevant only when certain build-time options are selected. - For example, test 4 is for Unicode support, and will not run if you have - built PCRE2 without it. See the comments at the start of each testinput - file. If you have a suitable Unix-like shell, the RunTest script will run - the appropriate tests for you. The command "RunTest list" will output a - list of all the tests. - - Note that the supplied files are in Unix format, with just LF characters - as line terminators. You may need to edit them to change this if your - system uses a different convention. - -(10) If you have built PCRE2 with SUPPORT_JIT, the JIT features can be tested - by running pcre2test with the -jit option. This is done automatically by - the RunTest script. You might also like to build and run the freestanding - JIT test program, src/pcre2_jit_test.c. - -(11) If you want to use the pcre2grep command, compile and link - src/pcre2grep.c; it uses only the basic 8-bit PCRE2 library (it does not - need the pcre2posix library). - - -STACK SIZE IN WINDOWS ENVIRONMENTS - -The default processor stack size of 1Mb in some Windows environments is too -small for matching patterns that need much recursion. In particular, test 2 may -fail because of this. Normally, running out of stack causes a crash, but there -have been cases where the test program has just died silently. See your linker -documentation for how to increase stack size if you experience problems. If you -are using CMake (see "BUILDING PCRE2 ON WINDOWS WITH CMAKE" below) and the gcc -compiler, you can increase the stack size for pcre2test and pcre2grep by -setting the CMAKE_EXE_LINKER_FLAGS variable to "-Wl,--stack,8388608" (for -example). The Linux default of 8Mb is a reasonable choice for the stack, though -even that can be too small for some pattern/subject combinations. - -PCRE2 has a compile configuration option to disable the use of stack for -recursion so that heap is used instead. However, pattern matching is -significantly slower when this is done. There is more about stack usage in the -"pcre2stack" documentation. - - -LINKING PROGRAMS IN WINDOWS ENVIRONMENTS - -If you want to statically link a program against a PCRE2 library in the form of -a non-dll .a file, you must define PCRE2_STATIC before including src/pcre2.h. - - -CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS - -It is possible to compile programs to use different calling conventions using -MSVC. Search the web for "calling conventions" for more information. To make it -easier to change the calling convention for the exported functions in the -PCRE2 library, the macro PCRE2_CALL_CONVENTION is present in all the external -definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is -not set, it defaults to empty; the default calling convention is then used -(which is what is wanted most of the time). - - -COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE2 ON WINDOWS WITH CMAKE") - -There are two ways of building PCRE2 using the "configure, make, make install" -paradigm on Windows systems: using MinGW or using Cygwin. These are not at all -the same thing; they are completely different from each other. There is also -support for building using CMake, which some users find a more straightforward -way of building PCRE2 under Windows. - -The MinGW home page (http://www.mingw.org/) says this: - - MinGW: A collection of freely available and freely distributable Windows - specific header files and import libraries combined with GNU toolsets that - allow one to produce native Windows programs that do not rely on any - 3rd-party C runtime DLLs. - -The Cygwin home page (http://www.cygwin.com/) says this: - - Cygwin is a Linux-like environment for Windows. It consists of two parts: - - . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing - substantial Linux API functionality - - . A collection of tools which provide Linux look and feel. - -On both MinGW and Cygwin, PCRE2 should build correctly using: - - ./configure && make && make install - -This should create two libraries called libpcre2-8 and libpcre2-posix. These -are independent libraries: when you link with libpcre2-posix you must also link -with libpcre2-8, which contains the basic functions. - -Using Cygwin's compiler generates libraries and executables that depend on -cygwin1.dll. If a library that is generated this way is distributed, -cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL -licence, this forces not only PCRE2 to be under the GPL, but also the entire -application. A distributor who wants to keep their own code proprietary must -purchase an appropriate Cygwin licence. - -MinGW has no such restrictions. The MinGW compiler generates a library or -executable that can run standalone on Windows without any third party dll or -licensing issues. - -But there is more complication: - -If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is -to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a -front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's -gcc and MinGW's gcc). So, a user can: - -. Build native binaries by using MinGW or by getting Cygwin and using - -mno-cygwin. - -. Build binaries that depend on cygwin1.dll by using Cygwin with the normal - compiler flags. - -The test files that are supplied with PCRE2 are in UNIX format, with LF -characters as line terminators. Unless your PCRE2 library uses a default -newline option that includes LF as a valid newline, it may be necessary to -change the line terminators in the test files to get some of the tests to work. - - -BUILDING PCRE2 ON WINDOWS WITH CMAKE - -CMake is an alternative configuration facility that can be used instead of -"configure". CMake creates project files (make files, solution files, etc.) -tailored to numerous development environments, including Visual Studio, -Borland, Msys, MinGW, NMake, and Unix. If possible, use short paths with no -spaces in the names for your CMake installation and your PCRE2 source and build -directories. - -The following instructions were contributed by a PCRE1 user, but they should -also work for PCRE2. If they are not followed exactly, errors may occur. In the -event that errors do occur, it is recommended that you delete the CMake cache -before attempting to repeat the CMake build process. In the CMake GUI, the -cache can be deleted by selecting "File > Delete Cache". - -1. Install the latest CMake version available from http://www.cmake.org/, and - ensure that cmake\bin is on your path. - -2. Unzip (retaining folder structure) the PCRE2 source tree into a source - directory such as C:\pcre2. You should ensure your local date and time - is not earlier than the file dates in your source dir if the release is - very new. - -3. Create a new, empty build directory, preferably a subdirectory of the - source dir. For example, C:\pcre2\pcre2-xx\build. - -4. Run cmake-gui from the Shell envirornment of your build tool, for example, - Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. Do not try - to start Cmake from the Windows Start menu, as this can lead to errors. - -5. Enter C:\pcre2\pcre2-xx and C:\pcre2\pcre2-xx\build for the source and - build directories, respectively. - -6. Hit the "Configure" button. - -7. Select the particular IDE / build tool that you are using (Visual - Studio, MSYS makefiles, MinGW makefiles, etc.) - -8. The GUI will then list several configuration options. This is where - you can disable Unicode support or select other PCRE2 optional features. - -9. Hit "Configure" again. The adjacent "Generate" button should now be - active. - -10. Hit "Generate". - -11. The build directory should now contain a usable build system, be it a - solution file for Visual Studio, makefiles for MinGW, etc. Exit from - cmake-gui and use the generated build system with your compiler or IDE. - E.g., for MinGW you can run "make", or for Visual Studio, open the PCRE2 - solution, select the desired configuration (Debug, or Release, etc.) and - build the ALL_BUILD project. - -12. If during configuration with cmake-gui you've elected to build the test - programs, you can execute them by building the test project. E.g., for - MinGW: "make test"; for Visual Studio build the RUN_TESTS project. The - most recent build configuration is targeted by the tests. A summary of - test results is presented. Complete test output is subsequently - available for review in Testing\Temporary under your build dir. - - -TESTING WITH RUNTEST.BAT - -If configured with CMake, building the test project ("make test" or building -ALL_TESTS in Visual Studio) creates (and runs) pcre2_test.bat (and depending -on your configuration options, possibly other test programs) in the build -directory. The pcre2_test.bat script runs RunTest.bat with correct source and -exe paths. - -For manual testing with RunTest.bat, provided the build dir is a subdirectory -of the source directory: Open command shell window. Chdir to the location -of your pcre2test.exe and pcre2grep.exe programs. Call RunTest.bat with -"..\RunTest.Bat" or "..\..\RunTest.bat" as appropriate. - -To run only a particular test with RunTest.Bat provide a test number argument. - -Otherwise: - -1. Copy RunTest.bat into the directory where pcre2test.exe and pcre2grep.exe - have been created. - -2. Edit RunTest.bat to indentify the full or relative location of - the pcre2 source (wherein which the testdata folder resides), e.g.: - - set srcdir=C:\pcre2\pcre2-10.00 - -3. In a Windows command environment, chdir to the location of your bat and - exe programs. - -4. Run RunTest.bat. Test outputs will automatically be compared to expected - results, and discrepancies will be identified in the console output. - -To independently test the just-in-time compiler, run pcre2_jit_test.exe. - - -BUILDING PCRE2 ON NATIVE Z/OS AND Z/VM - -z/OS and z/VM are operating systems for mainframe computers, produced by IBM. -The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and -applications can be supported through UNIX System Services, and in such an -environment PCRE2 can be built in the same way as in other systems. However, in -native z/OS (without UNIX System Services) and in z/VM, special ports are -required. For details, please see this web site: - - http://www.zaconsultants.net - -The site currently has ports for PCRE1 releases, but PCRE2 should follow in due -course. - -You may also download PCRE1 from WWW.CBTTAPE.ORG, file 882. Everything, source -and executable, is in EBCDIC and native z/OS file formats and this is the -recommended download site. - -============================= -Last Updated: 16 July 2015 diff --git a/pcre2/PrepareRelease b/pcre2/PrepareRelease deleted file mode 100755 index 114fce01d..000000000 --- a/pcre2/PrepareRelease +++ /dev/null @@ -1,235 +0,0 @@ -#/bin/sh - -# Script to prepare the files for building a PCRE2 release. It does some -# processing of the documentation, detrails files, and creates pcre2.h.generic -# and config.h.generic (for use by builders who can't run ./configure). - -# You must run this script before runnning "make dist". If its first argument -# is "doc", it stops after preparing the documentation. There are no other -# arguments. The script makes use of the following files: - -# 132html A Perl script that converts a .1 or .3 man page into HTML. It -# "knows" the relevant troff constructs that are used in the PCRE2 -# man pages. - -# CheckMan A Perl script that checks man pages for typos in the mark up. - -# CleanTxt A Perl script that cleans up the output of "nroff -man" by -# removing backspaces and other redundant text so as to produce -# a readable .txt file. - -# Detrail A Perl script that removes trailing spaces from files. - -# doc/index.html.src -# A file that is copied as index.html into the doc/html directory -# when the HTML documentation is built. It works like this so that -# doc/html can be deleted and re-created from scratch. - -# README & NON-AUTOTOOLS-BUILD -# These files are copied into the doc/html directory, with .txt -# extensions so that they can by hyperlinked from the HTML -# documentation, because some people just go to the HTML without -# looking for text files. - - -# First, sort out the documentation. Remove pcre2demo.3 first because it won't -# pass the markup check (it is created below, using markup that none of the -# other pages use). - -cd doc -echo Processing documentation - -/bin/rm -f pcre2demo.3 - -# Check the remaining man pages - -perl ../CheckMan *.1 *.3 -if [ $? != 0 ] ; then exit 1; fi - -# Make Text form of the documentation. It needs some mangling to make it -# tidy for online reading. Concatenate all the .3 stuff, but omit the -# individual function pages. - -cat <pcre2.txt ------------------------------------------------------------------------------ -This file contains a concatenation of the PCRE2 man pages, converted to plain -text format for ease of searching with a text editor, or for use on systems -that do not have a man page processor. The small individual files that give -synopses of each function in the library have not been included. Neither has -the pcre2demo program. There are separate text files for the pcre2grep and -pcre2test commands. ------------------------------------------------------------------------------ - - -End - -echo "Making pcre2.txt" -for file in pcre2 pcre2api pcre2build pcre2callout pcre2compat pcre2jit \ - pcre2limits pcre2matching pcre2partial pcre2pattern pcre2perform \ - pcre2posix pcre2sample pcre2serialize pcre2stack pcre2syntax \ - pcre2unicode ; do - echo " Processing $file.3" - nroff -c -man $file.3 >$file.rawtxt - perl ../CleanTxt <$file.rawtxt >>pcre2.txt - /bin/rm $file.rawtxt - echo "------------------------------------------------------------------------------" >>pcre2.txt - if [ "$file" != "pcre2sample" ] ; then - echo " " >>pcre2.txt - echo " " >>pcre2.txt - fi -done - -# The three commands -for file in pcre2test pcre2grep pcre2-config ; do - echo Making $file.txt - nroff -c -man $file.1 >$file.rawtxt - perl ../CleanTxt <$file.rawtxt >$file.txt - /bin/rm $file.rawtxt -done - - -# Make pcre2demo.3 from the pcre2demo.c source file - -echo "Making pcre2demo.3" -perl <<"END" >pcre2demo.3 - open(IN, "../src/pcre2demo.c") || die "Failed to open src/pcre2demo.c\n"; - open(OUT, ">pcre2demo.3") || die "Failed to open pcre2demo.3\n"; - print OUT ".\\\" Start example.\n" . - ".de EX\n" . - ". nr mE \\\\n(.f\n" . - ". nf\n" . - ". nh\n" . - ". ft CW\n" . - "..\n" . - ".\n" . - ".\n" . - ".\\\" End example.\n" . - ".de EE\n" . - ". ft \\\\n(mE\n" . - ". fi\n" . - ". hy \\\\n(HY\n" . - "..\n" . - ".\n" . - ".EX\n" ; - while () - { - s/\\/\\e/g; - print OUT; - } - print OUT ".EE\n"; - close(IN); - close(OUT); -END -if [ $? != 0 ] ; then exit 1; fi - - -# Make HTML form of the documentation. - -echo "Making HTML documentation" -/bin/rm html/* -cp index.html.src html/index.html -cp ../README html/README.txt -cp ../NON-AUTOTOOLS-BUILD html/NON-AUTOTOOLS-BUILD.txt - -for file in *.1 ; do - base=`basename $file .1` - echo " Making $base.html" - perl ../132html -toc $base <$file >html/$base.html -done - -# Exclude table of contents for function summaries. It seems that expr -# forces an anchored regex. Also exclude them for small pages that have -# only one section. - -for file in *.3 ; do - base=`basename $file .3` - toc=-toc - if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi - if [ "$base" = "pcre2sample" ] || \ - [ "$base" = "pcre2stack" ] || \ - [ "$base" = "pcre2compat" ] || \ - [ "$base" = "pcre2limits" ] || \ - [ "$base" = "pcre2unicode" ] ; then - toc="" - fi - echo " Making $base.html" - perl ../132html $toc $base <$file >html/$base.html - if [ $? != 0 ] ; then exit 1; fi -done - -# End of documentation processing; stop if only documentation required. - -cd .. -echo Documentation done -if [ "$1" = "doc" ] ; then exit; fi - -# These files are detrailed; do not detrail the test data because there may be -# significant trailing spaces. Do not detrail RunTest.bat, because it has CRLF -# line endings and the detrail script removes all trailing white space. The -# configure files are also omitted from the detrailing. - -files="\ - Makefile.am \ - configure.ac \ - README \ - LICENCE \ - COPYING \ - AUTHORS \ - NEWS \ - NON-AUTOTOOLS-BUILD \ - INSTALL \ - 132html \ - CleanTxt \ - Detrail \ - ChangeLog \ - CMakeLists.txt \ - RunGrepTest \ - RunTest \ - pcre2-config.in \ - perltest.sh \ - libpcre2-8.pc.in \ - libpcre2-16.pc.in \ - libpcre2-32.pc.in \ - libpcre2-posix.pc.in \ - src/dftables.c \ - src/pcre2.h.in \ - src/pcre2_auto_possess.c \ - src/pcre2_compile.c \ - src/pcre2_config.c \ - src/pcre2_context.c \ - src/pcre2_dfa_match.c \ - src/pcre2_error.c \ - src/pcre2_find_bracket.c \ - src/pcre2_internal.h \ - src/pcre2_intmodedep.h \ - src/pcre2_jit_compile.c \ - src/pcre2_jit_match.c \ - src/pcre2_jit_misc.c \ - src/pcre2_jit_test.c \ - src/pcre2_maketables.c \ - src/pcre2_match.c \ - src/pcre2_match_data.c \ - src/pcre2_newline.c \ - src/pcre2_ord2utf.c \ - src/pcre2_pattern_info.c \ - src/pcre2_printint.c \ - src/pcre2_string_utils.c \ - src/pcre2_study.c \ - src/pcre2_substring.c \ - src/pcre2_tables.c \ - src/pcre2_ucd.c \ - src/pcre2_ucp.h \ - src/pcre2_valid_utf.c \ - src/pcre2_xclass.c \ - src/pcre2demo.c \ - src/pcre2grep.c \ - src/pcre2posix.c \ - src/pcre2posix.h \ - src/pcre2test.c" - -echo Detrailing -perl ./Detrail $files doc/p* doc/html/* - -echo Done - -#End diff --git a/pcre2/README b/pcre2/README deleted file mode 100644 index 48d2ffdd7..000000000 --- a/pcre2/README +++ /dev/null @@ -1,843 +0,0 @@ -README file for PCRE2 (Perl-compatible regular expression library) ------------------------------------------------------------------- - -PCRE2 is a re-working of the original PCRE library to provide an entirely new -API. The latest release of PCRE2 is always available in three alternative -formats from: - - ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.tar.gz - ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.tar.bz2 - ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-xxx.zip - -There is a mailing list for discussion about the development of PCRE (both the -original and new APIs) at pcre-dev@exim.org. You can access the archives and -subscribe or manage your subscription here: - - https://lists.exim.org/mailman/listinfo/pcre-dev - -Please read the NEWS file if you are upgrading from a previous release. -The contents of this README file are: - - The PCRE2 APIs - Documentation for PCRE2 - Contributions by users of PCRE2 - Building PCRE2 on non-Unix-like systems - Building PCRE2 without using autotools - Building PCRE2 using autotools - Retrieving configuration information - Shared libraries - Cross-compiling using autotools - Making new tarballs - Testing PCRE2 - Character tables - File manifest - - -The PCRE2 APIs --------------- - -PCRE2 is written in C, and it has its own API. There are three sets of -functions, one for the 8-bit library, which processes strings of bytes, one for -the 16-bit library, which processes strings of 16-bit values, and one for the -32-bit library, which processes strings of 32-bit values. There are no C++ -wrappers. - -The distribution does contain a set of C wrapper functions for the 8-bit -library that are based on the POSIX regular expression API (see the pcre2posix -man page). These can be found in a library called libpcre2posix. Note that this -just provides a POSIX calling interface to PCRE2; the regular expressions -themselves still follow Perl syntax and semantics. The POSIX API is restricted, -and does not give full access to all of PCRE2's facilities. - -The header file for the POSIX-style functions is called pcre2posix.h. The -official POSIX name is regex.h, but I did not want to risk possible problems -with existing files of that name by distributing it that way. To use PCRE2 with -an existing program that uses the POSIX API, pcre2posix.h will have to be -renamed or pointed at by a link. - -If you are using the POSIX interface to PCRE2 and there is already a POSIX -regex library installed on your system, as well as worrying about the regex.h -header file (as mentioned above), you must also take care when linking programs -to ensure that they link with PCRE2's libpcre2posix library. Otherwise they may -pick up the POSIX functions of the same name from the other library. - -One way of avoiding this confusion is to compile PCRE2 with the addition of --Dregcomp=PCRE2regcomp (and similarly for the other POSIX functions) to the -compiler flags (CFLAGS if you are using "configure" -- see below). This has the -effect of renaming the functions so that the names no longer clash. Of course, -you have to do the same thing for your applications, or write them using the -new names. - - -Documentation for PCRE2 ------------------------ - -If you install PCRE2 in the normal way on a Unix-like system, you will end up -with a set of man pages whose names all start with "pcre2". The one that is -just called "pcre2" lists all the others. In addition to these man pages, the -PCRE2 documentation is supplied in two other forms: - - 1. There are files called doc/pcre2.txt, doc/pcre2grep.txt, and - doc/pcre2test.txt in the source distribution. The first of these is a - concatenation of the text forms of all the section 3 man pages except the - listing of pcre2demo.c and those that summarize individual functions. The - other two are the text forms of the section 1 man pages for the pcre2grep - and pcre2test commands. These text forms are provided for ease of scanning - with text editors or similar tools. They are installed in - /share/doc/pcre2, where is the installation prefix - (defaulting to /usr/local). - - 2. A set of files containing all the documentation in HTML form, hyperlinked - in various ways, and rooted in a file called index.html, is distributed in - doc/html and installed in /share/doc/pcre2/html. - - -Building PCRE2 on non-Unix-like systems ---------------------------------------- - -For a non-Unix-like system, please read the comments in the file -NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and -"make" you may be able to build PCRE2 using autotools in the same way as for -many Unix-like systems. - -PCRE2 can also be configured using CMake, which can be run in various ways -(command line, GUI, etc). This creates Makefiles, solution files, etc. The file -NON-AUTOTOOLS-BUILD has information about CMake. - -PCRE2 has been compiled on many different operating systems. It should be -straightforward to build PCRE2 on any system that has a Standard C compiler and -library, because it uses only Standard C functions. - - -Building PCRE2 without using autotools --------------------------------------- - -The use of autotools (in particular, libtool) is problematic in some -environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD -file for ways of building PCRE2 without using autotools. - - -Building PCRE2 using autotools ------------------------------- - -The following instructions assume the use of the widely used "configure; make; -make install" (autotools) process. - -To build PCRE2 on system that supports autotools, first run the "configure" -command from the PCRE2 distribution directory, with your current directory set -to the directory where you want the files to be created. This command is a -standard GNU "autoconf" configuration script, for which generic instructions -are supplied in the file INSTALL. - -Most commonly, people build PCRE2 within its own distribution directory, and in -this case, on many systems, just running "./configure" is sufficient. However, -the usual methods of changing standard defaults are available. For example: - -CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local - -This command specifies that the C compiler should be run with the flags '-O2 --Wall' instead of the default, and that "make install" should install PCRE2 -under /opt/local instead of the default /usr/local. - -If you want to build in a different directory, just run "configure" with that -directory as current. For example, suppose you have unpacked the PCRE2 source -into /source/pcre2/pcre2-xxx, but you want to build it in -/build/pcre2/pcre2-xxx: - -cd /build/pcre2/pcre2-xxx -/source/pcre2/pcre2-xxx/configure - -PCRE2 is written in C and is normally compiled as a C library. However, it is -possible to build it as a C++ library, though the provided building apparatus -does not have any features to support this. - -There are some optional features that can be included or omitted from the PCRE2 -library. They are also documented in the pcre2build man page. - -. By default, both shared and static libraries are built. You can change this - by adding one of these options to the "configure" command: - - --disable-shared - --disable-static - - (See also "Shared libraries on Unix-like systems" below.) - -. By default, only the 8-bit library is built. If you add --enable-pcre2-16 to - the "configure" command, the 16-bit library is also built. If you add - --enable-pcre2-32 to the "configure" command, the 32-bit library is also - built. If you want only the 16-bit or 32-bit library, use --disable-pcre2-8 - to disable building the 8-bit library. - -. If you want to include support for just-in-time compiling, which can give - large performance improvements on certain platforms, add --enable-jit to the - "configure" command. This support is available only for certain hardware - architectures. If you try to enable it on an unsupported architecture, there - will be a compile time error. - -. When JIT support is enabled, pcre2grep automatically makes use of it, unless - you add --disable-pcre2grep-jit to the "configure" command. - -. If you do not want to make use of the support for UTF-8 Unicode character - strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit - library, or UTF-32 Unicode character strings in the 32-bit library, you can - add --disable-unicode to the "configure" command. This reduces the size of - the libraries. It is not possible to configure one library with Unicode - support, and another without, in the same configuration. - - When Unicode support is available, the use of a UTF encoding still has to be - enabled by setting the PCRE2_UTF option at run time or starting a pattern - with (*UTF). When PCRE2 is compiled with Unicode support, its input can only - either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms. It is - not possible to use both --enable-unicode and --enable-ebcdic at the same - time. - - As well as supporting UTF strings, Unicode support includes support for the - \P, \p, and \X sequences that recognize Unicode character properties. - However, only the basic two-letter properties such as Lu are supported. - Escape sequences such as \d and \w in patterns do not by default make use of - Unicode properties, but can be made to do so by setting the PCRE2_UCP option - or starting a pattern with (*UCP). - -. You can build PCRE2 to recognize either CR or LF or the sequence CRLF, or any - of the preceding, or any of the Unicode newline sequences, as indicating the - end of a line. Whatever you specify at build time is the default; the caller - of PCRE2 can change the selection at run time. The default newline indicator - is a single LF character (the Unix standard). You can specify the default - newline indicator by adding --enable-newline-is-cr, --enable-newline-is-lf, - --enable-newline-is-crlf, --enable-newline-is-anycrlf, or - --enable-newline-is-any to the "configure" command, respectively. - - If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of - the standard tests will fail, because the lines in the test files end with - LF. Even if the files are edited to change the line endings, there are likely - to be some failures. With --enable-newline-is-anycrlf or - --enable-newline-is-any, many tests should succeed, but there may be some - failures. - -. By default, the sequence \R in a pattern matches any Unicode line ending - sequence. This is independent of the option specifying what PCRE2 considers - to be the end of a line (see above). However, the caller of PCRE2 can - restrict \R to match only CR, LF, or CRLF. You can make this the default by - adding --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R"). - -. In a pattern, the escape sequence \C matches a single code unit, even in a - UTF mode. This can be dangerous because it breaks up multi-code-unit - characters. You can build PCRE2 with the use of \C permanently locked out by - adding --enable-never-backslash-C (note the upper case C) to the "configure" - command. When \C is allowed by the library, individual applications can lock - it out by calling pcre2_compile() with the PCRE2_NEVER_BACKSLASH_C option. - -. PCRE2 has a counter that limits the depth of nesting of parentheses in a - pattern. This limits the amount of system stack that a pattern uses when it - is compiled. The default is 250, but you can change it by setting, for - example, - - --with-parens-nest-limit=500 - -. PCRE2 has a counter that can be set to limit the amount of resources it uses - when matching a pattern. If the limit is exceeded during a match, the match - fails. The default is ten million. You can change the default by setting, for - example, - - --with-match-limit=500000 - - on the "configure" command. This is just the default; individual calls to - pcre2_match() can supply their own value. There is more discussion on the - pcre2api man page. - -. There is a separate counter that limits the depth of recursive function calls - during a matching process. This also has a default of ten million, which is - essentially "unlimited". You can change the default by setting, for example, - - --with-match-limit-recursion=500000 - - Recursive function calls use up the runtime stack; running out of stack can - cause programs to crash in strange ways. There is a discussion about stack - sizes in the pcre2stack man page. - -. In the 8-bit library, the default maximum compiled pattern size is around - 64K. You can increase this by adding --with-link-size=3 to the "configure" - command. PCRE2 then uses three bytes instead of two for offsets to different - parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is - the same as --with-link-size=4, which (in both libraries) uses four-byte - offsets. Increasing the internal link size reduces performance in the 8-bit - and 16-bit libraries. In the 32-bit library, the link size setting is - ignored, as 4-byte offsets are always used. - -. You can build PCRE2 so that its internal match() function that is called from - pcre2_match() does not call itself recursively. Instead, it uses memory - blocks obtained from the heap to save data that would otherwise be saved on - the stack. To build PCRE2 like this, use - - --disable-stack-for-recursion - - on the "configure" command. PCRE2 runs more slowly in this mode, but it may - be necessary in environments with limited stack sizes. This applies only to - the normal execution of the pcre2_match() function; if JIT support is being - successfully used, it is not relevant. Equally, it does not apply to - pcre2_dfa_match(), which does not use deeply nested recursion. There is a - discussion about stack sizes in the pcre2stack man page. - -. For speed, PCRE2 uses four tables for manipulating and identifying characters - whose code point values are less than 256. By default, it uses a set of - tables for ASCII encoding that is part of the distribution. If you specify - - --enable-rebuild-chartables - - a program called dftables is compiled and run in the default C locale when - you obey "make". It builds a source file called pcre2_chartables.c. If you do - not specify this option, pcre2_chartables.c is created as a copy of - pcre2_chartables.c.dist. See "Character tables" below for further - information. - -. It is possible to compile PCRE2 for use on systems that use EBCDIC as their - character code (as opposed to ASCII/Unicode) by specifying - - --enable-ebcdic --disable-unicode - - This automatically implies --enable-rebuild-chartables (see above). However, - when PCRE2 is built this way, it always operates in EBCDIC. It cannot support - both EBCDIC and UTF-8/16/32. There is a second option, --enable-ebcdic-nl25, - which specifies that the code value for the EBCDIC NL character is 0x25 - instead of the default 0x15. - -. If you specify --enable-debug, additional debugging code is included in the - build. This option is intended for use by the PCRE2 maintainers. - -. In environments where valgrind is installed, if you specify - - --enable-valgrind - - PCRE2 will use valgrind annotations to mark certain memory regions as - unaddressable. This allows it to detect invalid memory accesses, and is - mostly useful for debugging PCRE2 itself. - -. In environments where the gcc compiler is used and lcov version 1.6 or above - is installed, if you specify - - --enable-coverage - - the build process implements a code coverage report for the test suite. The - report is generated by running "make coverage". If ccache is installed on - your system, it must be disabled when building PCRE2 for coverage reporting. - You can do this by setting the environment variable CCACHE_DISABLE=1 before - running "make" to build PCRE2. There is more information about coverage - reporting in the "pcre2build" documentation. - -. The pcre2grep program currently supports only 8-bit data files, and so - requires the 8-bit PCRE2 library. It is possible to compile pcre2grep to use - libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by - specifying one or both of - - --enable-pcre2grep-libz - --enable-pcre2grep-libbz2 - - Of course, the relevant libraries must be installed on your system. - -. The default size (in bytes) of the internal buffer used by pcre2grep can be - set by, for example: - - --with-pcre2grep-bufsize=51200 - - The value must be a plain integer. The default is 20480. - -. It is possible to compile pcre2test so that it links with the libreadline - or libedit libraries, by specifying, respectively, - - --enable-pcre2test-libreadline or --enable-pcre2test-libedit - - If this is done, when pcre2test's input is from a terminal, it reads it using - the readline() function. This provides line-editing and history facilities. - Note that libreadline is GPL-licenced, so if you distribute a binary of - pcre2test linked in this way, there may be licensing issues. These can be - avoided by linking with libedit (which has a BSD licence) instead. - - Enabling libreadline causes the -lreadline option to be added to the - pcre2test build. In many operating environments with a sytem-installed - readline library this is sufficient. However, in some environments (e.g. if - an unmodified distribution version of readline is in use), it may be - necessary to specify something like LIBS="-lncurses" as well. This is - because, to quote the readline INSTALL, "Readline uses the termcap functions, - but does not link with the termcap or curses library itself, allowing - applications which link with readline the to choose an appropriate library." - If you get error messages about missing functions tgetstr, tgetent, tputs, - tgetflag, or tgoto, this is the problem, and linking with the ncurses library - should fix it. - -The "configure" script builds the following files for the basic C library: - -. Makefile the makefile that builds the library -. src/config.h build-time configuration options for the library -. src/pcre2.h the public PCRE2 header file -. pcre2-config script that shows the building settings such as CFLAGS - that were set for "configure" -. libpcre2-8.pc ) -. libpcre2-16.pc ) data for the pkg-config command -. libpcre2-32.pc ) -. libpcre2-posix.pc ) -. libtool script that builds shared and/or static libraries - -Versions of config.h and pcre2.h are distributed in the src directory of PCRE2 -tarballs under the names config.h.generic and pcre2.h.generic. These are -provided for those who have to build PCRE2 without using "configure" or CMake. -If you use "configure" or CMake, the .generic versions are not used. - -The "configure" script also creates config.status, which is an executable -script that can be run to recreate the configuration, and config.log, which -contains compiler output from tests that "configure" runs. - -Once "configure" has run, you can run "make". This builds whichever of the -libraries libpcre2-8, libpcre2-16 and libpcre2-32 are configured, and a test -program called pcre2test. If you enabled JIT support with --enable-jit, another -test program called pcre2_jit_test is built as well. If the 8-bit library is -built, libpcre2-posix and the pcre2grep command are also built. Running -"make" with the -j option may speed up compilation on multiprocessor systems. - -The command "make check" runs all the appropriate tests. Details of the PCRE2 -tests are given below in a separate section of this document. The -j option of -"make" can also be used when running the tests. - -You can use "make install" to install PCRE2 into live directories on your -system. The following are installed (file names are all relative to the - that is set when "configure" is run): - - Commands (bin): - pcre2test - pcre2grep (if 8-bit support is enabled) - pcre2-config - - Libraries (lib): - libpcre2-8 (if 8-bit support is enabled) - libpcre2-16 (if 16-bit support is enabled) - libpcre2-32 (if 32-bit support is enabled) - libpcre2-posix (if 8-bit support is enabled) - - Configuration information (lib/pkgconfig): - libpcre2-8.pc - libpcre2-16.pc - libpcre2-32.pc - libpcre2-posix.pc - - Header files (include): - pcre2.h - pcre2posix.h - - Man pages (share/man/man{1,3}): - pcre2grep.1 - pcre2test.1 - pcre2-config.1 - pcre2.3 - pcre2*.3 (lots more pages, all starting "pcre2") - - HTML documentation (share/doc/pcre2/html): - index.html - *.html (lots more pages, hyperlinked from index.html) - - Text file documentation (share/doc/pcre2): - AUTHORS - COPYING - ChangeLog - LICENCE - NEWS - README - pcre2.txt (a concatenation of the man(3) pages) - pcre2test.txt the pcre2test man page - pcre2grep.txt the pcre2grep man page - pcre2-config.txt the pcre2-config man page - -If you want to remove PCRE2 from your system, you can run "make uninstall". -This removes all the files that "make install" installed. However, it does not -remove any directories, because these are often shared with other programs. - - -Retrieving configuration information ------------------------------------- - -Running "make install" installs the command pcre2-config, which can be used to -recall information about the PCRE2 configuration and installation. For example: - - pcre2-config --version - -prints the version number, and - - pcre2-config --libs8 - -outputs information about where the 8-bit library is installed. This command -can be included in makefiles for programs that use PCRE2, saving the programmer -from having to remember too many details. Run pcre2-config with no arguments to -obtain a list of possible arguments. - -The pkg-config command is another system for saving and retrieving information -about installed libraries. Instead of separate commands for each library, a -single command is used. For example: - - pkg-config --libs libpcre2-16 - -The data is held in *.pc files that are installed in a directory called -/lib/pkgconfig. - - -Shared libraries ----------------- - -The default distribution builds PCRE2 as shared libraries and static libraries, -as long as the operating system supports shared libraries. Shared library -support relies on the "libtool" script which is built as part of the -"configure" process. - -The libtool script is used to compile and link both shared and static -libraries. They are placed in a subdirectory called .libs when they are newly -built. The programs pcre2test and pcre2grep are built to use these uninstalled -libraries (by means of wrapper scripts in the case of shared libraries). When -you use "make install" to install shared libraries, pcre2grep and pcre2test are -automatically re-built to use the newly installed shared libraries before being -installed themselves. However, the versions left in the build directory still -use the uninstalled libraries. - -To build PCRE2 using static libraries only you must use --disable-shared when -configuring it. For example: - -./configure --prefix=/usr/gnu --disable-shared - -Then run "make" in the usual way. Similarly, you can use --disable-static to -build only shared libraries. - - -Cross-compiling using autotools -------------------------------- - -You can specify CC and CFLAGS in the normal way to the "configure" command, in -order to cross-compile PCRE2 for some other host. However, you should NOT -specify --enable-rebuild-chartables, because if you do, the dftables.c source -file is compiled and run on the local host, in order to generate the inbuilt -character tables (the pcre2_chartables.c file). This will probably not work, -because dftables.c needs to be compiled with the local compiler, not the cross -compiler. - -When --enable-rebuild-chartables is not specified, pcre2_chartables.c is -created by making a copy of pcre2_chartables.c.dist, which is a default set of -tables that assumes ASCII code. Cross-compiling with the default tables should -not be a problem. - -If you need to modify the character tables when cross-compiling, you should -move pcre2_chartables.c.dist out of the way, then compile dftables.c by hand -and run it on the local host to make a new version of pcre2_chartables.c.dist. -Then when you cross-compile PCRE2 this new version of the tables will be used. - - -Making new tarballs -------------------- - -The command "make dist" creates three PCRE2 tarballs, in tar.gz, tar.bz2, and -zip formats. The command "make distcheck" does the same, but then does a trial -build of the new distribution to ensure that it works. - -If you have modified any of the man page sources in the doc directory, you -should first run the PrepareRelease script before making a distribution. This -script creates the .txt and HTML forms of the documentation from the man pages. - - -Testing PCRE2 ------------- - -To test the basic PCRE2 library on a Unix-like system, run the RunTest script. -There is another script called RunGrepTest that tests the pcre2grep command. -When JIT support is enabled, a third test program called pcre2_jit_test is -built. Both the scripts and all the program tests are run if you obey "make -check". For other environments, see the instructions in NON-AUTOTOOLS-BUILD. - -The RunTest script runs the pcre2test test program (which is documented in its -own man page) on each of the relevant testinput files in the testdata -directory, and compares the output with the contents of the corresponding -testoutput files. RunTest uses a file called testtry to hold the main output -from pcre2test. Other files whose names begin with "test" are used as working -files in some tests. - -Some tests are relevant only when certain build-time options were selected. For -example, the tests for UTF-8/16/32 features are run only when Unicode support -is available. RunTest outputs a comment when it skips a test. - -Many (but not all) of the tests that are not skipped are run twice if JIT -support is available. On the second run, JIT compilation is forced. This -testing can be suppressed by putting "nojit" on the RunTest command line. - -The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit -libraries that are enabled. If you want to run just one set of tests, call -RunTest with either the -8, -16 or -32 option. - -If valgrind is installed, you can run the tests under it by putting "valgrind" -on the RunTest command line. To run pcre2test on just one or more specific test -files, give their numbers as arguments to RunTest, for example: - - RunTest 2 7 11 - -You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the -end), or a number preceded by ~ to exclude a test. For example: - - Runtest 3-15 ~10 - -This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests -except test 13. Whatever order the arguments are in, the tests are always run -in numerical order. - -You can also call RunTest with the single argument "list" to cause it to output -a list of tests. - -The test sequence starts with "test 0", which is a special test that has no -input file, and whose output is not checked. This is because it will be -different on different hardware and with different configurations. The test -exists in order to exercise some of pcre2test's code that would not otherwise -be run. - -Tests 1 and 2 can always be run, as they expect only plain text strings (not -UTF) and make no use of Unicode properties. The first test file can be fed -directly into the perltest.sh script to check that Perl gives the same results. -The only difference you should see is in the first few lines, where the Perl -version is given instead of the PCRE2 version. The second set of tests check -auxiliary functions, error detection, and run-time flags that are specific to -PCRE2. It also uses the debugging flags to check some of the internals of -pcre2_compile(). - -If you build PCRE2 with a locale setting that is not the standard C locale, the -character tables may be different (see next paragraph). In some cases, this may -cause failures in the second set of tests. For example, in a locale where the -isprint() function yields TRUE for characters in the range 128-255, the use of -[:isascii:] inside a character class defines a different set of characters, and -this shows up in this test as a difference in the compiled code, which is being -listed for checking. For example, where the comparison test output contains -[\x00-\x7f] the test might contain [\x00-\xff], and similarly in some other -cases. This is not a bug in PCRE2. - -Test 3 checks pcre2_maketables(), the facility for building a set of character -tables for a specific locale and using them instead of the default tables. The -script uses the "locale" command to check for the availability of the "fr_FR", -"french", or "fr" locale, and uses the first one that it finds. If the "locale" -command fails, or if its output doesn't include "fr_FR", "french", or "fr" in -the list of available locales, the third test cannot be run, and a comment is -output to say why. If running this test produces an error like this: - - ** Failed to set locale "fr_FR" - -it means that the given locale is not available on your system, despite being -listed by "locale". This does not mean that PCRE2 is broken. There are three -alternative output files for the third test, because three different versions -of the French locale have been encountered. The test passes if its output -matches any one of them. - -Tests 4 and 5 check UTF and Unicode property support, test 4 being compatible -with the perltest.sh script, and test 5 checking PCRE2-specific things. - -Tests 6 and 7 check the pcre2_dfa_match() alternative matching function, in -non-UTF mode and UTF-mode with Unicode property support, respectively. - -Test 8 checks some internal offsets and code size features; it is run only when -the default "link size" of 2 is set (in other cases the sizes change) and when -Unicode support is enabled. - -Tests 9 and 10 are run only in 8-bit mode, and tests 11 and 12 are run only in -16-bit and 32-bit modes. These are tests that generate different output in -8-bit mode. Each pair are for general cases and Unicode support, respectively. -Test 13 checks the handling of non-UTF characters greater than 255 by -pcre2_dfa_match() in 16-bit and 32-bit modes. - -Test 14 contains a number of tests that must not be run with JIT. They check, -among other non-JIT things, the match-limiting features of the intepretive -matcher. - -Test 15 is run only when JIT support is not available. It checks that an -attempt to use JIT has the expected behaviour. - -Test 16 is run only when JIT support is available. It checks JIT complete and -partial modes, match-limiting under JIT, and other JIT-specific features. - -Tests 17 and 18 are run only in 8-bit mode. They check the POSIX interface to -the 8-bit library, without and with Unicode support, respectively. - -Test 19 checks the serialization functions by writing a set of compiled -patterns to a file, and then reloading and checking them. - - -Character tables ----------------- - -For speed, PCRE2 uses four tables for manipulating and identifying characters -whose code point values are less than 256. By default, a set of tables that is -built into the library is used. The pcre2_maketables() function can be called -by an application to create a new set of tables in the current locale. This are -passed to PCRE2 by calling pcre2_set_character_tables() to put a pointer into a -compile context. - -The source file called pcre2_chartables.c contains the default set of tables. -By default, this is created as a copy of pcre2_chartables.c.dist, which -contains tables for ASCII coding. However, if --enable-rebuild-chartables is -specified for ./configure, a different version of pcre2_chartables.c is built -by the program dftables (compiled from dftables.c), which uses the ANSI C -character handling functions such as isalnum(), isalpha(), isupper(), -islower(), etc. to build the table sources. This means that the default C -locale which is set for your system will control the contents of these default -tables. You can change the default tables by editing pcre2_chartables.c and -then re-building PCRE2. If you do this, you should take care to ensure that the -file does not get automatically re-generated. The best way to do this is to -move pcre2_chartables.c.dist out of the way and replace it with your customized -tables. - -When the dftables program is run as a result of --enable-rebuild-chartables, -it uses the default C locale that is set on your system. It does not pay -attention to the LC_xxx environment variables. In other words, it uses the -system's default locale rather than whatever the compiling user happens to have -set. If you really do want to build a source set of character tables in a -locale that is specified by the LC_xxx variables, you can run the dftables -program by hand with the -L option. For example: - - ./dftables -L pcre2_chartables.c.special - -The first two 256-byte tables provide lower casing and case flipping functions, -respectively. The next table consists of three 32-byte bit maps which identify -digits, "word" characters, and white space, respectively. These are used when -building 32-byte bit maps that represent character classes for code points less -than 256. The final 256-byte table has bits indicating various character types, -as follows: - - 1 white space character - 2 letter - 4 decimal digit - 8 hexadecimal digit - 16 alphanumeric or '_' - 128 regular expression metacharacter or binary zero - -You should not alter the set of characters that contain the 128 bit, as that -will cause PCRE2 to malfunction. - - -File manifest -------------- - -The distribution should contain the files listed below. - -(A) Source files for the PCRE2 library functions and their headers are found in - the src directory: - - src/dftables.c auxiliary program for building pcre2_chartables.c - when --enable-rebuild-chartables is specified - - src/pcre2_chartables.c.dist a default set of character tables that assume - ASCII coding; unless --enable-rebuild-chartables is - specified, used by copying to pcre2_chartables.c - - src/pcre2posix.c ) - src/pcre2_auto_possess.c ) - src/pcre2_compile.c ) - src/pcre2_config.c ) - src/pcre2_context.c ) - src/pcre2_dfa_match.c ) - src/pcre2_error.c ) - src/pcre2_find_bracket.c ) - src/pcre2_jit_compile.c ) - src/pcre2_jit_match.c ) sources for the functions in the library, - src/pcre2_jit_misc.c ) and some internal functions that they use - src/pcre2_maketables.c ) - src/pcre2_match.c ) - src/pcre2_match_data.c ) - src/pcre2_newline.c ) - src/pcre2_ord2utf.c ) - src/pcre2_pattern_info.c ) - src/pcre2_serialize.c ) - src/pcre2_string_utils.c ) - src/pcre2_study.c ) - src/pcre2_substitute.c ) - src/pcre2_substring.c ) - src/pcre2_tables.c ) - src/pcre2_ucd.c ) - src/pcre2_valid_utf.c ) - src/pcre2_xclass.c ) - - src/pcre2_printint.c debugging function that is used by pcre2test, - - src/config.h.in template for config.h, when built by "configure" - src/pcre2.h.in template for pcre2.h when built by "configure" - src/pcre2posix.h header for the external POSIX wrapper API - src/pcre2_internal.h header for internal use - src/pcre2_intmodedep.h a mode-specific internal header - src/pcre2_ucp.h header for Unicode property handling - - sljit/* source files for the JIT compiler - -(B) Source files for programs that use PCRE2: - - src/pcre2demo.c simple demonstration of coding calls to PCRE2 - src/pcre2grep.c source of a grep utility that uses PCRE2 - src/pcre2test.c comprehensive test program - src/pcre2_printint.c part of pcre2test - src/pcre2_jit_test.c JIT test program - -(C) Auxiliary files: - - 132html script to turn "man" pages into HTML - AUTHORS information about the author of PCRE2 - ChangeLog log of changes to the code - CleanTxt script to clean nroff output for txt man pages - Detrail script to remove trailing spaces - HACKING some notes about the internals of PCRE2 - INSTALL generic installation instructions - LICENCE conditions for the use of PCRE2 - COPYING the same, using GNU's standard name - Makefile.in ) template for Unix Makefile, which is built by - ) "configure" - Makefile.am ) the automake input that was used to create - ) Makefile.in - NEWS important changes in this release - NON-AUTOTOOLS-BUILD notes on building PCRE2 without using autotools - PrepareRelease script to make preparations for "make dist" - README this file - RunTest a Unix shell script for running tests - RunGrepTest a Unix shell script for pcre2grep tests - aclocal.m4 m4 macros (generated by "aclocal") - config.guess ) files used by libtool, - config.sub ) used only when building a shared library - configure a configuring shell script (built by autoconf) - configure.ac ) the autoconf input that was used to build - ) "configure" and config.h - depcomp ) script to find program dependencies, generated by - ) automake - doc/*.3 man page sources for PCRE2 - doc/*.1 man page sources for pcre2grep and pcre2test - doc/index.html.src the base HTML page - doc/html/* HTML documentation - doc/pcre2.txt plain text version of the man pages - doc/pcre2test.txt plain text documentation of test program - install-sh a shell script for installing files - libpcre2-8.pc.in template for libpcre2-8.pc for pkg-config - libpcre2-16.pc.in template for libpcre2-16.pc for pkg-config - libpcre2-32.pc.in template for libpcre2-32.pc for pkg-config - libpcre2posix.pc.in template for libpcre2posix.pc for pkg-config - ltmain.sh file used to build a libtool script - missing ) common stub for a few missing GNU programs while - ) installing, generated by automake - mkinstalldirs script for making install directories - perltest.sh Script for running a Perl test program - pcre2-config.in source of script which retains PCRE2 information - testdata/testinput* test data for main library tests - testdata/testoutput* expected test results - testdata/grep* input and output for pcre2grep tests - testdata/* other supporting test files - -(D) Auxiliary files for cmake support - - cmake/COPYING-CMAKE-SCRIPTS - cmake/FindPackageHandleStandardArgs.cmake - cmake/FindEditline.cmake - cmake/FindReadline.cmake - CMakeLists.txt - config-cmake.h.in - -(E) Auxiliary files for building PCRE2 "by hand" - - pcre2.h.generic ) a version of the public PCRE2 header file - ) for use in non-"configure" environments - config.h.generic ) a version of config.h for use in non-"configure" - ) environments - -Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk -Last updated: 16 October 2015 diff --git a/pcre2/RunGrepTest b/pcre2/RunGrepTest deleted file mode 100755 index 67d672ba3..000000000 --- a/pcre2/RunGrepTest +++ /dev/null @@ -1,633 +0,0 @@ -#! /bin/sh - -# Run pcre2grep tests. The assumption is that the PCRE2 tests check the library -# itself. What we are checking here is the file handling and options that are -# supported by pcre2grep. This script must be run in the build directory. - -# Set the C locale, so that sort(1) behaves predictably. - -LC_ALL=C -export LC_ALL - -# Remove any non-default colouring and aliases that the caller may have set. - -unset PCRE2GREP_COLOUR PCRE2GREP_COLOR -unset cp ls mv rm - -# Remember the current (build) directory, set the program to be tested, and -# valgrind settings when requested. - -builddir=`pwd` -pcre2grep=$builddir/pcre2grep -pcre2test=$builddir/pcre2test - -if [ ! -x $pcre2grep ] ; then - echo "** $pcre2grep does not exist or is not execuatble." - exit 1 -fi - -if [ ! -x $pcre2test ] ; then - echo "** $pcre2test does not exist or is not execuatble." - exit 1 -fi - -valgrind= -while [ $# -gt 0 ] ; do - case $1 in - valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; - *) echo "RunGrepTest: Unknown argument $1"; exit 1;; - esac - shift -done - -pcre2grep_version=`$pcre2grep -V` -if [ "$valgrind" = "" ] ; then - echo "Testing $pcre2grep_version" -else - echo "Testing $pcre2grep_version using valgrind" -fi - -# Set up a suitable "diff" command for comparison. Some systems have a diff -# that lacks a -u option. Try to deal with this; better do the test for the -b -# option as well. - -cf="diff" -diff -b /dev/null /dev/null 2>/dev/null && cf="diff -b" -diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" -diff -ub /dev/null /dev/null 2>/dev/null && cf="diff -ub" - -# If this test is being run from "make check", $srcdir will be set. If not, set -# it to the current or parent directory, whichever one contains the test data. -# Subsequently, we run most of the pcre2grep tests in the source directory so -# that the file names in the output are always the same. - -if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then - if [ -d "./testdata" ] ; then - srcdir=. - elif [ -d "../testdata" ] ; then - srcdir=.. - else - echo "Cannot find the testdata directory" - exit 1 - fi -fi - -# Check for the availability of UTF-8 support - -$pcre2test -C unicode >/dev/null -utf8=$? - -# Check default newline convention. If it does not include LF, force LF. - -nl=`$pcre2test -C newline` -if [ "$nl" != "LF" -a "$nl" != "ANY" -a "$nl" != "ANYCRLF" ]; then - pcre2grep="$pcre2grep -N LF" - echo "Default newline setting forced to LF" -fi - -# ------ Function to run and check a special pcre2grep arguments test ------- - -checkspecial() - { - $valgrind $pcre2grep $1 >>testtrygrep 2>&1 - if [ $? -ne $2 ] ; then - echo "** pcre2grep $1 failed - check testtrygrep" - exit 1 - fi - } - -# ------ Normal tests ------ - -echo "Testing pcre2grep main features" - -echo "---------------------------- Test 1 ------------------------------" >testtrygrep -(cd $srcdir; $valgrind $pcre2grep PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 2 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '^PATTERN' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 3 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 4 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -ic PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 5 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 6 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 7 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 8 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 9 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 10 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 11 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -vn pattern ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 12 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -ix pattern ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 13 -----------------------------" >>testtrygrep -echo seventeen >testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 14 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 15 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 16 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 17 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 18 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 19 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 20 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 21 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nA3 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 22 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB3 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 23 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -C3 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 24 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A9 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 25 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB9 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 26 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 27 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A10 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 28 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB10 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 29 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 30 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 31 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 32 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 33 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 34 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 35 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 36 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 37 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep -echo "RC=$?" >>testtrygrep -echo "======== STDERR ========" >>testtrygrep -cat teststderrgrep >>testtrygrep - -echo "---------------------------- Test 38 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '>\x00<' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 39 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 40 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 41 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 42 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 43 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 44 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 45 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 46 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 47 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Fx "AB.VE -elephant" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 48 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -F "AB.VE -elephant" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 49 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -F -e DATA -e "AB.VE -elephant" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 50 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 51 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 52 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --colour=always jumps ./testdata/grepinputv) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 53 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 54 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 55 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 56 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -c lazy ./testdata/grepinput*) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 57 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -c -l lazy ./testdata/grepinput*) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 58 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regex=PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 59 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 60 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regex PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 61 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regexp PATTERN ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 62 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 63 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 64 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 65 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 66 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 67 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 68 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 69 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 70 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 71 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 72 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 73 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 74 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 75 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 76 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 77 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 78 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 79 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 80 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 81 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 82 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 83 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 84 -----------------------------" >>testtrygrep -echo testdata/grepinput3 >testtemp1grep -(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 85 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 86 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 87 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 88 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 89 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 90 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 91 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 92 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 93 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 94 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 95 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 96 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 97 -----------------------------" >>testtrygrep -echo "grepinput$" >testtemp1grep -echo "grepinput8" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 98 -----------------------------" >>testtrygrep -echo "grepinput$" >testtemp1grep -echo "grepinput8" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 99 -----------------------------" >>testtrygrep -echo "grepinput$" >testtemp1grep -echo "grepinput8" >testtemp2grep -(cd $srcdir; $valgrind $pcre2grep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 100 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 101 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 102 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 103 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 104 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 105 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 106 -----------------------------" >>testtrygrep -(cd $srcdir; echo "a" | $valgrind $pcre2grep -M "|a" ) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 107 -----------------------------" >>testtrygrep -echo "a" >testtemp1grep -echo "aaaaa" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep --line-offsets '(?<=\Ka)' $builddir/testtemp1grep) >>testtrygrep 2>&1 -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 108 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -lq PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep -echo "RC=$?" >>testtrygrep - -echo "---------------------------- Test 109 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -cq lazy ./testdata/grepinput*) >>testtrygrep -echo "RC=$?" >>testtrygrep - -# Now compare the results. - -$cf $srcdir/testdata/grepoutput testtrygrep -if [ $? != 0 ] ; then exit 1; fi - - -# These tests require UTF-8 support - -if [ $utf8 -ne 0 ] ; then - echo "Testing pcre2grep UTF-8 features" - - echo "---------------------------- Test U1 ------------------------------" >testtrygrep - (cd $srcdir; $valgrind $pcre2grep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep - echo "RC=$?" >>testtrygrep - - echo "---------------------------- Test U2 ------------------------------" >>testtrygrep - (cd $srcdir; $valgrind $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep - echo "RC=$?" >>testtrygrep - - echo "---------------------------- Test U3 ------------------------------" >>testtrygrep - (cd $srcdir; $valgrind $pcre2grep --line-offsets -u --newline=any '(?<=\K\x{17f})' ./testdata/grepinput8) >>testtrygrep - echo "RC=$?" >>testtrygrep - - $cf $srcdir/testdata/grepoutput8 testtrygrep - if [ $? != 0 ] ; then exit 1; fi - -else - echo "Skipping pcre2grep UTF-8 tests: no UTF-8 support in PCRE2 library" -fi - - -# We go to some contortions to try to ensure that the tests for the various -# newline settings will work in environments where the normal newline sequence -# is not \n. Do not use exported files, whose line endings might be changed. -# Instead, create an input file using printf so that its contents are exactly -# what we want. Note the messy fudge to get printf to write a string that -# starts with a hyphen. These tests are run in the build directory. - -echo "Testing pcre2grep newline settings" -printf "abc\rdef\r\nghi\njkl" >testNinputgrep - -printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtrygrep -$valgrind $pcre2grep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep - -printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep - -printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtrygrep -pattern=`printf 'def\rjkl'` -$valgrind $pcre2grep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep - -printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep - -printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep - -printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep - -$cf $srcdir/testdata/grepoutputN testtrygrep -if [ $? != 0 ] ; then exit 1; fi - - -# Finally, some tests to exercise code that is not tested above, just to be -# sure that it runs OK. Doing this improves the coverage statistics. The output -# is not checked. - -echo "Testing miscellaneous pcre2grep arguments (unchecked)" -echo '' >testtrygrep -checkspecial '-xxxxx' 2 -checkspecial '--help' 0 -checkspecial '--line-buffered --colour=auto abc /dev/null' 1 - -# Clean up local working files -rm -f testNinputgrep teststderrgrep testtrygrep testtemp1grep testtemp2grep - -exit 0 - -# End diff --git a/pcre2/RunTest b/pcre2/RunTest deleted file mode 100755 index 36dc638ed..000000000 --- a/pcre2/RunTest +++ /dev/null @@ -1,850 +0,0 @@ -#! /bin/sh - -############################################################################### -# Run the PCRE2 tests using the pcre2test program. The appropriate tests are -# selected, depending on which build-time options were used. -# -# When JIT support is available, all appropriate tests are run with and without -# JIT, unless "-nojit" is given on the command line. There are also two tests -# for JIT-specific features, one to be run when JIT support is available -# (unless "-nojit" is specified), and one when it is not. -# -# Whichever of the 8-, 16- and 32-bit libraries exist are tested. It is also -# possible to select which to test by giving "-8", "-16" or "-32" on the -# command line. -# -# As well as "-nojit", "-8", "-16", and "-32", arguments for this script are -# individual test numbers, ranges of tests such as 3-6 or 3- (meaning 3 to the -# end), or a number preceded by ~ to exclude a test. For example, "3-15 ~10" -# runs tests 3 to 15, excluding test 10, and just "~10" runs all the tests -# except test 10. Whatever order the arguments are in, the tests are always run -# in numerical order. -# -# Inappropriate tests are automatically skipped (with a comment to say so). For -# example, if JIT support is not compiled, test 16 is skipped, whereas if JIT -# support is compiled, test 15 is skipped. -# -# Other arguments can be one of the words "-valgrind", "-valgrind-log", or -# "-sim" followed by an argument to run cross-compiled executables under a -# simulator, for example: -# -# RunTest 3 -sim "qemu-arm -s 8388608" -# -# For backwards compatibility, -nojit, -valgrind, -valgrind-log, and -sim may -# be given without the leading "-" character. -# -# When PCRE2 is compiled by clang with -fsanitize arguments, some tests need -# very much more stack than normal. In environments where the stack can be -# set at runtime, -bigstack sets a gigantic stack. -# -# There are two special cases where only one argument is allowed: -# -# If the first and only argument is "ebcdic", the script runs the special -# EBCDIC test that can be useful for checking certain EBCDIC features, even -# when run in an ASCII environment. PCRE2 must be built with EBCDIC support for -# this test to be run. -# -# If the script is obeyed as "RunTest list", a list of available tests is -# output, but none of them are run. -############################################################################### - -# Define test titles in variables so that they can be output as a list. Some -# of them are modified (e.g. with -8 or -16) when used in the actual tests. - -title0="Test 0: Unchecked pcre2test argument tests (to improve coverage)" -title1="Test 1: Main non-UTF, non-UCP functionality (compatible with Perl >= 5.10)" -title2="Test 2: API, errors, internals, and non-Perl stuff" -title3="Test 3: Locale-specific features" -title4A="Test 4: UTF" -title4B=" and Unicode property support (compatible with Perl >= 5.10)" -title5A="Test 5: API, internals, and non-Perl stuff for UTF" -title5B=" and UCP support" -title6="Test 6: DFA matching main non-UTF, non-UCP functionality" -title7A="Test 7: DFA matching with UTF" -title7B=" and Unicode property support" -title8="Test 8: Internal offsets and code size tests" -title9="Test 9: Specials for the basic 8-bit library" -title10="Test 10: Specials for the 8-bit library with UTF-8 and UCP support" -title11="Test 11: Specials for the basic 16-bit and 32-bit libraries" -title12="Test 12: Specials for the 16-bit and 32-bit libraries UTF and UCP support" -title13="Test 13: DFA specials for the basic 16-bit and 32-bit libraries" -title14="Test 14: DFA specials for UTF and UCP support" -title15="Test 15: Non-JIT limits and other non-JIT tests" -title16="Test 16: JIT-specific features when JIT is not available" -title17="Test 17: JIT-specific features when JIT is available" -title18="Test 18: Tests of the POSIX interface, excluding UTF/UCP" -title19="Test 19: Tests of the POSIX interface with UTF/UCP" -title20="Test 20: Serialization tests" -title21="Test 21: \C tests without UTF (supported for DFA matching)" -title22="Test 22: \C tests with UTF (not supported for DFA matching)" -title23="Test 23: \C disabled test" -maxtest=23 - -if [ $# -eq 1 -a "$1" = "list" ]; then - echo $title0 - echo $title1 - echo $title2 "(not UTF or UCP)" - echo $title3 - echo $title4A $title4B - echo $title5A $title5B - echo $title6 - echo $title7A $title7B - echo $title8 - echo $title9 - echo $title10 - echo $title11 - echo $title12 - echo $title13 - echo $title14 - echo $title15 - echo $title16 - echo $title17 - echo $title18 - echo $title19 - echo $title20 - echo $title21 - echo $title22 - echo $title23 - exit 0 -fi - -# Set up a suitable "diff" command for comparison. Some systems -# have a diff that lacks a -u option. Try to deal with this. - -cf="diff" -diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" - -# Find the test data - -if [ -n "$srcdir" -a -d "$srcdir" ] ; then - testdata="$srcdir/testdata" -elif [ -d "./testdata" ] ; then - testdata=./testdata -elif [ -d "../testdata" ] ; then - testdata=../testdata -else - echo "Cannot find the testdata directory" - exit 1 -fi - - -# ------ Function to check results of a test ------- - -# This function is called with three parameters: -# -# $1 the value of $? after a call to pcre2test -# $2 the suffix of the output file to compare with -# $3 the $opt value (empty, -jit, or -dfa) -# -# Note: must define using name(), not "function name", for Solaris. - -checkresult() - { - if [ $1 -ne 0 ] ; then - echo "** pcre2test failed - check testtry" - exit 1 - fi - case "$3" in - -jit) with=" with JIT";; - -dfa) with=" with DFA";; - *) with="";; - esac - $cf $testdata/testoutput$2 testtry - if [ $? != 0 ] ; then - echo "" - echo "** Test $2 failed$with" - exit 1 - fi - echo " OK$with" - } - - -# ------ Function to run and check a special pcre2test arguments test ------- - -checkspecial() - { - $valgrind $vjs ./pcre2test $1 >>testtry - if [ $? -ne 0 ] ; then - echo "** pcre2test $1 failed - check testtry" - exit 1 - fi - } - - -# ------ Special EBCDIC Test ------- - -if [ $# -eq 1 -a "$1" = "ebcdic" ]; then - $valgrind ./pcre2test -C ebcdic >/dev/null - ebcdic=$? - if [ $ebcdic -ne 1 ] ; then - echo "Cannot run EBCDIC tests: EBCDIC support not compiled" - exit 1 - fi - for opt in "" "-dfa"; do - ./pcre2test -q $opt $testdata/testinputEBC >testtry - checkresult $? EBC "$opt" - done -exit 0 -fi - - -# ------ Normal Tests ------ - -# Default values - -arg8= -arg16= -arg32= -nojit= -bigstack= -sim= -skip= -valgrind= -vjs= - -# This is in case the caller has set aliases (as I do - PH) -unset cp ls mv rm - -# Process options and select which tests to run; for those that are explicitly -# requested, check that the necessary optional facilities are available. - -do0=no -do1=no -do2=no -do3=no -do4=no -do5=no -do6=no -do7=no -do8=no -do9=no -do10=no -do11=no -do12=no -do13=no -do14=no -do15=no -do16=no -do17=no -do18=no -do19=no -do20=no -do21=no -do22=no -do23=no - -while [ $# -gt 0 ] ; do - case $1 in - 0) do0=yes;; - 1) do1=yes;; - 2) do2=yes;; - 3) do3=yes;; - 4) do4=yes;; - 5) do5=yes;; - 6) do6=yes;; - 7) do7=yes;; - 8) do8=yes;; - 9) do9=yes;; - 10) do10=yes;; - 11) do11=yes;; - 12) do12=yes;; - 13) do13=yes;; - 14) do14=yes;; - 15) do15=yes;; - 16) do16=yes;; - 17) do17=yes;; - 18) do18=yes;; - 19) do19=yes;; - 20) do20=yes;; - 21) do21=yes;; - 22) do22=yes;; - 23) do23=yes;; - -8) arg8=yes;; - -16) arg16=yes;; - -32) arg32=yes;; - bigstack|-bigstack) bigstack=yes;; - nojit|-nojit) nojit=yes;; - sim|-sim) shift; sim=$1;; - valgrind|-valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all";; - valgrind-log|-valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all --log-file=report.%p ";; - ~*) - if expr "$1" : '~[0-9][0-9]*$' >/dev/null; then - skip="$skip `expr "$1" : '~\([0-9]*\)*$'`" - else - echo "Unknown option or test selector '$1'"; exit 1 - fi - ;; - *-*) - if expr "$1" : '[0-9][0-9]*-[0-9]*$' >/dev/null; then - tf=`expr "$1" : '\([0-9]*\)'` - tt=`expr "$1" : '.*-\([0-9]*\)'` - if [ "$tt" = "" ] ; then tt=$maxtest; fi - if expr \( "$tt" ">" "$maxtest" \) >/dev/null; then - echo "Invalid test range '$1'"; exit 1 - fi - while expr "$tf" "<=" "$tt" >/dev/null; do - eval do${tf}=yes - tf=`expr $tf + 1` - done - else - echo "Invalid test range '$1'"; exit 1 - fi - ;; - *) echo "Unknown option or test selector '$1'"; exit 1;; - esac - shift -done - -# Find which optional facilities are available. - -$sim ./pcre2test -C linksize >/dev/null -link_size=$? -if [ $link_size -lt 2 ] ; then - echo "RunTest: Failed to find internal link size" - exit 1 -fi -if [ $link_size -gt 4 ] ; then - echo "RunTest: Failed to find internal link size" - exit 1 -fi - -# If it is possible to set the system stack size, arrange to set a value for -# test 2, which needs more than the even the Linux default when PCRE2 has been -# compiled by gcc with -fsanitize=address. When the compiler is clang, sanitize -# options require an even bigger stack for test 2, and an increased stack for -# some of the other tests. - -$sim ./pcre2test -S 1 /dev/null /dev/null -if [ $? -eq 0 ] ; then - if [ "$bigstack" = "" ] ; then - test2stack="-S 16" - defaultstack="" - else - test2stack="-S 1024" - defaultstack="-S 64" - fi -else - test2stack="" - defaultstack="" -fi - -# All of 8-bit, 16-bit, and 32-bit character strings may be supported, but only -# one need be. - -$sim ./pcre2test -C pcre2-8 >/dev/null -support8=$? -$sim ./pcre2test -C pcre2-16 >/dev/null -support16=$? -$sim ./pcre2test -C pcre2-32 >/dev/null -support32=$? - -# \C may be disabled - -$sim ./pcre2test -C backslash-C >/dev/null -supportBSC=$? - -# Initialize all bitsizes skipped - -test8=skip -test16=skip -test32=skip - -# If no bitsize arguments, select all that are available - -if [ "$arg8$arg16$arg32" = "" ] ; then - if [ $support8 -ne 0 ] ; then - test8=-8 - fi - if [ $support16 -ne 0 ] ; then - test16=-16 - fi - if [ $support32 -ne 0 ] ; then - test32=-32 - fi - -# Otherwise, select requested bit sizes - -else - if [ "$arg8" = yes ] ; then - if [ $support8 -eq 0 ] ; then - echo "Cannot run 8-bit library tests: 8-bit library not compiled" - exit 1 - fi - test8=-8 - fi - if [ "$arg16" = yes ] ; then - if [ $support16 -eq 0 ] ; then - echo "Cannot run 16-bit library tests: 16-bit library not compiled" - exit 1 - fi - test16=-16 - fi - if [ "$arg32" = yes ] ; then - if [ $support32 -eq 0 ] ; then - echo "Cannot run 32-bit library tests: 32-bit library not compiled" - exit 1 - fi - test32=-32 - fi -fi - -# UTF support is implied by Unicode support, and it always applies to all bit -# sizes if both are supported; we can't have UTF-8 support without UTF-16 or -# UTF-32 support. - -$sim ./pcre2test -C unicode >/dev/null -utf=$? - -# When JIT is used with valgrind, we need to set up valgrind suppressions as -# otherwise there are a lot of false positive valgrind reports when the -# the hardware supports SSE2. - -jitopt= -$sim ./pcre2test -C jit >/dev/null -jit=$? -if [ $jit -ne 0 -a "$nojit" != "yes" ] ; then - jitopt=-jit - if [ "$valgrind" != "" ] ; then - vjs="--suppressions=$testdata/valgrind-jit.supp" - fi -fi - -# If no specific tests were requested, select all. Those that are not -# relevant will be automatically skipped. - -if [ $do0 = no -a $do1 = no -a $do2 = no -a $do3 = no -a \ - $do4 = no -a $do5 = no -a $do6 = no -a $do7 = no -a \ - $do8 = no -a $do9 = no -a $do10 = no -a $do11 = no -a \ - $do12 = no -a $do13 = no -a $do14 = no -a $do15 = no -a \ - $do16 = no -a $do17 = no -a $do18 = no -a $do19 = no -a \ - $do20 = no -a $do21 = no -a $do22 = no -a $do23 = no \ - ]; then - do0=yes - do1=yes - do2=yes - do3=yes - do4=yes - do5=yes - do6=yes - do7=yes - do8=yes - do9=yes - do10=yes - do11=yes - do12=yes - do13=yes - do14=yes - do15=yes - do16=yes - do17=yes - do18=yes - do19=yes - do20=yes - do21=yes - do22=yes - do23=yes -fi - -# Handle any explicit skips at this stage, so that an argument list may consist -# only of explicit skips. - -for i in $skip; do eval do$i=no; done - -# Show which release and which test data - -echo "" -echo PCRE2 C library tests using test data from $testdata -$sim ./pcre2test /dev/null -echo "" - -for bmode in "$test8" "$test16" "$test32"; do - case "$bmode" in - skip) continue;; - -16) if [ "$test8$test32" != "skipskip" ] ; then echo ""; fi - bits=16; echo "---- Testing 16-bit library ----"; echo "";; - -32) if [ "$test8$test16" != "skipskip" ] ; then echo ""; fi - bits=32; echo "---- Testing 32-bit library ----"; echo "";; - -8) bits=8; echo "---- Testing 8-bit library ----"; echo "";; - esac - - # Test 0 is a special test. Its output is not checked, because it will - # be different on different hardware and with different configurations. - # Running this test just exercises the code. - - if [ $do0 = yes ] ; then - echo $title0 - echo '/abc/jit,memory' >testSinput - echo ' abc' >>testSinput - echo '' >testtry - checkspecial '-C' - checkspecial '--help' - checkspecial '-S 1 -t 10 testSinput' - echo " OK" - fi - - # Primary non-UTF test, compatible with JIT and all versions of Perl >= 5.8 - - if [ $do1 = yes ] ; then - echo $title1 - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput1 testtry - checkresult $? 1 "$opt" - done - fi - - # PCRE2 tests that are not Perl-compatible: API, errors, internals - - if [ $do2 = yes ] ; then - echo $title2 "(excluding UTF-$bits)" - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $test2stack $bmode $opt $testdata/testinput2 testtry - if [ $? = 0 ] ; then - checkresult $? 2 "$opt" - else - echo " " - echo "** Test 2 requires a lot of stack. If it has crashed with a" - echo "** segmentation fault, it may be that you do not have enough" - echo "** stack available by default. Please see the 'pcre2stack' man" - echo "** page for a discussion of PCRE2's stack usage." - echo " " - exit 1 - fi - done - fi - - # Locale-specific tests, provided that either the "fr_FR", "fr_CA", "french" - # or "fr" locale is available. The first two are Unix-like standards; the - # last two are for Windows. Unfortunately, different versions of the French - # locale give different outputs for some items. This test passes if the - # output matches any one of the alternative output files. - - if [ $do3 = yes ] ; then - locale= - - # In some environments locales that are listed by the "locale -a" - # command do not seem to work with setlocale(). Therefore, we do - # a preliminary test to see if pcre2test can set one before going - # on to use it. - - for loc in 'fr_FR' 'french' 'fr' 'fr_CA'; do - locale -a | grep "^$loc\$" >/dev/null - if [ $? -eq 0 ] ; then - echo "/a/locale=$loc" | \ - $sim $valgrind ./pcre2test -q $bmode | \ - grep "Failed to set locale" >/dev/null - if [ $? -ne 0 ] ; then - locale=$loc - if [ "$locale" = "fr_FR" ] ; then - infile=$testdata/testinput3 - outfile=$testdata/testoutput3 - outfile2=$testdata/testoutput3A - outfile3=$testdata/testoutput3B - else - infile=test3input - outfile=test3output - outfile2=test3outputA - outfile3=test3outputB - sed "s/fr_FR/$loc/" $testdata/testinput3 >test3input - sed "s/fr_FR/$loc/" $testdata/testoutput3 >test3output - sed "s/fr_FR/$loc/" $testdata/testoutput3A >test3outputA - sed "s/fr_FR/$loc/" $testdata/testoutput3B >test3outputB - fi - break - fi - fi - done - - if [ "$locale" != "" ] ; then - echo $title3 "(using '$locale' locale)" - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $infile testtry - if [ $? = 0 ] ; then - case "$opt" in - -jit) with=" with JIT";; - *) with="";; - esac - if $cf $outfile testtry >teststdout || \ - $cf $outfile2 testtry >teststdout || \ - $cf $outfile3 testtry >teststdout - then - echo " OK$with" - else - echo "** Locale test did not run successfully$with. The output did not match" - echo " $outfile, $outfile2 or $outfile3." - echo " This may mean that there is a problem with the locale settings rather" - echo " than a bug in PCRE2." - exit 1 - fi - else exit 1 - fi - done - else - echo "Cannot test locale-specific features - none of the 'fr_FR', 'fr_CA'," - echo "'fr' or 'french' locales can be set, or the \"locale\" command is" - echo "not available to check for them." - echo " " - fi - fi - - # Tests for UTF and Unicode property support - - if [ $do4 = yes ] ; then - echo ${title4A}-${bits}${title4B} - if [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput4 testtry - checkresult $? 4 "$opt" - done - fi - fi - - if [ $do5 = yes ] ; then - echo ${title5A}-${bits}$title5B - if [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput5 testtry - checkresult $? 5 "$opt" - done - fi - fi - - # Tests for DFA matching support - - if [ $do6 = yes ] ; then - echo $title6 - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput6 testtry - checkresult $? 6 "" - fi - - if [ $do7 = yes ] ; then - echo ${title7A}-${bits}$title7B - if [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput7 testtry - checkresult $? 7 "" - fi - fi - - # Test of internal offsets and code sizes. This test is run only when there - # is UTF/UCP support. The actual tests are mostly the same as in some of the - # above, but in this test we inspect some offsets and sizes. This is a - # doublecheck for the maintainer, just in case something changes unexpectely. - # The output from this test is different in 8-bit, 16-bit, and 32-bit modes - # and for different link sizes, so there are different output files for each - # mode and link size. - - if [ $do8 = yes ] ; then - echo $title8 - if [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput8 testtry - checkresult $? 8-$bits-$link_size "" - fi - fi - - # Tests for 8-bit-specific features - - if [ "$do9" = yes ] ; then - echo $title9 - if [ "$bits" = "16" -o "$bits" = "32" ] ; then - echo " Skipped when running 16/32-bit tests" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput9 testtry - checkresult $? 9 "$opt" - done - fi - fi - - # Tests for UTF-8 and UCP 8-bit-specific features - - if [ "$do10" = yes ] ; then - echo $title10 - if [ "$bits" = "16" -o "$bits" = "32" ] ; then - echo " Skipped when running 16/32-bit tests" - elif [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput10 testtry - checkresult $? 10 "$opt" - done - fi - fi - - # Tests for 16-bit and 32-bit features. Output is different for the two widths. - - if [ $do11 = yes ] ; then - echo $title11 - if [ "$bits" = "8" ] ; then - echo " Skipped when running 8-bit tests" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput11 testtry - checkresult $? 11-$bits "$opt" - done - fi - fi - - # Tests for 16-bit and 32-bit features with UTF-16/32 and UCP support. Output - # is different for the two widths. - - if [ $do12 = yes ] ; then - echo $title12 - if [ "$bits" = "8" ] ; then - echo " Skipped when running 8-bit tests" - elif [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput12 testtry - checkresult $? 12-$bits "$opt" - done - fi - fi - - # Tests for 16/32-bit-specific features in DFA non-UTF modes - - if [ $do13 = yes ] ; then - echo $title13 - if [ "$bits" = "8" ] ; then - echo " Skipped when running 8-bit tests" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput13 testtry - checkresult $? 13 "" - fi - fi - - # Tests for DFA UTF and UCP features. Output is different for the different widths. - - if [ $do14 = yes ] ; then - echo $title14 - if [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput14 testtry - checkresult $? 14-$bits "" - fi - fi - - # Test non-JIT match and recursion limits - - if [ $do15 = yes ] ; then - echo $title15 - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput15 testtry - checkresult $? 15 "" - fi - - # Test JIT-specific features when JIT is not available - - if [ $do16 = yes ] ; then - echo $title16 - if [ $jit -ne 0 ] ; then - echo " Skipped because JIT is available" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput16 testtry - checkresult $? 16 "" - fi - fi - - # Test JIT-specific features when JIT is available - - if [ $do17 = yes ] ; then - echo $title17 - if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then - echo " Skipped because JIT is not available or nojit was specified" - else - $sim $valgrind $vjs ./pcre2test -q $defaultstack $bmode $testdata/testinput17 testtry - checkresult $? 17 "" - fi - fi - - # Tests for the POSIX interface without UTF/UCP (8-bit only) - - if [ $do18 = yes ] ; then - echo $title18 - if [ "$bits" = "16" -o "$bits" = "32" ] ; then - echo " Skipped when running 16/32-bit tests" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput18 testtry - checkresult $? 18 "" - fi - fi - - # Tests for the POSIX interface with UTF/UCP (8-bit only) - - if [ $do19 = yes ] ; then - echo $title19 - if [ "$bits" = "16" -o "$bits" = "32" ] ; then - echo " Skipped when running 16/32-bit tests" - elif [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput19 testtry - checkresult $? 19 "" - fi - fi - - # Serialization tests - - if [ $do20 = yes ] ; then - echo $title20 - $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput20 testtry - checkresult $? 20 "" - fi - - # \C tests without UTF - DFA matching is supported - - if [ "$do21" = yes ] ; then - echo $title21 - if [ $supportBSC -eq 0 ] ; then - echo " Skipped because \C is disabled" - else - for opt in "" $jitopt -dfa; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput21 testtry - checkresult $? 21 "$opt" - done - fi - fi - - # \C tests with UTF - DFA matching is not supported for \C in UTF mode - - if [ "$do22" = yes ] ; then - echo $title22 - if [ $supportBSC -eq 0 ] ; then - echo " Skipped because \C is disabled" - elif [ $utf -eq 0 ] ; then - echo " Skipped because UTF-$bits support is not available" - else - for opt in "" $jitopt; do - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput22 testtry - checkresult $? 22-$bits "$opt" - done - fi - fi - - # Test when \C is disabled - - if [ "$do23" = yes ] ; then - echo $title23 - if [ $supportBSC -ne 0 ] ; then - echo " Skipped because \C is not disabled" - else - $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput23 testtry - checkresult $? 23 "" - fi - fi - -# End of loop for 8/16/32-bit tests -done - -# Clean up local working files -rm -f testSinput test3input testsaved1 testsaved2 test3output test3outputA test3outputB teststdout teststderr testtry - -# End diff --git a/pcre2/aclocal.m4 b/pcre2/aclocal.m4 deleted file mode 100644 index 795657e89..000000000 --- a/pcre2/aclocal.m4 +++ /dev/null @@ -1,1531 +0,0 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29) -dnl -dnl Copyright © 2004 Scott James Remnant . -dnl Copyright © 2012-2015 Dan Nicholson -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a -dnl configuration script generated by Autoconf, you may include it under -dnl the same distribution terms that you use for the rest of that -dnl program. - -dnl PKG_PREREQ(MIN-VERSION) -dnl ----------------------- -dnl Since: 0.29 -dnl -dnl Verify that the version of the pkg-config macros are at least -dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's -dnl installed version of pkg-config, this checks the developer's version -dnl of pkg.m4 when generating configure. -dnl -dnl To ensure that this macro is defined, also add: -dnl m4_ifndef([PKG_PREREQ], -dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) -dnl -dnl See the "Since" comment for each macro you use to see what version -dnl of the macros you require. -m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29]) -m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, - [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) -])dnl PKG_PREREQ - -dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) -dnl ---------------------------------- -dnl Since: 0.16 -dnl -dnl Search for the pkg-config tool and set the PKG_CONFIG variable to -dnl first found in the path. Checks that the version of pkg-config found -dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is -dnl used since that's the first version where most current features of -dnl pkg-config existed. -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) -m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi -fi[]dnl -])dnl PKG_PROG_PKG_CONFIG - -dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------------------------------- -dnl Since: 0.18 -dnl -dnl Check to see whether a particular set of modules exists. Similar to -dnl PKG_CHECK_MODULES(), but does not set variables or print errors. -dnl -dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -dnl only at the first occurence in configure.ac, so if the first place -dnl it's called might be skipped (such as if it is within an "if", you -dnl have to call PKG_CHECK_EXISTS manually -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_default([$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - -dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -dnl --------------------------------------------- -dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting -dnl pkg_failed based on the result. -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes ], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])dnl _PKG_CONFIG - -dnl _PKG_SHORT_ERRORS_SUPPORTED -dnl --------------------------- -dnl Internal check to see if pkg-config supports short errors. -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])dnl _PKG_SHORT_ERRORS_SUPPORTED - - -dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl -------------------------------------------------------------- -dnl Since: 0.4.0 -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES might not happen, you should be sure to include an -dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - m4_default([$4], [AC_MSG_ERROR( -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT])[]dnl - ]) -elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])[]dnl - ]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - $3 -fi[]dnl -])dnl PKG_CHECK_MODULES - - -dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl --------------------------------------------------------------------- -dnl Since: 0.29 -dnl -dnl Checks for existence of MODULES and gathers its build flags with -dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags -dnl and VARIABLE-PREFIX_LIBS from --libs. -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to -dnl include an explicit call to PKG_PROG_PKG_CONFIG in your -dnl configure.ac. -AC_DEFUN([PKG_CHECK_MODULES_STATIC], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -_save_PKG_CONFIG=$PKG_CONFIG -PKG_CONFIG="$PKG_CONFIG --static" -PKG_CHECK_MODULES($@) -PKG_CONFIG=$_save_PKG_CONFIG[]dnl -])dnl PKG_CHECK_MODULES_STATIC - - -dnl PKG_INSTALLDIR([DIRECTORY]) -dnl ------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable pkgconfigdir as the location where a module -dnl should install pkg-config .pc files. By default the directory is -dnl $libdir/pkgconfig, but the default can be changed by passing -dnl DIRECTORY. The user can override through the --with-pkgconfigdir -dnl parameter. -AC_DEFUN([PKG_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([pkgconfigdir], - [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, - [with_pkgconfigdir=]pkg_default) -AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -])dnl PKG_INSTALLDIR - - -dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) -dnl -------------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable noarch_pkgconfigdir as the location where a -dnl module should install arch-independent pkg-config .pc files. By -dnl default the directory is $datadir/pkgconfig, but the default can be -dnl changed by passing DIRECTORY. The user can override through the -dnl --with-noarch-pkgconfigdir parameter. -AC_DEFUN([PKG_NOARCH_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([noarch-pkgconfigdir], - [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, - [with_noarch_pkgconfigdir=]pkg_default) -AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -])dnl PKG_NOARCH_INSTALLDIR - - -dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------- -dnl Since: 0.28 -dnl -dnl Retrieves the value of the pkg-config variable for the given module. -AC_DEFUN([PKG_CHECK_VAR], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl - -_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -AS_VAR_COPY([$1], [pkg_cv_][$1]) - -AS_VAR_IF([$1], [""], [$5], [$4])dnl -])dnl PKG_CHECK_VAR - -# Copyright (C) 2002-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# Copyright (C) 2011-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_AR([ACT-IF-FAIL]) -# ------------------------- -# Try to determine the archiver interface, and trigger the ar-lib wrapper -# if it is needed. If the detection of archiver interface fails, run -# ACT-IF-FAIL (default is to abort configure with a proper error message). -AC_DEFUN([AM_PROG_AR], -[AC_BEFORE([$0], [LT_INIT])dnl -AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([ar-lib])dnl -AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) -: ${AR=ar} - -AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], - [AC_LANG_PUSH([C]) - am_cv_ar_interface=ar - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], - [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - ]) - AC_LANG_POP([C])]) - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - m4_default([$1], - [AC_MSG_ERROR([could not determine $AR interface])]) - ;; -esac -AC_SUBST([AR])dnl -]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless 'enable' is passed literally. -# For symmetry, 'disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], - [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], - am_maintainer_other[ make rules and dependencies not useful - (and sometimes confusing) to the casual installer])], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/ax_pthread.m4]) -m4_include([m4/libtool.m4]) -m4_include([m4/ltoptions.m4]) -m4_include([m4/ltsugar.m4]) -m4_include([m4/ltversion.m4]) -m4_include([m4/lt~obsolete.m4]) -m4_include([m4/pcre2_visibility.m4]) diff --git a/pcre2/ar-lib b/pcre2/ar-lib deleted file mode 100755 index 463b9ec02..000000000 --- a/pcre2/ar-lib +++ /dev/null @@ -1,270 +0,0 @@ -#! /bin/sh -# Wrapper for Microsoft lib.exe - -me=ar-lib -scriptversion=2012-03-01.08; # UTC - -# Copyright (C) 2010-2014 Free Software Foundation, Inc. -# Written by Peter Rosin . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - - -# func_error message -func_error () -{ - echo "$me: $1" 1>&2 - exit 1 -} - -file_conv= - -# func_file_conv build_file -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv in - mingw) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_at_file at_file operation archive -# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE -# for each of them. -# When interpreting the content of the @FILE, do NOT use func_file_conv, -# since the user would need to supply preconverted file names to -# binutils ar, at least for MinGW. -func_at_file () -{ - operation=$2 - archive=$3 - at_file_contents=`cat "$1"` - eval set x "$at_file_contents" - shift - - for member - do - $AR -NOLOGO $operation:"$member" "$archive" || exit $? - done -} - -case $1 in - '') - func_error "no command. Try '$0 --help' for more information." - ;; - -h | --h*) - cat <_FOUND variable. -# The package is found if all variables listed are TRUE. -# Example: -# -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) -# -# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and -# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. -# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, -# independent whether QUIET was used or not. -# If it is found, the location is reported using the VAR1 argument, so -# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. -# If the second argument is DEFAULT_MSG, the message in the failure case will -# be "Could NOT find LibXml2", if you don't like this message you can specify -# your own custom failure message there. - -MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) - - IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") - IF (${_NAME}_FIND_REQUIRED) - SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") - ELSE (${_NAME}_FIND_REQUIRED) - SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") - ENDIF (${_NAME}_FIND_REQUIRED) - ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") - SET(_FAIL_MESSAGE "${_FAIL_MSG}") - ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") - - STRING(TOUPPER ${_NAME} _NAME_UPPER) - - SET(${_NAME_UPPER}_FOUND TRUE) - IF(NOT ${_VAR1}) - SET(${_NAME_UPPER}_FOUND FALSE) - ENDIF(NOT ${_VAR1}) - - FOREACH(_CURRENT_VAR ${ARGN}) - IF(NOT ${_CURRENT_VAR}) - SET(${_NAME_UPPER}_FOUND FALSE) - ENDIF(NOT ${_CURRENT_VAR}) - ENDFOREACH(_CURRENT_VAR) - - IF (${_NAME_UPPER}_FOUND) - IF (NOT ${_NAME}_FIND_QUIETLY) - MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") - ENDIF (NOT ${_NAME}_FIND_QUIETLY) - ELSE (${_NAME_UPPER}_FOUND) - IF (${_NAME}_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") - ELSE (${_NAME}_FIND_REQUIRED) - IF (NOT ${_NAME}_FIND_QUIETLY) - MESSAGE(STATUS "${_FAIL_MESSAGE}") - ENDIF (NOT ${_NAME}_FIND_QUIETLY) - ENDIF (${_NAME}_FIND_REQUIRED) - ENDIF (${_NAME_UPPER}_FOUND) -ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) diff --git a/pcre2/cmake/FindReadline.cmake b/pcre2/cmake/FindReadline.cmake deleted file mode 100644 index 1d4cc5584..000000000 --- a/pcre2/cmake/FindReadline.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# from http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/FindReadline.cmake -# http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/COPYING-CMAKE-SCRIPTS -# --> BSD licensed -# -# GNU Readline library finder -if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) - set(READLINE_FOUND TRUE) -else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) - FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h - /usr/include/readline - ) - -# 2008-04-22 The next clause used to read like this: -# -# FIND_LIBRARY(READLINE_LIBRARY NAMES readline) -# FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses ) -# include(FindPackageHandleStandardArgs) -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY ) -# -# I was advised to modify it such that it will find an ncurses library if -# required, but not if one was explicitly given, that is, it allows the -# default to be overridden. PH - - FIND_LIBRARY(READLINE_LIBRARY NAMES readline) - include(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY ) - - MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY) -endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) diff --git a/pcre2/compile b/pcre2/compile deleted file mode 100755 index a85b723c7..000000000 --- a/pcre2/compile +++ /dev/null @@ -1,347 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2012-10-14.11; # UTC - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' - -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" "" $nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv/,$2, in - *,$file_conv,*) - ;; - mingw/*) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin/*) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine/*) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - if test -f "$dir/lib$lib.a"; then - found=yes - lib=$dir/lib$lib.a - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ - # Assume a capable shell - lib_path= - shared=: - linker_opts= - for arg - do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - eat=1 - case $2 in - *.o | *.[oO][bB][jJ]) - func_file_conv "$2" - set x "$@" -Fo"$file" - shift - ;; - *) - func_file_conv "$2" - set x "$@" -Fe"$file" - shift - ;; - esac - ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; - -I*) - func_file_conv "${1#-I}" mingw - set x "$@" -I"$file" - shift - ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; - -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" - shift - ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; - -L*) - func_cl_dashL "${1#-L}" - ;; - -static) - shared=false - ;; - -Wl,*) - arg=${1#-Wl,} - save_ifs="$IFS"; IFS=',' - for flag in $arg; do - IFS="$save_ifs" - linker_opts="$linker_opts $flag" - done - IFS="$save_ifs" - ;; - -Xlinker) - eat=1 - linker_opts="$linker_opts $2" - ;; - -*) - set x "$@" "$1" - shift - ;; - *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) - func_file_conv "$1" - set x "$@" -Tp"$file" - shift - ;; - *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) - func_file_conv "$1" mingw - set x "$@" "$file" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift - done - if test -n "$linker_opts"; then - linker_opts="-link$linker_opts" - fi - exec "$@" $linker_opts - exit 1 -} - -eat= - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) - func_cl_wrapper "$@" # Doesn't return... - ;; -esac - -ofile= -cfile= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - # So we strip '-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no '-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # '.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/pcre2/config-cmake.h.in b/pcre2/config-cmake.h.in deleted file mode 100644 index 0cfd8b134..000000000 --- a/pcre2/config-cmake.h.in +++ /dev/null @@ -1,48 +0,0 @@ -/* config.h for CMake builds */ - -#cmakedefine HAVE_DIRENT_H 1 -#cmakedefine HAVE_INTTYPES_H 1 -#cmakedefine HAVE_STDINT_H 1 -#cmakedefine HAVE_STRERROR 1 -#cmakedefine HAVE_SYS_STAT_H 1 -#cmakedefine HAVE_SYS_TYPES_H 1 -#cmakedefine HAVE_UNISTD_H 1 -#cmakedefine HAVE_WINDOWS_H 1 - -#cmakedefine HAVE_BCOPY 1 -#cmakedefine HAVE_MEMMOVE 1 - -#cmakedefine PCRE2_STATIC 1 - -#cmakedefine SUPPORT_PCRE2_8 1 -#cmakedefine SUPPORT_PCRE2_16 1 -#cmakedefine SUPPORT_PCRE2_32 1 -#cmakedefine PCRE2_DEBUG 1 - -#cmakedefine SUPPORT_LIBBZ2 1 -#cmakedefine SUPPORT_LIBEDIT 1 -#cmakedefine SUPPORT_LIBREADLINE 1 -#cmakedefine SUPPORT_LIBZ 1 - -#cmakedefine SUPPORT_JIT 1 -#cmakedefine SUPPORT_PCRE2GREP_JIT 1 -#cmakedefine SUPPORT_UNICODE 1 -#cmakedefine SUPPORT_VALGRIND 1 - -#cmakedefine BSR_ANYCRLF 1 -#cmakedefine EBCDIC 1 -#cmakedefine EBCDIC_NL25 1 -#cmakedefine HEAP_MATCH_RECURSE 1 -#cmakedefine NEVER_BACKSLASH_C 1 - -#define LINK_SIZE @PCRE2_LINK_SIZE@ -#define MATCH_LIMIT @PCRE2_MATCH_LIMIT@ -#define MATCH_LIMIT_RECURSION @PCRE2_MATCH_LIMIT_RECURSION@ -#define NEWLINE_DEFAULT @NEWLINE_DEFAULT@ -#define PARENS_NEST_LIMIT @PCRE2_PARENS_NEST_LIMIT@ -#define PCRE2GREP_BUFSIZE @PCRE2GREP_BUFSIZE@ - -#define MAX_NAME_SIZE 32 -#define MAX_NAME_COUNT 10000 - -/* end config.h for CMake builds */ diff --git a/pcre2/config.guess b/pcre2/config.guess deleted file mode 100755 index 6c32c8645..000000000 --- a/pcre2/config.guess +++ /dev/null @@ -1,1421 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. - -timestamp='2014-11-04' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches to . - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case "${UNAME_SYSTEM}" in -Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu - - eval $set_cc_for_build - cat <<-EOF > $dummy.c - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` - ;; -esac - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi - else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } - ;; - openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} - exit ;; - or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} - exit ;; - ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc - fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 - fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/pcre2/config.sub b/pcre2/config.sub deleted file mode 100755 index 7ffe37378..000000000 --- a/pcre2/config.sub +++ /dev/null @@ -1,1807 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. - -timestamp='2014-12-03' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2014 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - c8051-*) - os=-elf - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/pcre2/configure b/pcre2/configure deleted file mode 100755 index ad2696549..000000000 --- a/pcre2/configure +++ /dev/null @@ -1,18296 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCRE2 10.21. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='PCRE2' -PACKAGE_TARNAME='pcre2' -PACKAGE_VERSION='10.21' -PACKAGE_STRING='PCRE2 10.21' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -ac_unique_file="src/pcre2.h.in" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -WITH_GCOV_FALSE -WITH_GCOV_TRUE -GCOV_LIBS -GCOV_CXXFLAGS -GCOV_CFLAGS -GENHTML -LCOV -SHTOOL -VALGRIND_LIBS -VALGRIND_CFLAGS -PKG_CONFIG_LIBDIR -PKG_CONFIG_PATH -PKG_CONFIG -LIBBZ2 -LIBZ -DISTCHECK_CONFIGURE_FLAGS -EXTRA_LIBPCRE2_POSIX_LDFLAGS -EXTRA_LIBPCRE2_32_LDFLAGS -EXTRA_LIBPCRE2_16_LDFLAGS -EXTRA_LIBPCRE2_8_LDFLAGS -PTHREAD_CFLAGS -PTHREAD_LIBS -PTHREAD_CC -ax_pthread_config -PCRE2_STATIC_CFLAG -LIBREADLINE -WITH_VALGRIND_FALSE -WITH_VALGRIND_TRUE -WITH_UNICODE_FALSE -WITH_UNICODE_TRUE -WITH_JIT_FALSE -WITH_JIT_TRUE -WITH_REBUILD_CHARTABLES_FALSE -WITH_REBUILD_CHARTABLES_TRUE -WITH_DEBUG_FALSE -WITH_DEBUG_TRUE -WITH_PCRE2_32_FALSE -WITH_PCRE2_32_TRUE -WITH_PCRE2_16_FALSE -WITH_PCRE2_16_TRUE -WITH_PCRE2_8_FALSE -WITH_PCRE2_8_TRUE -enable_pcre2_32 -enable_pcre2_16 -enable_pcre2_8 -PCRE2_DATE -PCRE2_PRERELEASE -PCRE2_MINOR -PCRE2_MAJOR -HAVE_VISIBILITY -VISIBILITY_CXXFLAGS -VISIBILITY_CFLAGS -LT_SYS_LIBRARY_PATH -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -SED -LIBTOOL -OBJDUMP -DLLTOOL -AS -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -EGREP -GREP -CPP -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -ac_ct_AR -AR -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_maintainer_mode -enable_dependency_tracking -enable_shared -enable_static -with_pic -enable_fast_install -with_aix_soname -with_gnu_ld -with_sysroot -enable_libtool_lock -enable_pcre8 -enable_pcre16 -enable_pcre32 -enable_pcre2_8 -enable_pcre2_16 -enable_pcre2_32 -enable_debug -enable_jit -enable_pcre2grep_jit -enable_rebuild_chartables -enable_unicode -enable_newline_is_cr -enable_newline_is_lf -enable_newline_is_crlf -enable_newline_is_anycrlf -enable_newline_is_any -enable_bsr_anycrlf -enable_never_backslash_C -enable_ebcdic -enable_ebcdic_nl25 -enable_stack_for_recursion -enable_pcre2grep_libz -enable_pcre2grep_libbz2 -with_pcre2grep_bufsize -enable_pcre2test_libedit -enable_pcre2test_libreadline -with_link_size -with_parens_nest_limit -with_match_limit -with_match_limit_recursion -enable_valgrind -enable_coverage -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -LT_SYS_LIBRARY_PATH -PKG_CONFIG -PKG_CONFIG_PATH -PKG_CONFIG_LIBDIR -VALGRIND_CFLAGS -VALGRIND_LIBS -LCOV -GENHTML' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures PCRE2 10.21 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/pcre2] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of PCRE2 10.21:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - - --disable-pcre2-8 disable 8 bit character support - --enable-pcre2-16 enable 16 bit character support - --enable-pcre2-32 enable 32 bit character support - --enable-debug enable debugging code - --enable-jit enable Just-In-Time compiling support - --disable-pcre2grep-jit disable JIT support in pcre2grep - --enable-rebuild-chartables - rebuild character tables in current locale - --disable-unicode disable Unicode support - --enable-newline-is-cr use CR as newline character - --enable-newline-is-lf use LF as newline character (default) - --enable-newline-is-crlf - use CRLF as newline sequence - --enable-newline-is-anycrlf - use CR, LF, or CRLF as newline sequence - --enable-newline-is-any use any valid Unicode newline sequence - --enable-bsr-anycrlf \R matches only CR, LF, CRLF by default - --enable-never-backslash-C - use of \C causes an error - --enable-ebcdic assume EBCDIC coding rather than ASCII; incompatible - with --enable-utf; use only in (uncommon) EBCDIC - environments; it implies --enable-rebuild-chartables - --enable-ebcdic-nl25 set EBCDIC code for NL to 0x25 instead of 0x15; it - implies --enable-ebcdic - --disable-stack-for-recursion - don't use stack recursion when matching - --enable-pcre2grep-libz link pcre2grep with libz to handle .gz files - --enable-pcre2grep-libbz2 - link pcre2grep with libbz2 to handle .bz2 files - --enable-pcre2test-libedit - link pcre2test with libedit - --enable-pcre2test-libreadline - link pcre2test with libreadline - --enable-valgrind valgrind support - --enable-coverage enable code coverage reports using gcov - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-aix-soname=aix|svr4|both - shared library versioning (aka "SONAME") variant to - provide on AIX, [default=aix]. - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot[=DIR] Search for dependent libraries within DIR (or the - compiler's sysroot if not specified). - --with-pcre2grep-bufsize=N - pcre2grep buffer size (default=20480, minimum=8192) - --with-link-size=N internal link size (2, 3, or 4 allowed; default=2) - --with-parens-nest-limit=N - nested parentheses limit (default=250) - --with-match-limit=N default limit on internal looping (default=10000000) - --with-match-limit-recursion=N - default limit on internal recursion - (default=MATCH_LIMIT) - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - LT_SYS_LIBRARY_PATH - User-defined run-time library search path. - PKG_CONFIG path to pkg-config utility - PKG_CONFIG_PATH - directories to add to pkg-config's search path - PKG_CONFIG_LIBDIR - path overriding pkg-config's built-in search path - VALGRIND_CFLAGS - C compiler flags for VALGRIND, overriding pkg-config - VALGRIND_LIBS - linker flags for VALGRIND, overriding pkg-config - LCOV the ltp lcov program - GENHTML the ltp genhtml program - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -PCRE2 configure 10.21 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_find_intX_t LINENO BITS VAR -# ----------------------------------- -# Finds a signed integer type with width BITS, setting cache variable VAR -# accordingly. -ac_fn_c_find_intX_t () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 -$as_echo_n "checking for int$2_t... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in int$2_t 'int' 'long int' \ - 'long long int' 'short int' 'signed char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default - enum { N = $2 / 2 - 1 }; -int -main () -{ -static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default - enum { N = $2 / 2 - 1 }; -int -main () -{ -static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) - < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - case $ac_type in #( - int$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : - -else - break -fi - done -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_intX_t - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by PCRE2 $as_me 10.21, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -am__api_version='1.15' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='pcre2' - VERSION='10.21' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -ac_config_headers="$ac_config_headers src/config.h" - - -# FISH PATCH -# Enable maintainer mode to avoid spurious rebuilds due to timestamps in git -# not being stored. Discussion in https://github.com/fish-shell/fish-shell/issues/2469 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - -# END FISH PATCH - -# This is a new thing required to stop a warning from automake 1.12 -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar lib "link -lib" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar lib "link -lib" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 -$as_echo_n "checking the archiver ($AR) interface... " >&6; } -if ${am_cv_ar_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - am_cv_ar_interface=ar - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int some_variable = 0; -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 -$as_echo "$am_cv_ar_interface" >&6; } - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - as_fn_error $? "could not determine $AR interface" "$LINENO" 5 - ;; -esac - - -# This was added at the suggestion of libtoolize (03-Jan-10) - - -# The default CFLAGS in Autoconf are "-g -O2" for gcc and just "-g" for any -# other compiler. There doesn't seem to be a standard way of getting rid of the -# -g (which I don't think is needed for a production library). This fudge seems -# to achieve the necessary. First, we remember the externally set values of -# CFLAGS. Then call the AC_PROG_CC macro to find the compiler - if CFLAGS is -# not set, it will be set to Autoconf's defaults. Afterwards, if the original -# values were not set, remove the -g from the Autoconf defaults. - -remember_set_CFLAGS="$CFLAGS" - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - - -if test "x$remember_set_CFLAGS" = "x" -then - if test "$CFLAGS" = "-g -O2" - then - CFLAGS="-O2" - elif test "$CFLAGS" = "-g" - then - CFLAGS="" - fi -fi - -# Check for a 64-bit integer type -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" -case $ac_cv_c_int64_t in #( - no|yes) ;; #( - *) - -cat >>confdefs.h <<_ACEOF -#define int64_t $ac_cv_c_int64_t -_ACEOF -;; -esac - - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. -set dummy ${ac_tool_prefix}as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="${ac_tool_prefix}as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AS"; then - ac_ct_AS=$AS - # Extract the first word of "as", so it can be a program name with args. -set dummy as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AS"; then - ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AS="as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AS=$ac_cv_prog_ac_ct_AS -if test -n "$ac_ct_AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 -$as_echo "$ac_ct_AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AS" = x; then - AS="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AS=$ac_ct_AS - fi -else - AS="$ac_cv_prog_AS" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - - ;; -esac - -test -z "$AS" && AS=as - - - - - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.6' -macro_revision='2.4.6' - - - - - - - - - - - - - -ltmain=$ac_aux_dir/ltmain.sh - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case $ECHO in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test yes = "$GCC"; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return, which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD=$ac_prog - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test yes = "$with_gnu_ld"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD=$ac_dir/$ac_prog - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM=$NM -else - lt_nm_to_check=${ac_tool_prefix}nm - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/$lt_tmp_nm - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the 'sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty - case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; - *) lt_bad_file=/dev/null ;; - esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in - *$lt_bad_file* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break 2 - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break 2 - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS=$lt_save_ifs - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test no != "$lt_cv_path_NM"; then - NM=$lt_cv_path_NM -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols -headers" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test : != "$DUMPBIN"; then - NM=$DUMPBIN - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring=ABCD - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test X`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test 17 != "$i" # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n "$lt_cv_sys_max_cmd_len"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test yes != "$GCC"; then - reload_cmds=false - fi - ;; - darwin*) - if test yes = "$GCC"; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# 'unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# that responds to the $file_magic_cmd with a given extended regex. -# If you have 'file' or equivalent on your system and you're not sure -# whether 'pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd* | bitrig*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -os2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh; - # decide which one to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd=$ECHO - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cru} - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test 0 -eq "$ac_status"; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test 0 -ne "$ac_status"; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } - -if test no = "$lt_cv_ar_at_file"; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test ia64 = "$host_cpu"; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" - # Adjust the below global symbol transforms to fixup imported variables. - lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" - lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" - lt_c_name_lib_hook="\ - -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ - -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" -else - # Disable hooks by default. - lt_cv_sys_global_symbol_to_import= - lt_cdecl_hook= - lt_c_name_hook= - lt_c_name_lib_hook= -fi - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ -$lt_cdecl_hook\ -" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ -$lt_c_name_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" - -# Transform an extracted symbol line into symbol name with lib prefix and -# symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ -$lt_c_name_lib_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function, - # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ -" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ -" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ -" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ -" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS=conftstm.$ac_objext - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test yes = "$pipe_works"; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; -else - with_sysroot=no -fi - - -lt_sysroot= -case $with_sysroot in #( - yes) - if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 -$as_echo "$with_sysroot" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 -$as_echo_n "checking for a working dd... " >&6; } -if ${ac_cv_path_lt_DD+:} false; then : - $as_echo_n "(cached) " >&6 -else - printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -: ${lt_DD:=$DD} -if test -z "$lt_DD"; then - ac_path_lt_DD_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in dd; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_lt_DD" || continue -if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: -fi - $ac_path_lt_DD_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_lt_DD"; then - : - fi -else - ac_cv_path_lt_DD=$lt_DD -fi - -rm -f conftest.i conftest2.i conftest.out -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 -$as_echo "$ac_cv_path_lt_DD" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 -$as_echo_n "checking how to truncate binary pipes... " >&6; } -if ${lt_cv_truncate_bin+:} false; then : - $as_echo_n "(cached) " >&6 -else - printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -lt_cv_truncate_bin= -if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" -fi -rm -f conftest.i conftest2.i conftest.out -test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 -$as_echo "$lt_cv_truncate_bin" >&6; } - - - - - - - -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in $*""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test no = "$enable_libtool_lock" || enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out what ABI is being produced by ac_compile, and set mode - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE=32 - ;; - *ELF-64*) - HPUX_IA64_MODE=64 - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -mips64*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - emul=elf - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - emul="${emul}32" - ;; - *64-bit*) - emul="${emul}64" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *MSB*) - emul="${emul}btsmip" - ;; - *LSB*) - emul="${emul}ltsmip" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *N32*) - emul="${emul}n32" - ;; - esac - LD="${LD-ld} -m $emul" - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. Note that the listed cases only cover the - # situations where additional linker options are needed (such as when - # doing 32-bit compilation for a host where ld defaults to 64-bit, or - # vice versa); the common cases where no linker options are needed do - # not appear in the list. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*linux*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*linux*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test yes != "$lt_cv_cc_needs_belf"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS=$SAVE_CFLAGS - fi - ;; -*-*solaris*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*|x86_64-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD=${LD-ld}_sol2 - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks=$enable_libtool_lock - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test yes != "$lt_cv_path_mainfest_tool"; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "$LT_MULTI_MODULE"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&5 - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test 0 = "$_lt_result"; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&5 - elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test yes = "$lt_cv_apple_cc_single_mod"; then - _lt_dar_single_mod='$single_module' - fi - if test yes = "$lt_cv_ld_exported_symbols_list"; then - _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' - fi - if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x$2 in - x) - ;; - *:) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" - ;; - x:*) - eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" - ;; - *) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" - ;; - esac -} - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - - - -# Set options - - - - enable_dlopen=no - - - - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else - pic_mode=default -fi - - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - shared_archive_member_spec= -case $host,$enable_shared in -power*-*-aix[5-9]*,yes) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 -$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } - -# Check whether --with-aix-soname was given. -if test "${with_aix_soname+set}" = set; then : - withval=$with_aix_soname; case $withval in - aix|svr4|both) - ;; - *) - as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname -else - if ${lt_cv_with_aix_soname+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_with_aix_soname=aix -fi - - with_aix_soname=$lt_cv_with_aix_soname -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 -$as_echo "$with_aix_soname" >&6; } - if test aix != "$with_aix_soname"; then - # For the AIX way of multilib, we name the shared archive member - # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', - # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. - # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, - # the AIX toolchain works better with OBJECT_MODE set (default 32). - if test 64 = "${OBJECT_MODE-32}"; then - shared_archive_member_spec=shr_64 - else - shared_archive_member_spec=shr - fi - fi - ;; -*) - with_aix_soname=aix - ;; -esac - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS=$ltmain - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld=$lt_cv_prog_gnu_ld - -old_CC=$CC -old_CFLAGS=$CFLAGS - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -func_cc_basename $compiler -cc_basename=$func_cc_basename_result - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/${ac_tool_prefix}file"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac -fi - -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/file"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac -fi - -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC=$CC -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test yes = "$GCC"; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test yes = "$GCC"; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - lt_prog_compiler_pic='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - case $host_os in - os2*) - lt_prog_compiler_static='$wl-static' - ;; - esac - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - if test -n "$lt_prog_compiler_pic"; then - lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - case $cc_basename in - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - case $host_os in - os2*) - lt_prog_compiler_static='$wl-static' - ;; - esac - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='$wl-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64, which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ F* | *Sun*Fortran*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Intel*\ [CF]*Compiler*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - *Portland\ Group*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms that do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test yes = "$lt_cv_prog_compiler_pic_works"; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test yes = "$lt_cv_prog_compiler_static_works"; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links=nottested -if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test no = "$hard_links"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ' (' and ')$', so one must not match beginning or - # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', - # as well as any symbol that contains 'd'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test yes != "$GCC"; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test yes = "$with_gnu_ld"; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test yes = "$lt_use_gnu_ld_interface"; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='$wl' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - export_dynamic_flag_spec='$wl--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test ia64 != "$host_cpu"; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='$wl--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - shrext_cmds=.dll - archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - enable_shared_with_static_runtimes=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - export_dynamic_flag_spec='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test linux-dietlibc = "$host_os"; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test no = "$tmp_diet" - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - nagfor*) # NAGFOR 5.3 - tmp_sharedflag='-Wl,-shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - - if test yes = "$supports_anon_versioning"; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - tcc*) - export_dynamic_flag_spec='-rdynamic' - ;; - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test yes = "$supports_anon_versioning"; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test no = "$ld_shlibs"; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then - aix_use_runtimelinking=yes - break - fi - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # traditional, no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - hardcode_direct=no - hardcode_direct_absolute=no - ;; - esac - - if test yes = "$GCC"; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag="$shared_flag "'$wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - export_dynamic_flag_spec='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=/usr/lib:/lib - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=/usr/lib:/lib - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' $wl-bernotok' - allow_undefined_flag=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test yes = "$lt_cv_ld_force_load"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag=$_lt_dar_allow_undefined - case $cc_basename in - ifort*|nagfor*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test yes = "$_lt_dar_can_shared"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test yes = "$GCC"; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='$wl-E' - ;; - - hpux10*) - if test yes,no = "$GCC,$with_gnu_ld"; then - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test no = "$with_gnu_ld"; then - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='$wl-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test yes,no = "$GCC,$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler__b=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } - -if test yes = "$lt_cv_prog_compiler__b"; then - archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test no = "$with_gnu_ld"; then - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='$wl-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test yes = "$GCC"; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_irix_exported_symbol=yes -else - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test yes = "$lt_cv_irix_exported_symbol"; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' - fi - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - linux*) - case $cc_basename in - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - ld_shlibs=yes - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - export_dynamic_flag_spec='$wl-E' - else - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - shrext_cmds=.dll - archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - enable_shared_with_static_runtimes=yes - ;; - - osf3*) - if test yes = "$GCC"; then - allow_undefined_flag=' $wl-expect_unresolved $wl\*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test yes = "$GCC"; then - allow_undefined_flag=' $wl-expect_unresolved $wl\*' - archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test yes = "$GCC"; then - wlarc='$wl' - archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='$wl' - archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. GCC discards it without '$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test yes = "$GCC"; then - whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test sequent = "$host_vendor"; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='$wl-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='$wl-z,text' - allow_undefined_flag='$wl-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='$wl-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test sni = "$host_vendor"; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='$wl-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test no = "$ld_shlibs" && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test yes,yes = "$GCC,$enable_shared"; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test yes = "$GCC"; then - case $host_os in - darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; - *) lt_awk_arg='/^libraries:/' ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; - *) lt_sed_strip_eq='s|=/|/|g' ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary... - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path component already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). - case "$lt_multi_os_dir; $lt_search_path_spec " in - "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) - lt_multi_os_dir= - ;; - esac - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" - elif test -n "$lt_multi_os_dir"; then - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS = " "; FS = "/|\n";} { - lt_foo = ""; - lt_count = 0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo = "/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's|/\([A-Za-z]:\)|\1|g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=.so -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - - - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='$libname$release$shared_ext$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test ia64 = "$host_cpu"; then - # AIX 5 supports IA64 - library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line '#! .'. This would cause the generated library to - # depend on '.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # Using Import Files as archive members, it is possible to support - # filename-based versioning of shared library archives on AIX. While - # this would work for both with and without runtime linking, it will - # prevent static linking of such archives. So we do filename-based - # shared library versioning with .so extension only, which is used - # when both runtime linking and shared linking is enabled. - # Unfortunately, runtime linking may impact performance, so we do - # not want this to be the default eventually. Also, we use the - # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. - # To allow for filename-based versioning support, we need to create - # libNAME.so.V as an archive file, containing: - # *) an Import File, referring to the versioned filename of the - # archive as well as the shared archive member, telling the - # bitwidth (32 or 64) of that shared object, and providing the - # list of exported symbols of that shared object, eventually - # decorated with the 'weak' keyword - # *) the shared object with the F_LOADONLY flag set, to really avoid - # it being seen by the linker. - # At run time we better use the real file rather than another symlink, - # but for link time we create the symlink libNAME.so -> libNAME.so.V - - case $with_aix_soname,$aix_use_runtimelinking in - # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - aix,yes) # traditional libtool - dynamic_linker='AIX unversionable lib.so' - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - aix,no) # traditional AIX only - dynamic_linker='AIX lib.a(lib.so.V)' - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - ;; - svr4,*) # full svr4 only - dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,yes) # both, prefer svr4 - dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # unpreferred sharedlib libNAME.a needs extra handling - postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' - postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,no) # both, prefer aix - dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling - postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' - postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' - ;; - esac - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='$libname$shared_ext' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - library_names_spec='$libname.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec=$LIB - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' - soname_spec='$libname$release$major$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - if test 32 = "$HPUX_IA64_MODE"; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - sys_lib_dlsearch_path_spec=/usr/lib/hpux32 - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - sys_lib_dlsearch_path_spec=/usr/lib/hpux64 - fi - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test yes = "$lt_cv_prog_gnu_ld"; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" - sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -linux*android*) - version_type=none # Android doesn't support versioned libraries. - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext' - soname_spec='$libname$release$shared_ext' - finish_cmds= - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - hardcode_libdir_flag_spec='-L$libdir' - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Ideally, we could use ldconfig to report *all* directores which are - # searched for libraries, however this is still not possible. Aside from not - # being certain /sbin/ldconfig is available, command - # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, - # even though it is searched at run-time. Try to do the best guess by - # appending ld.so.conf contents (and includes) to the search path. - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd* | bitrig*) - version_type=sunos - sys_lib_dlsearch_path_spec=/usr/lib - need_lib_prefix=no - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - need_version=no - else - need_version=yes - fi - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -os2*) - libname_spec='$name' - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - # OS/2 can only load a DLL with a base name of 8 characters or less. - soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; - v=$($ECHO $release$versuffix | tr -d .-); - n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); - $ECHO $n$v`$shared_ext' - library_names_spec='${libname}_dll.$libext' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=BEGINLIBPATH - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test yes = "$with_gnu_ld"; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec; then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' - soname_spec='$libname$shared_ext.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=sco - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test yes = "$with_gnu_ld"; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test no = "$dynamic_linker" && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test yes = "$GCC"; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then - sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec -fi - -if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then - sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec -fi - -# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... -configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec - -# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code -func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" - -# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool -configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test yes = "$hardcode_automatic"; then - - # We can hardcode non-existent directories. - if test no != "$hardcode_direct" && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && - test no != "$hardcode_minus_L"; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test relink = "$hardcode_action" || - test yes = "$inherit_rpath"; then - # Fast installation is not supported - enable_fast_install=no -elif test yes = "$shlibpath_overrides_runpath" || - test no = "$enable_shared"; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test yes != "$enable_dlopen"; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen=load_add_on - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen=LoadLibrary - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else - - lt_cv_dlopen=dyld - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - tpf*) - # Don't try to run any link tests for TPF. We know it's impossible - # because TPF is a cross-compiler, and we know how we open DSOs. - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - lt_cv_dlopen_self=no - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen=shl_load -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen=dlopen -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test no = "$lt_cv_dlopen"; then - enable_dlopen=no - else - enable_dlopen=yes - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS=$CPPFLAGS - test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS=$LDFLAGS - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS=$LIBS - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test yes = "$cross_compiling"; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test yes = "$lt_cv_dlopen_self"; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test yes = "$cross_compiling"; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS=$save_CPPFLAGS - LDFLAGS=$save_LDFLAGS - LIBS=$save_LIBS - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report what library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC=$lt_save_CC - - - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - - -# Check for GCC visibility feature - - - - VISIBILITY_CFLAGS= - VISIBILITY_CXXFLAGS= - HAVE_VISIBILITY=0 - if test -n "$GCC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the -Werror option is usable" >&5 -$as_echo_n "checking whether the -Werror option is usable... " >&6; } - if ${pcre2_cv_cc_vis_werror+:} false; then : - $as_echo_n "(cached) " >&6 -else - - pcre2_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pcre2_cv_cc_vis_werror=yes -else - pcre2_cv_cc_vis_werror=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$pcre2_save_CFLAGS" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre2_cv_cc_vis_werror" >&5 -$as_echo "$pcre2_cv_cc_vis_werror" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for simple visibility declarations" >&5 -$as_echo_n "checking for simple visibility declarations... " >&6; } - if ${pcre2_cv_cc_visibility+:} false; then : - $as_echo_n "(cached) " >&6 -else - - pcre2_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fvisibility=hidden" - if test $pcre2_cv_cc_vis_werror = yes; then - CFLAGS="$CFLAGS -Werror" - fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern __attribute__((__visibility__("hidden"))) int hiddenvar; - extern __attribute__((__visibility__("default"))) int exportedvar; - extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); - extern __attribute__((__visibility__("default"))) int exportedfunc (void); - void dummyfunc (void) {} - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pcre2_cv_cc_visibility=yes -else - pcre2_cv_cc_visibility=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$pcre2_save_CFLAGS" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre2_cv_cc_visibility" >&5 -$as_echo "$pcre2_cv_cc_visibility" >&6; } - if test $pcre2_cv_cc_visibility = yes; then - VISIBILITY_CFLAGS="-fvisibility=hidden" - VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" - HAVE_VISIBILITY=1 - -$as_echo "#define PCRE2_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h - - -$as_echo "#define PCRE2_EXP_DEFN __attribute__ ((visibility (\"default\")))" >>confdefs.h - - -$as_echo "#define PCRE2POSIX_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h - - -$as_echo "#define PCRE2POSIX_EXP_DEFN extern __attribute__ ((visibility (\"default\")))" >>confdefs.h - - fi - fi - - - - -cat >>confdefs.h <<_ACEOF -#define HAVE_VISIBILITY $HAVE_VISIBILITY -_ACEOF - - - -# Versioning - -PCRE2_MAJOR="10" -PCRE2_MINOR="21" -PCRE2_PRERELEASE="" -PCRE2_DATE="2016-01-12" - -if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09" -then - echo "***" - echo "*** Minor version number $PCRE2_MINOR must not be used. ***" - echo "*** Use only 00 to 07 or 10 onwards, to avoid octal issues. ***" - echo "***" - exit 1 -fi - - - - - - -# Set a more sensible default value for $(htmldir). -if test "x$htmldir" = 'x${docdir}' -then - htmldir='${docdir}/html' -fi - -# Force an error for PCRE1 size options -# Check whether --enable-pcre8 was given. -if test "${enable_pcre8+set}" = set; then : - enableval=$enable_pcre8; -else - enable_pcre8=no -fi - -# Check whether --enable-pcre16 was given. -if test "${enable_pcre16+set}" = set; then : - enableval=$enable_pcre16; -else - enable_pcre16=no -fi - -# Check whether --enable-pcre32 was given. -if test "${enable_pcre32+set}" = set; then : - enableval=$enable_pcre32; -else - enable_pcre32=no -fi - - -if test "$enable_pcre8$enable_pcre16$enable_pcre32" != "nonono" -then - echo "** ERROR: Use --[en|dis]able-pcre2-[8|16|32], not --[en|dis]able-pcre[8|16|32]" - exit 1 -fi - -# Handle --disable-pcre2-8 (enabled by default) -# Check whether --enable-pcre2-8 was given. -if test "${enable_pcre2_8+set}" = set; then : - enableval=$enable_pcre2_8; -else - enable_pcre2_8=unset -fi - - - -# Handle --enable-pcre2-16 (disabled by default) -# Check whether --enable-pcre2-16 was given. -if test "${enable_pcre2_16+set}" = set; then : - enableval=$enable_pcre2_16; -else - enable_pcre2_16=unset -fi - - - -# Handle --enable-pcre2-32 (disabled by default) -# Check whether --enable-pcre2-32 was given. -if test "${enable_pcre2_32+set}" = set; then : - enableval=$enable_pcre2_32; -else - enable_pcre2_32=unset -fi - - - -# Handle --dnable-debug (disabled by default) -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; -else - enable_debug=no -fi - - -# Handle --enable-jit (disabled by default) -# Check whether --enable-jit was given. -if test "${enable_jit+set}" = set; then : - enableval=$enable_jit; -else - enable_jit=no -fi - - -# Handle --disable-pcre2grep-jit (enabled by default) -# Check whether --enable-pcre2grep-jit was given. -if test "${enable_pcre2grep_jit+set}" = set; then : - enableval=$enable_pcre2grep_jit; -else - enable_pcre2grep_jit=yes -fi - - -# Handle --enable-rebuild-chartables -# Check whether --enable-rebuild-chartables was given. -if test "${enable_rebuild_chartables+set}" = set; then : - enableval=$enable_rebuild_chartables; -else - enable_rebuild_chartables=no -fi - - -# Handle --disable-unicode (enabled by default) -# Check whether --enable-unicode was given. -if test "${enable_unicode+set}" = set; then : - enableval=$enable_unicode; -else - enable_unicode=unset -fi - - -# Handle newline options -ac_pcre2_newline=lf -# Check whether --enable-newline-is-cr was given. -if test "${enable_newline_is_cr+set}" = set; then : - enableval=$enable_newline_is_cr; ac_pcre2_newline=cr -fi - -# Check whether --enable-newline-is-lf was given. -if test "${enable_newline_is_lf+set}" = set; then : - enableval=$enable_newline_is_lf; ac_pcre2_newline=lf -fi - -# Check whether --enable-newline-is-crlf was given. -if test "${enable_newline_is_crlf+set}" = set; then : - enableval=$enable_newline_is_crlf; ac_pcre2_newline=crlf -fi - -# Check whether --enable-newline-is-anycrlf was given. -if test "${enable_newline_is_anycrlf+set}" = set; then : - enableval=$enable_newline_is_anycrlf; ac_pcre2_newline=anycrlf -fi - -# Check whether --enable-newline-is-any was given. -if test "${enable_newline_is_any+set}" = set; then : - enableval=$enable_newline_is_any; ac_pcre2_newline=any -fi - -enable_newline="$ac_pcre2_newline" - -# Handle --enable-bsr-anycrlf -# Check whether --enable-bsr-anycrlf was given. -if test "${enable_bsr_anycrlf+set}" = set; then : - enableval=$enable_bsr_anycrlf; -else - enable_bsr_anycrlf=no -fi - - -# Handle --enable-never-backslash-C -# Check whether --enable-never-backslash-C was given. -if test "${enable_never_backslash_C+set}" = set; then : - enableval=$enable_never_backslash_C; -else - enable_never_backslash_C=no -fi - - -# Handle --enable-ebcdic -# Check whether --enable-ebcdic was given. -if test "${enable_ebcdic+set}" = set; then : - enableval=$enable_ebcdic; -else - enable_ebcdic=no -fi - - -# Handle --enable-ebcdic-nl25 -# Check whether --enable-ebcdic-nl25 was given. -if test "${enable_ebcdic_nl25+set}" = set; then : - enableval=$enable_ebcdic_nl25; -else - enable_ebcdic_nl25=no -fi - - -# Handle --disable-stack-for-recursion -# Check whether --enable-stack-for-recursion was given. -if test "${enable_stack_for_recursion+set}" = set; then : - enableval=$enable_stack_for_recursion; -else - enable_stack_for_recursion=yes -fi - - -# Handle --enable-pcre2grep-libz -# Check whether --enable-pcre2grep-libz was given. -if test "${enable_pcre2grep_libz+set}" = set; then : - enableval=$enable_pcre2grep_libz; -else - enable_pcre2grep_libz=no -fi - - -# Handle --enable-pcre2grep-libbz2 -# Check whether --enable-pcre2grep-libbz2 was given. -if test "${enable_pcre2grep_libbz2+set}" = set; then : - enableval=$enable_pcre2grep_libbz2; -else - enable_pcre2grep_libbz2=no -fi - - -# Handle --with-pcre2grep-bufsize=N - -# Check whether --with-pcre2grep-bufsize was given. -if test "${with_pcre2grep_bufsize+set}" = set; then : - withval=$with_pcre2grep_bufsize; -else - with_pcre2grep_bufsize=20480 -fi - - -# Handle --enable-pcre2test-libedit -# Check whether --enable-pcre2test-libedit was given. -if test "${enable_pcre2test_libedit+set}" = set; then : - enableval=$enable_pcre2test_libedit; -else - enable_pcre2test_libedit=no -fi - - -# Handle --enable-pcre2test-libreadline -# Check whether --enable-pcre2test-libreadline was given. -if test "${enable_pcre2test_libreadline+set}" = set; then : - enableval=$enable_pcre2test_libreadline; -else - enable_pcre2test_libreadline=no -fi - - -# Handle --with-link-size=N - -# Check whether --with-link-size was given. -if test "${with_link_size+set}" = set; then : - withval=$with_link_size; -else - with_link_size=2 -fi - - -# Handle --with-parens-nest-limit=N - -# Check whether --with-parens-nest-limit was given. -if test "${with_parens_nest_limit+set}" = set; then : - withval=$with_parens_nest_limit; -else - with_parens_nest_limit=250 -fi - - -# Handle --with-match-limit=N - -# Check whether --with-match-limit was given. -if test "${with_match_limit+set}" = set; then : - withval=$with_match_limit; -else - with_match_limit=10000000 -fi - - -# Handle --with-match-limit_recursion=N -# -# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION -# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric -# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some -# different numeric value (or even the same numeric value as MATCH_LIMIT, -# though no longer defined in terms of the latter). -# - -# Check whether --with-match-limit-recursion was given. -if test "${with_match_limit_recursion+set}" = set; then : - withval=$with_match_limit_recursion; -else - with_match_limit_recursion=MATCH_LIMIT -fi - - -# Handle --enable-valgrind -# Check whether --enable-valgrind was given. -if test "${enable_valgrind+set}" = set; then : - enableval=$enable_valgrind; -else - enable_valgrind=no -fi - - -# Enable code coverage reports using gcov -# Check whether --enable-coverage was given. -if test "${enable_coverage+set}" = set; then : - enableval=$enable_coverage; -else - enable_coverage=no -fi - - -# Set the default value for pcre2-8 -if test "x$enable_pcre2_8" = "xunset" -then - enable_pcre2_8=yes -fi - -# Set the default value for pcre2-16 -if test "x$enable_pcre2_16" = "xunset" -then - enable_pcre2_16=no -fi - -# Set the default value for pcre2-32 -if test "x$enable_pcre2_32" = "xunset" -then - enable_pcre2_32=no -fi - -# Make sure at least one library is selected -if test "x$enable_pcre2_8$enable_pcre2_16$enable_pcre2_32" = "xnonono" -then - as_fn_error $? "At least one of the 8, 16 or 32 bit libraries must be enabled" "$LINENO" 5 -fi - -# Unicode is enabled by default. -if test "x$enable_unicode" = "xunset" -then - enable_unicode=yes -fi - -# Convert the newline identifier into the appropriate integer value. These must -# agree with the PCRE2_NEWLINE_xxx values in pcre2.h. - -case "$enable_newline" in - cr) ac_pcre2_newline_value=1 ;; - lf) ac_pcre2_newline_value=2 ;; - crlf) ac_pcre2_newline_value=3 ;; - any) ac_pcre2_newline_value=4 ;; - anycrlf) ac_pcre2_newline_value=5 ;; - *) - as_fn_error $? "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5 - ;; -esac - -# --enable-ebcdic-nl25 implies --enable-ebcdic -if test "x$enable_ebcdic_nl25" = "xyes"; then - enable_ebcdic=yes -fi - -# Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. -# Also check that UTF support is not requested, because PCRE2 cannot handle -# EBCDIC and UTF in the same build. To do so it would need to use different -# character constants depending on the mode. Also, EBCDIC cannot be used with -# 16-bit and 32-bit libraries. -# -if test "x$enable_ebcdic" = "xyes"; then - enable_rebuild_chartables=yes - if test "x$enable_unicode" = "xyes"; then - as_fn_error $? "support for EBCDIC and Unicode cannot be enabled at the same time" "$LINENO" 5 - fi - if test "x$enable_pcre2_16" = "xyes" -o "x$enable_pcre2_32" = "xyes"; then - as_fn_error $? "EBCDIC support is available only for the 8-bit library" "$LINENO" 5 - fi -fi - -# Check argument to --with-link-size -case "$with_link_size" in - 2|3|4) ;; - *) - as_fn_error $? "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 - ;; -esac - - - -# Checks for header files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -for ac_header in limits.h sys/types.h sys/stat.h dirent.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -for ac_header in windows.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" -if test "x$ac_cv_header_windows_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_WINDOWS_H 1 -_ACEOF - HAVE_WINDOWS_H=1 -fi - -done - - -# Conditional compilation - if test "x$enable_pcre2_8" = "xyes"; then - WITH_PCRE2_8_TRUE= - WITH_PCRE2_8_FALSE='#' -else - WITH_PCRE2_8_TRUE='#' - WITH_PCRE2_8_FALSE= -fi - - if test "x$enable_pcre2_16" = "xyes"; then - WITH_PCRE2_16_TRUE= - WITH_PCRE2_16_FALSE='#' -else - WITH_PCRE2_16_TRUE='#' - WITH_PCRE2_16_FALSE= -fi - - if test "x$enable_pcre2_32" = "xyes"; then - WITH_PCRE2_32_TRUE= - WITH_PCRE2_32_FALSE='#' -else - WITH_PCRE2_32_TRUE='#' - WITH_PCRE2_32_FALSE= -fi - - if test "x$enable_debug" = "xyes"; then - WITH_DEBUG_TRUE= - WITH_DEBUG_FALSE='#' -else - WITH_DEBUG_TRUE='#' - WITH_DEBUG_FALSE= -fi - - if test "x$enable_rebuild_chartables" = "xyes"; then - WITH_REBUILD_CHARTABLES_TRUE= - WITH_REBUILD_CHARTABLES_FALSE='#' -else - WITH_REBUILD_CHARTABLES_TRUE='#' - WITH_REBUILD_CHARTABLES_FALSE= -fi - - if test "x$enable_jit" = "xyes"; then - WITH_JIT_TRUE= - WITH_JIT_FALSE='#' -else - WITH_JIT_TRUE='#' - WITH_JIT_FALSE= -fi - - if test "x$enable_unicode" = "xyes"; then - WITH_UNICODE_TRUE= - WITH_UNICODE_FALSE='#' -else - WITH_UNICODE_TRUE='#' - WITH_UNICODE_FALSE= -fi - - if test "x$enable_valgrind" = "xyes"; then - WITH_VALGRIND_TRUE= - WITH_VALGRIND_FALSE='#' -else - WITH_VALGRIND_TRUE='#' - WITH_VALGRIND_FALSE= -fi - - -# Checks for typedefs, structures, and compiler characteristics. - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - - -# Checks for library functions. - -for ac_func in bcopy memmove strerror -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -# Check for the availability of libz (aka zlib) - -for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - HAVE_ZLIB_H=1 -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 -$as_echo_n "checking for gzopen in -lz... " >&6; } -if ${ac_cv_lib_z_gzopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gzopen (); -int -main () -{ -return gzopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_gzopen=yes -else - ac_cv_lib_z_gzopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 -$as_echo "$ac_cv_lib_z_gzopen" >&6; } -if test "x$ac_cv_lib_z_gzopen" = xyes; then : - HAVE_LIBZ=1 -fi - - -# Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, -# as for libz. However, this had the following problem, diagnosed and fixed by -# a user: -# -# - libbz2 uses the Pascal calling convention (WINAPI) for the functions -# under Win32. -# - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", -# therefore missing the function definition. -# - The compiler thus generates a "C" signature for the test function. -# - The linker fails to find the "C" function. -# - PCRE2 fails to configure if asked to do so against libbz2. -# -# Solution: -# -# - Replace the AC_CHECK_LIB test with a custom test. - -for ac_header in bzlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_BZLIB_H 1 -_ACEOF - HAVE_BZLIB_H=1 -fi - -done - -# Original test -# AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) -# -# Custom test follows - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbz2" >&5 -$as_echo_n "checking for libbz2... " >&6; } -OLD_LIBS="$LIBS" -LIBS="$LIBS -lbz2" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifdef HAVE_BZLIB_H -#include -#endif -int -main () -{ -return (int)BZ2_bzopen("conftest", "rb"); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; };HAVE_LIBBZ2=1; break; -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS="$OLD_LIBS" - -# Check for the availabiity of libreadline - -if test "$enable_pcre2test_libreadline" = "yes"; then - for ac_header in readline/readline.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_readline_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_READLINE_READLINE_H 1 -_ACEOF - HAVE_READLINE_H=1 -fi - -done - - for ac_header in readline/history.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_history_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_READLINE_HISTORY_H 1 -_ACEOF - HAVE_HISTORY_H=1 -fi - -done - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-lreadline" -else - unset ac_cv_lib_readline_readline; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline -ltinfo $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-ltinfo" -else - unset ac_cv_lib_readline_readline; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline -lcurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-lcurses" -else - unset ac_cv_lib_readline_readline; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline -lncurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-lncurses" -else - unset ac_cv_lib_readline_readline; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline -lncursesw $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-lncursesw" -else - unset ac_cv_lib_readline_readline; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline -ltermcap $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - LIBREADLINE="-ltermcap" -else - LIBREADLINE="" -fi - -fi - -fi - -fi - -fi - -fi - - - if test -n "$LIBREADLINE"; then - if test "$LIBREADLINE" != "-lreadline"; then - echo "-lreadline needs $LIBREADLINE" - LIBREADLINE="-lreadline $LIBREADLINE" - fi - fi -fi - - -# Check for the availability of libedit. Different distributions put its -# headers in different places. Try to cover the most common ones. - -if test "$enable_pcre2test_libedit" = "yes"; then - for ac_header in editline/readline.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_editline_readline_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EDITLINE_READLINE_H 1 -_ACEOF - HAVE_EDITLINE_READLINE_H=1 -else - for ac_header in edit/readline/readline.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "edit/readline/readline.h" "ac_cv_header_edit_readline_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_edit_readline_readline_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EDIT_READLINE_READLINE_H 1 -_ACEOF - HAVE_READLINE_READLINE_H=1 -else - for ac_header in readline/readline.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_readline_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_READLINE_READLINE_H 1 -_ACEOF - HAVE_READLINE_READLINE_H=1 -fi - -done - -fi - -done - -fi - -done - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 -$as_echo_n "checking for readline in -ledit... " >&6; } -if ${ac_cv_lib_edit_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ledit $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_edit_readline=yes -else - ac_cv_lib_edit_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 -$as_echo "$ac_cv_lib_edit_readline" >&6; } -if test "x$ac_cv_lib_edit_readline" = xyes; then : - LIBEDIT="-ledit" -fi - -fi - -# This facilitates -ansi builds under Linux - -PCRE2_STATIC_CFLAG="" -if test "x$enable_shared" = "xno" ; then - -$as_echo "#define PCRE2_STATIC 1" >>confdefs.h - - PCRE2_STATIC_CFLAG="-DPCRE2_STATIC" -fi - - -# Here is where PCRE2-specific defines are handled - -if test "$enable_pcre2_8" = "yes"; then - -$as_echo "#define SUPPORT_PCRE2_8 /**/" >>confdefs.h - -fi - -if test "$enable_pcre2_16" = "yes"; then - -$as_echo "#define SUPPORT_PCRE2_16 /**/" >>confdefs.h - -fi - -if test "$enable_pcre2_32" = "yes"; then - -$as_echo "#define SUPPORT_PCRE2_32 /**/" >>confdefs.h - -fi - -if test "$enable_debug" = "yes"; then - -$as_echo "#define PCRE2_DEBUG /**/" >>confdefs.h - -fi - -# Unless running under Windows, JIT support requires pthreads. - -if test "$enable_jit" = "yes"; then - if test "$HAVE_WINDOWS_H" != "1"; then - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ax_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 -$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_join (); -int -main () -{ -return pthread_join (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_pthread_ok=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 -$as_echo "$ax_pthread_ok" >&6; } - if test x"$ax_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case ${host_os} in - solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" - ;; - - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" - ;; -esac - -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do - - case $flag in - none) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 -$as_echo_n "checking whether pthreads work without any flags... " >&6; } - ;; - - -*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 -$as_echo_n "checking whether pthreads work with $flag... " >&6; } - PTHREAD_CFLAGS="$flag" - ;; - - pthread-config) - # Extract the first word of "pthread-config", so it can be a program name with args. -set dummy pthread-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ax_pthread_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ax_pthread_config"; then - ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ax_pthread_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" -fi -fi -ax_pthread_config=$ac_cv_prog_ax_pthread_config -if test -n "$ax_pthread_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 -$as_echo "$ax_pthread_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test x"$ax_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 -$as_echo_n "checking for the pthreads library -l$flag... " >&6; } - PTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; } -int -main () -{ -pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */ - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_pthread_ok=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 -$as_echo "$ax_pthread_ok" >&6; } - if test "x$ax_pthread_ok" = xyes; then - break; - fi - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 -$as_echo_n "checking for joinable pthread attribute... " >&6; } - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -int attr = $attr; return attr /* ; */ - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - attr_name=$attr; break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 -$as_echo "$attr_name" >&6; } - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - -cat >>confdefs.h <<_ACEOF -#define PTHREAD_CREATE_JOINABLE $attr_name -_ACEOF - - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 -$as_echo_n "checking if more special flags are required for pthreads... " >&6; } - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - flag="-mt -D_REENTRANT" - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 -$as_echo "${flag}" >&6; } - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 -$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } -if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include -int -main () -{ -int i = PTHREAD_PRIO_INHERIT; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_PTHREAD_PRIO_INHERIT=yes -else - ax_cv_PTHREAD_PRIO_INHERIT=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 -$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } - if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : - -$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h - -fi - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - # More AIX lossage: must compile with xlc_r or cc_r - if test x"$GCC" != xyes; then - for ac_prog in xlc_r cc_r -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PTHREAD_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PTHREAD_CC"; then - ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PTHREAD_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -PTHREAD_CC=$ac_cv_prog_PTHREAD_CC -if test -n "$PTHREAD_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 -$as_echo "$PTHREAD_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PTHREAD_CC" && break -done -test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" - - else - PTHREAD_CC=$CC - fi -else - PTHREAD_CC="$CC" -fi - - - - - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - -$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h - - : -else - ax_pthread_ok=no - as_fn_error $? "JIT support requires pthreads" "$LINENO" 5 -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - CC="$PTHREAD_CC" - CFLAGS="$PTHREAD_CFLAGS $CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - fi - -$as_echo "#define SUPPORT_JIT /**/" >>confdefs.h - -else - enable_pcre2grep_jit="no" -fi - -if test "$enable_pcre2grep_jit" = "yes"; then - -$as_echo "#define SUPPORT_PCRE2GREP_JIT /**/" >>confdefs.h - -fi - -if test "$enable_unicode" = "yes"; then - -$as_echo "#define SUPPORT_UNICODE /**/" >>confdefs.h - -fi - -if test "$enable_stack_for_recursion" = "no"; then - -$as_echo "#define HEAP_MATCH_RECURSE /**/" >>confdefs.h - -fi - -if test "$enable_pcre2grep_libz" = "yes"; then - -$as_echo "#define SUPPORT_LIBZ /**/" >>confdefs.h - -fi - -if test "$enable_pcre2grep_libbz2" = "yes"; then - -$as_echo "#define SUPPORT_LIBBZ2 /**/" >>confdefs.h - -fi - -if test $with_pcre2grep_bufsize -lt 8192 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192" >&5 -$as_echo "$as_me: WARNING: $with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192" >&2;} - with_pcre2grep_bufsize="8192" -else - if test $? -gt 1 ; then - as_fn_error $? "Bad value for --with-pcre2grep-bufsize" "$LINENO" 5 - fi -fi - - -cat >>confdefs.h <<_ACEOF -#define PCRE2GREP_BUFSIZE $with_pcre2grep_bufsize -_ACEOF - - -if test "$enable_pcre2test_libedit" = "yes"; then - -$as_echo "#define SUPPORT_LIBEDIT /**/" >>confdefs.h - - LIBREADLINE="$LIBEDIT" -elif test "$enable_pcre2test_libreadline" = "yes"; then - -$as_echo "#define SUPPORT_LIBREADLINE /**/" >>confdefs.h - -fi - - -cat >>confdefs.h <<_ACEOF -#define NEWLINE_DEFAULT $ac_pcre2_newline_value -_ACEOF - - -if test "$enable_bsr_anycrlf" = "yes"; then - -$as_echo "#define BSR_ANYCRLF /**/" >>confdefs.h - -fi - -if test "$enable_never_backslash_C" = "yes"; then - -$as_echo "#define NEVER_BACKSLASH_C /**/" >>confdefs.h - -fi - - -cat >>confdefs.h <<_ACEOF -#define LINK_SIZE $with_link_size -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define PARENS_NEST_LIMIT $with_parens_nest_limit -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define MATCH_LIMIT $with_match_limit -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define MATCH_LIMIT_RECURSION $with_match_limit_recursion -_ACEOF - - - -$as_echo "#define MAX_NAME_SIZE 32" >>confdefs.h - - - -$as_echo "#define MAX_NAME_COUNT 10000" >>confdefs.h - - - - -if test "$enable_ebcdic" = "yes"; then - -cat >>confdefs.h <<_ACEOF -#define EBCDIC /**/ -_ACEOF - -fi - -if test "$enable_ebcdic_nl25" = "yes"; then - -cat >>confdefs.h <<_ACEOF -#define EBCDIC_NL25 /**/ -_ACEOF - -fi - -if test "$enable_valgrind" = "yes"; then - -cat >>confdefs.h <<_ACEOF -#define SUPPORT_VALGRIND /**/ -_ACEOF - -fi - -# Platform specific issues -NO_UNDEFINED= -EXPORT_ALL_SYMBOLS= -case $host_os in - cygwin* | mingw* ) - if test X"$enable_shared" = Xyes; then - NO_UNDEFINED="-no-undefined" - EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" - fi - ;; -esac - -# The extra LDFLAGS for each particular library. The libpcre2*_version values -# are m4 variables, assigned above. - -EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" - -EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" - -EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" - -EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \ - $NO_UNDEFINED -version-info 0:1:0" - - - - - - -# When we run 'make distcheck', use these arguments. Turning off compiler -# optimization makes it run faster. -DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre2-16 --enable-pcre2-32 --enable-jit --enable-utf" - - -# Check that, if --enable-pcre2grep-libz or --enable-pcre2grep-libbz2 is -# specified, the relevant library is available. - -if test "$enable_pcre2grep_libz" = "yes"; then - if test "$HAVE_ZLIB_H" != "1"; then - echo "** Cannot --enable-pcre2grep-libz because zlib.h was not found" - exit 1 - fi - if test "$HAVE_LIBZ" != "1"; then - echo "** Cannot --enable-pcre2grep-libz because libz was not found" - exit 1 - fi - LIBZ="-lz" -fi - - -if test "$enable_pcre2grep_libbz2" = "yes"; then - if test "$HAVE_BZLIB_H" != "1"; then - echo "** Cannot --enable-pcre2grep-libbz2 because bzlib.h was not found" - exit 1 - fi - if test "$HAVE_LIBBZ2" != "1"; then - echo "** Cannot --enable-pcre2grep-libbz2 because libbz2 was not found" - exit 1 - fi - LIBBZ2="-lbz2" -fi - - -# Similarly for --enable-pcre2test-readline - -if test "$enable_pcre2test_libedit" = "yes"; then - if test "$enable_pcre2test_libreadline" = "yes"; then - echo "** Cannot use both --enable-pcre2test-libedit and --enable-pcre2test-readline" - exit 1 - fi - if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ - "$HAVE_READLINE_READLINE_H" != "1"; then - echo "** Cannot --enable-pcre2test-libedit because neither editline/readline.h" - echo "** nor readline/readline.h was found." - exit 1 - fi - if test -z "$LIBEDIT"; then - echo "** Cannot --enable-pcre2test-libedit because libedit library was not found." - exit 1 - fi -fi - -if test "$enable_pcre2test_libreadline" = "yes"; then - if test "$HAVE_READLINE_H" != "1"; then - echo "** Cannot --enable-pcre2test-readline because readline/readline.h was not found." - exit 1 - fi - if test "$HAVE_HISTORY_H" != "1"; then - echo "** Cannot --enable-pcre2test-readline because readline/history.h was not found." - exit 1 - fi - if test -z "$LIBREADLINE"; then - echo "** Cannot --enable-pcre2test-readline because readline library was not found." - exit 1 - fi -fi - -# Handle valgrind support - -if test "$enable_valgrind" = "yes"; then - - - - - - - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - PKG_CONFIG="" - fi -fi - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5 -$as_echo_n "checking for VALGRIND... " >&6; } - -if test -n "$VALGRIND_CFLAGS"; then - pkg_cv_VALGRIND_CFLAGS="$VALGRIND_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 - ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_VALGRIND_CFLAGS=`$PKG_CONFIG --cflags "valgrind" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$VALGRIND_LIBS"; then - pkg_cv_VALGRIND_LIBS="$VALGRIND_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 - ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_VALGRIND_LIBS=`$PKG_CONFIG --libs "valgrind" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - VALGRIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "valgrind" 2>&1` - else - VALGRIND_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "valgrind" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$VALGRIND_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (valgrind) were not met: - -$VALGRIND_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables VALGRIND_CFLAGS -and VALGRIND_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables VALGRIND_CFLAGS -and VALGRIND_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } -else - VALGRIND_CFLAGS=$pkg_cv_VALGRIND_CFLAGS - VALGRIND_LIBS=$pkg_cv_VALGRIND_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi -fi - -# Handle code coverage reporting support -if test "$enable_coverage" = "yes"; then - if test "x$GCC" != "xyes"; then - as_fn_error $? "Code coverage reports can only be generated when using GCC" "$LINENO" 5 - fi - - # ccache is incompatible with gcov - # Extract the first word of "shtool", so it can be a program name with args. -set dummy shtool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SHTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SHTOOL in - [\\/]* | ?:[\\/]*) - ac_cv_path_SHTOOL="$SHTOOL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SHTOOL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_SHTOOL" && ac_cv_path_SHTOOL="false" - ;; -esac -fi -SHTOOL=$ac_cv_path_SHTOOL -if test -n "$SHTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHTOOL" >&5 -$as_echo "$SHTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - case `$SHTOOL path $CC` in - *ccache*) cc_ccache=yes;; - *) cc_ccache=no;; - esac - - if test "$cc_ccache" = "yes"; then - if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then - as_fn_error $? "must export CCACHE_DISABLE=1 to disable ccache for code coverage" "$LINENO" 5 - fi - fi - - - # Extract the first word of "lcov", so it can be a program name with args. -set dummy lcov; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $LCOV in - [\\/]* | ?:[\\/]*) - ac_cv_path_LCOV="$LCOV" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LCOV="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_LCOV" && ac_cv_path_LCOV="false" - ;; -esac -fi -LCOV=$ac_cv_path_LCOV -if test -n "$LCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 -$as_echo "$LCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$LCOV" = "xfalse"; then - as_fn_error $? "lcov not found" "$LINENO" 5 - fi - - - # Extract the first word of "genhtml", so it can be a program name with args. -set dummy genhtml; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_GENHTML+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $GENHTML in - [\\/]* | ?:[\\/]*) - ac_cv_path_GENHTML="$GENHTML" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_GENHTML="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_GENHTML" && ac_cv_path_GENHTML="false" - ;; -esac -fi -GENHTML=$ac_cv_path_GENHTML -if test -n "$GENHTML"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 -$as_echo "$GENHTML" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$GENHTML" = "xfalse"; then - as_fn_error $? "genhtml not found" "$LINENO" 5 - fi - - # Set flags needed for gcov - GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" - GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" - GCOV_LIBS="-lgcov" - - - -fi # enable_coverage - - if test "x$enable_coverage" = "xyes"; then - WITH_GCOV_TRUE= - WITH_GCOV_FALSE='#' -else - WITH_GCOV_TRUE='#' - WITH_GCOV_FALSE= -fi - - -# Produce these files, in addition to config.h. -ac_config_files="$ac_config_files Makefile libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc libpcre2-posix.pc pcre2-config src/pcre2.h" - - -# Make the generated script files executable. -ac_config_commands="$ac_config_commands script-chmod" - - -# Make sure that pcre2_chartables.c is removed in case the method for -# creating it was changed by reconfiguration. -ac_config_commands="$ac_config_commands delete-old-chartables" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_PCRE2_8_TRUE}" && test -z "${WITH_PCRE2_8_FALSE}"; then - as_fn_error $? "conditional \"WITH_PCRE2_8\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_PCRE2_16_TRUE}" && test -z "${WITH_PCRE2_16_FALSE}"; then - as_fn_error $? "conditional \"WITH_PCRE2_16\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_PCRE2_32_TRUE}" && test -z "${WITH_PCRE2_32_FALSE}"; then - as_fn_error $? "conditional \"WITH_PCRE2_32\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_DEBUG_TRUE}" && test -z "${WITH_DEBUG_FALSE}"; then - as_fn_error $? "conditional \"WITH_DEBUG\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_REBUILD_CHARTABLES_TRUE}" && test -z "${WITH_REBUILD_CHARTABLES_FALSE}"; then - as_fn_error $? "conditional \"WITH_REBUILD_CHARTABLES\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_JIT_TRUE}" && test -z "${WITH_JIT_FALSE}"; then - as_fn_error $? "conditional \"WITH_JIT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_UNICODE_TRUE}" && test -z "${WITH_UNICODE_FALSE}"; then - as_fn_error $? "conditional \"WITH_UNICODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_VALGRIND_TRUE}" && test -z "${WITH_VALGRIND_FALSE}"; then - as_fn_error $? "conditional \"WITH_VALGRIND\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${WITH_GCOV_TRUE}" && test -z "${WITH_GCOV_FALSE}"; then - as_fn_error $? "conditional \"WITH_GCOV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by PCRE2 $as_me 10.21, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -PCRE2 config.status 10.21 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' -configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in AS \ -DLLTOOL \ -OBJDUMP \ -SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_import \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -lt_cv_nm_interface \ -nm_file_list_spec \ -lt_cv_truncate_bin \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -configure_time_dlsearch_path \ -configure_time_lt_sys_library_path; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' - -# See if we are running on zsh, and set the options that allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "libpcre2-8.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-8.pc" ;; - "libpcre2-16.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-16.pc" ;; - "libpcre2-32.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-32.pc" ;; - "libpcre2-posix.pc") CONFIG_FILES="$CONFIG_FILES libpcre2-posix.pc" ;; - "pcre2-config") CONFIG_FILES="$CONFIG_FILES pcre2-config" ;; - "src/pcre2.h") CONFIG_FILES="$CONFIG_FILES src/pcre2.h" ;; - "script-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS script-chmod" ;; - "delete-old-chartables") CONFIG_COMMANDS="$CONFIG_COMMANDS delete-old-chartables" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - "libtool":C) - - # See if we are running on zsh, and set the options that allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST - fi - - cfgfile=${ofile}T - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL -# Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. - -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit, 1996 - -# Copyright (C) 2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program or library that is built -# using GNU Libtool, you may include this file under the same -# distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -# The names of the tagged configurations supported by this script. -available_tags='' - -# Configured defaults for sys_lib_dlsearch_path munging. -: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} - -# ### BEGIN LIBTOOL CONFIG - -# Assembler program. -AS=$lt_AS - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Object dumper program. -OBJDUMP=$lt_OBJDUMP - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shared archive member basename,for filename based shared library versioning on AIX. -shared_archive_member_spec=$shared_archive_member_spec - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm into a list of symbols to manually relocate. -global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# The name lister interface. -nm_interface=$lt_lt_cv_nm_interface - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and where our libraries should be installed. -lt_sysroot=$lt_sysroot - -# Command to truncate a binary pipe. -lt_truncate_bin=$lt_lt_cv_truncate_bin - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Detected run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path - -# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. -configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \$shlibpath_var if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - cat <<'_LT_EOF' >> "$cfgfile" - -# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE - -# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x$2 in - x) - ;; - *:) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" - ;; - x:*) - eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" - ;; - *) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" - ;; - esac -} - - -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in $*""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} - - -# ### END FUNCTIONS SHARED WITH CONFIGURE - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain=$ac_aux_dir/ltmain.sh - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - "script-chmod":C) chmod a+x pcre2-config ;; - "delete-old-chartables":C) rm -f pcre2_chartables.c ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -# Print out a nice little message after configure is run displaying the -# chosen options. - -ebcdic_nl_code=n/a -if test "$enable_ebcdic_nl25" = "yes"; then - ebcdic_nl_code=0x25 -elif test "$enable_ebcdic" = "yes"; then - ebcdic_nl_code=0x15 -fi - -cat < -#endif]], -[[return (int)BZ2_bzopen("conftest", "rb");]])], -[AC_MSG_RESULT([yes]);HAVE_LIBBZ2=1; break;], -AC_MSG_RESULT([no])) -LIBS="$OLD_LIBS" - -# Check for the availabiity of libreadline - -if test "$enable_pcre2test_libreadline" = "yes"; then - AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1]) - AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1]) - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lreadline"], - [unset ac_cv_lib_readline_readline; - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltinfo"], - [unset ac_cv_lib_readline_readline; - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lcurses"], - [unset ac_cv_lib_readline_readline; - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncurses"], - [unset ac_cv_lib_readline_readline; - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncursesw"], - [unset ac_cv_lib_readline_readline; - AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltermcap"], - [LIBREADLINE=""], - [-ltermcap])], - [-lncursesw])], - [-lncurses])], - [-lcurses])], - [-ltinfo])]) - AC_SUBST(LIBREADLINE) - if test -n "$LIBREADLINE"; then - if test "$LIBREADLINE" != "-lreadline"; then - echo "-lreadline needs $LIBREADLINE" - LIBREADLINE="-lreadline $LIBREADLINE" - fi - fi -fi - - -# Check for the availability of libedit. Different distributions put its -# headers in different places. Try to cover the most common ones. - -if test "$enable_pcre2test_libedit" = "yes"; then - AC_CHECK_HEADERS([editline/readline.h], [HAVE_EDITLINE_READLINE_H=1], - [AC_CHECK_HEADERS([edit/readline/readline.h], [HAVE_READLINE_READLINE_H=1], - [AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_READLINE_H=1])])]) - AC_CHECK_LIB([edit], [readline], [LIBEDIT="-ledit"]) -fi - -# This facilitates -ansi builds under Linux -dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc]) - -PCRE2_STATIC_CFLAG="" -if test "x$enable_shared" = "xno" ; then - AC_DEFINE([PCRE2_STATIC], [1], [ - Define to any value if linking statically (TODO: make nice with Libtool)]) - PCRE2_STATIC_CFLAG="-DPCRE2_STATIC" -fi -AC_SUBST(PCRE2_STATIC_CFLAG) - -# Here is where PCRE2-specific defines are handled - -if test "$enable_pcre2_8" = "yes"; then - AC_DEFINE([SUPPORT_PCRE2_8], [], [ - Define to any value to enable the 8 bit PCRE2 library.]) -fi - -if test "$enable_pcre2_16" = "yes"; then - AC_DEFINE([SUPPORT_PCRE2_16], [], [ - Define to any value to enable the 16 bit PCRE2 library.]) -fi - -if test "$enable_pcre2_32" = "yes"; then - AC_DEFINE([SUPPORT_PCRE2_32], [], [ - Define to any value to enable the 32 bit PCRE2 library.]) -fi - -if test "$enable_debug" = "yes"; then - AC_DEFINE([PCRE2_DEBUG], [], [ - Define to any value to include debugging code.]) -fi - -# Unless running under Windows, JIT support requires pthreads. - -if test "$enable_jit" = "yes"; then - if test "$HAVE_WINDOWS_H" != "1"; then - AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])]) - CC="$PTHREAD_CC" - CFLAGS="$PTHREAD_CFLAGS $CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - fi - AC_DEFINE([SUPPORT_JIT], [], [ - Define to any value to enable support for Just-In-Time compiling.]) -else - enable_pcre2grep_jit="no" -fi - -if test "$enable_pcre2grep_jit" = "yes"; then - AC_DEFINE([SUPPORT_PCRE2GREP_JIT], [], [ - Define to any value to enable JIT support in pcre2grep.]) -fi - -if test "$enable_unicode" = "yes"; then - AC_DEFINE([SUPPORT_UNICODE], [], [ - Define to any value to enable support for Unicode and UTF encoding. - This will work even in an EBCDIC environment, but it is incompatible - with the EBCDIC macro. That is, PCRE2 can support *either* EBCDIC - code *or* ASCII/Unicode, but not both at once.]) -fi - -if test "$enable_stack_for_recursion" = "no"; then - AC_DEFINE([HEAP_MATCH_RECURSE], [], [ - PCRE2 uses recursive function calls to handle backtracking while - matching. This can sometimes be a problem on systems that have - stacks of limited size. Define HEAP_MATCH_RECURSE to any value to get a - version that doesn't use recursion in the match() function; instead - it creates its own stack by steam using memory from the heap. For more - detail, see the comments and other stuff just above the match() function.]) -fi - -if test "$enable_pcre2grep_libz" = "yes"; then - AC_DEFINE([SUPPORT_LIBZ], [], [ - Define to any value to allow pcre2grep to be linked with libz, so that it is - able to handle .gz files.]) -fi - -if test "$enable_pcre2grep_libbz2" = "yes"; then - AC_DEFINE([SUPPORT_LIBBZ2], [], [ - Define to any value to allow pcre2grep to be linked with libbz2, so that it - is able to handle .bz2 files.]) -fi - -if test $with_pcre2grep_bufsize -lt 8192 ; then - AC_MSG_WARN([$with_pcre2grep_bufsize is too small for --with-pcre2grep-bufsize; using 8192]) - with_pcre2grep_bufsize="8192" -else - if test $? -gt 1 ; then - AC_MSG_ERROR([Bad value for --with-pcre2grep-bufsize]) - fi -fi - -AC_DEFINE_UNQUOTED([PCRE2GREP_BUFSIZE], [$with_pcre2grep_bufsize], [ - The value of PCRE2GREP_BUFSIZE determines the size of buffer used by pcre2grep - to hold parts of the file it is searching. This is also the minimum value. - The actual amount of memory used by pcre2grep is three times this number, - because it allows for the buffering of "before" and "after" lines.]) - -if test "$enable_pcre2test_libedit" = "yes"; then - AC_DEFINE([SUPPORT_LIBEDIT], [], [ - Define to any value to allow pcre2test to be linked with libedit.]) - LIBREADLINE="$LIBEDIT" -elif test "$enable_pcre2test_libreadline" = "yes"; then - AC_DEFINE([SUPPORT_LIBREADLINE], [], [ - Define to any value to allow pcre2test to be linked with libreadline.]) -fi - -AC_DEFINE_UNQUOTED([NEWLINE_DEFAULT], [$ac_pcre2_newline_value], [ - The value of NEWLINE_DEFAULT determines the default newline character - sequence. PCRE2 client programs can override this by selecting other values - at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), - and 5 (ANYCRLF).]) - -if test "$enable_bsr_anycrlf" = "yes"; then - AC_DEFINE([BSR_ANYCRLF], [], [ - By default, the \R escape sequence matches any Unicode line ending - character or sequence of characters. If BSR_ANYCRLF is defined (to any - value), this is changed so that backslash-R matches only CR, LF, or CRLF. - The build-time default can be overridden by the user of PCRE2 at runtime.]) -fi - -if test "$enable_never_backslash_C" = "yes"; then - AC_DEFINE([NEVER_BACKSLASH_C], [], [ - Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns.]) -fi - -AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [ - The value of LINK_SIZE determines the number of bytes used to store - links as offsets within the compiled regex. The default is 2, which - allows for compiled patterns up to 64K long. This covers the vast - majority of cases. However, PCRE2 can also be compiled to use 3 or 4 - bytes instead. This allows for longer patterns in extreme cases.]) - -AC_DEFINE_UNQUOTED([PARENS_NEST_LIMIT], [$with_parens_nest_limit], [ - The value of PARENS_NEST_LIMIT specifies the maximum depth of nested - parentheses (of any kind) in a pattern. This limits the amount of system - stack that is used while compiling a pattern.]) - -AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ - The value of MATCH_LIMIT determines the default number of times the - internal match() function can be called during a single execution of - pcre2_match(). There is a runtime interface for setting a different - limit. The limit exists in order to catch runaway regular - expressions that take for ever to determine that they do not match. - The default is set very large so that it does not accidentally catch - legitimate cases.]) - -AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ - The above limit applies to all calls of match(), whether or not they - increase the recursion depth. In some environments it is desirable - to limit the depth of recursive calls of match() more strictly, in - order to restrict the maximum amount of stack (or heap, if - HEAP_MATCH_RECURSE is defined) that is used. The value of - MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To - have any useful effect, it must be less than the value of - MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. - There is a runtime method for setting a different limit.]) - -AC_DEFINE([MAX_NAME_SIZE], [32], [ - This limit is parameterized just in case anybody ever wants to - change it. Care must be taken if it is increased, because it guards - against integer overflow caused by enormously large patterns.]) - -AC_DEFINE([MAX_NAME_COUNT], [10000], [ - This limit is parameterized just in case anybody ever wants to - change it. Care must be taken if it is increased, because it guards - against integer overflow caused by enormously large patterns.]) - -AH_VERBATIM([PCRE2_EXP_DEFN], [ -/* If you are compiling for a system other than a Unix-like system or - Win32, and it needs some magic to be inserted before the definition - of a function that is exported by the library, define this macro to - contain the relevant magic. If you do not define this macro, a suitable - __declspec value is used for Windows systems; in other environments - "extern" is used for a C compiler and "extern C" for a C++ compiler. - This macro apears at the start of every exported function that is part - of the external API. It does not appear on functions that are "external" - in the C sense, but which are internal to the library. */ -#undef PCRE2_EXP_DEFN]) - -if test "$enable_ebcdic" = "yes"; then - AC_DEFINE_UNQUOTED([EBCDIC], [], [ - If you are compiling for a system that uses EBCDIC instead of ASCII - character codes, define this macro to any value. When EBCDIC is set, PCRE2 - assumes that all input strings are in EBCDIC. If you do not define this - macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It - is not possible to build a version of PCRE2 that supports both EBCDIC and - UTF-8/16/32.]) -fi - -if test "$enable_ebcdic_nl25" = "yes"; then - AC_DEFINE_UNQUOTED([EBCDIC_NL25], [], [ - In an EBCDIC environment, define this macro to any value to arrange for - the NL character to be 0x25 instead of the default 0x15. NL plays the role - that LF does in an ASCII/Unicode environment.]) -fi - -if test "$enable_valgrind" = "yes"; then - AC_DEFINE_UNQUOTED([SUPPORT_VALGRIND], [], [ - Define to any value for valgrind support to find invalid memory reads.]) -fi - -# Platform specific issues -NO_UNDEFINED= -EXPORT_ALL_SYMBOLS= -case $host_os in - cygwin* | mingw* ) - if test X"$enable_shared" = Xyes; then - NO_UNDEFINED="-no-undefined" - EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" - fi - ;; -esac - -# The extra LDFLAGS for each particular library. The libpcre2*_version values -# are m4 variables, assigned above. - -EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \ - $NO_UNDEFINED -version-info libpcre2_8_version" - -EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \ - $NO_UNDEFINED -version-info libpcre2_16_version" - -EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \ - $NO_UNDEFINED -version-info libpcre2_32_version" - -EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \ - $NO_UNDEFINED -version-info libpcre2_posix_version" - -AC_SUBST(EXTRA_LIBPCRE2_8_LDFLAGS) -AC_SUBST(EXTRA_LIBPCRE2_16_LDFLAGS) -AC_SUBST(EXTRA_LIBPCRE2_32_LDFLAGS) -AC_SUBST(EXTRA_LIBPCRE2_POSIX_LDFLAGS) - -# When we run 'make distcheck', use these arguments. Turning off compiler -# optimization makes it run faster. -DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre2-16 --enable-pcre2-32 --enable-jit --enable-utf" -AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) - -# Check that, if --enable-pcre2grep-libz or --enable-pcre2grep-libbz2 is -# specified, the relevant library is available. - -if test "$enable_pcre2grep_libz" = "yes"; then - if test "$HAVE_ZLIB_H" != "1"; then - echo "** Cannot --enable-pcre2grep-libz because zlib.h was not found" - exit 1 - fi - if test "$HAVE_LIBZ" != "1"; then - echo "** Cannot --enable-pcre2grep-libz because libz was not found" - exit 1 - fi - LIBZ="-lz" -fi -AC_SUBST(LIBZ) - -if test "$enable_pcre2grep_libbz2" = "yes"; then - if test "$HAVE_BZLIB_H" != "1"; then - echo "** Cannot --enable-pcre2grep-libbz2 because bzlib.h was not found" - exit 1 - fi - if test "$HAVE_LIBBZ2" != "1"; then - echo "** Cannot --enable-pcre2grep-libbz2 because libbz2 was not found" - exit 1 - fi - LIBBZ2="-lbz2" -fi -AC_SUBST(LIBBZ2) - -# Similarly for --enable-pcre2test-readline - -if test "$enable_pcre2test_libedit" = "yes"; then - if test "$enable_pcre2test_libreadline" = "yes"; then - echo "** Cannot use both --enable-pcre2test-libedit and --enable-pcre2test-readline" - exit 1 - fi - if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ - "$HAVE_READLINE_READLINE_H" != "1"; then - echo "** Cannot --enable-pcre2test-libedit because neither editline/readline.h" - echo "** nor readline/readline.h was found." - exit 1 - fi - if test -z "$LIBEDIT"; then - echo "** Cannot --enable-pcre2test-libedit because libedit library was not found." - exit 1 - fi -fi - -if test "$enable_pcre2test_libreadline" = "yes"; then - if test "$HAVE_READLINE_H" != "1"; then - echo "** Cannot --enable-pcre2test-readline because readline/readline.h was not found." - exit 1 - fi - if test "$HAVE_HISTORY_H" != "1"; then - echo "** Cannot --enable-pcre2test-readline because readline/history.h was not found." - exit 1 - fi - if test -z "$LIBREADLINE"; then - echo "** Cannot --enable-pcre2test-readline because readline library was not found." - exit 1 - fi -fi - -# Handle valgrind support - -if test "$enable_valgrind" = "yes"; then - m4_ifdef([PKG_CHECK_MODULES], - [PKG_CHECK_MODULES([VALGRIND],[valgrind])], - [AC_MSG_ERROR([pkg-config not supported])]) -fi - -# Handle code coverage reporting support -if test "$enable_coverage" = "yes"; then - if test "x$GCC" != "xyes"; then - AC_MSG_ERROR([Code coverage reports can only be generated when using GCC]) - fi - - # ccache is incompatible with gcov - AC_PATH_PROG([SHTOOL],[shtool],[false]) - case `$SHTOOL path $CC` in - *ccache*) cc_ccache=yes;; - *) cc_ccache=no;; - esac - - if test "$cc_ccache" = "yes"; then - if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then - AC_MSG_ERROR([must export CCACHE_DISABLE=1 to disable ccache for code coverage]) - fi - fi - - AC_ARG_VAR([LCOV],[the ltp lcov program]) - AC_PATH_PROG([LCOV],[lcov],[false]) - if test "x$LCOV" = "xfalse"; then - AC_MSG_ERROR([lcov not found]) - fi - - AC_ARG_VAR([GENHTML],[the ltp genhtml program]) - AC_PATH_PROG([GENHTML],[genhtml],[false]) - if test "x$GENHTML" = "xfalse"; then - AC_MSG_ERROR([genhtml not found]) - fi - - # Set flags needed for gcov - GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" - GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" - GCOV_LIBS="-lgcov" - AC_SUBST([GCOV_CFLAGS]) - AC_SUBST([GCOV_CXXFLAGS]) - AC_SUBST([GCOV_LIBS]) -fi # enable_coverage - -AM_CONDITIONAL([WITH_GCOV],[test "x$enable_coverage" = "xyes"]) - -# Produce these files, in addition to config.h. -AC_CONFIG_FILES( - Makefile - libpcre2-8.pc - libpcre2-16.pc - libpcre2-32.pc - libpcre2-posix.pc - pcre2-config - src/pcre2.h -) - -# Make the generated script files executable. -AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre2-config]) - -# Make sure that pcre2_chartables.c is removed in case the method for -# creating it was changed by reconfiguration. -AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre2_chartables.c]) - -AC_OUTPUT - -# Print out a nice little message after configure is run displaying the -# chosen options. - -ebcdic_nl_code=n/a -if test "$enable_ebcdic_nl25" = "yes"; then - ebcdic_nl_code=0x25 -elif test "$enable_ebcdic" = "yes"; then - ebcdic_nl_code=0x15 -fi - -cat <. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by 'PROGRAMS ARGS'. - object Object file output by 'PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -# Get the directory component of the given path, and save it in the -# global variables '$dir'. Note that this directory component will -# be either empty or ending with a '/' character. This is deliberate. -set_dir_from () -{ - case $1 in - */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; - *) dir=;; - esac -} - -# Get the suffix-stripped basename of the given path, and save it the -# global variable '$base'. -set_base_from () -{ - base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` -} - -# If no dependency file was actually created by the compiler invocation, -# we still have to create a dummy depfile, to avoid errors with the -# Makefile "include basename.Plo" scheme. -make_dummy_depfile () -{ - echo "#dummy" > "$depfile" -} - -# Factor out some common post-processing of the generated depfile. -# Requires the auxiliary global variable '$tmpdepfile' to be set. -aix_post_process_depfile () -{ - # If the compiler actually managed to produce a dependency file, - # post-process it. - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependency.h'. - # Do two passes, one to just change these to - # $object: dependency.h - # and one to simply output - # dependency.h: - # which is needed to avoid the deleted-header problem. - { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" - sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" - } > "$depfile" - rm -f "$tmpdepfile" - else - make_dummy_depfile - fi -} - -# A tabulation character. -tab=' ' -# A newline character. -nl=' -' -# Character ranges might be problematic outside the C locale. -# These definitions help. -upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ -lower=abcdefghijklmnopqrstuvwxyz -digits=0123456789 -alpha=${upper}${lower} - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Avoid interferences from the environment. -gccflag= dashmflag= - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. - gccflag=-qmakedep=gcc,-MF - depmode=gcc -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. -## (see the conditional assignment to $gccflag above). -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). Also, it might not be -## supported by the other compilers which use the 'gcc' depmode. -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The second -e expression handles DOS-style file names with drive - # letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the "deleted header file" problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. -## Some versions of gcc put a space before the ':'. On the theory -## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like '#:fec' to the end of the - # dependency line. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ - | tr "$nl" ' ' >> "$depfile" - echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" - ;; - -xlc) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts '$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - aix_post_process_depfile - ;; - -tcc) - # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 - # FIXME: That version still under development at the moment of writing. - # Make that this statement remains true also for stable, released - # versions. - # It will wrap lines (doesn't matter whether long or short) with a - # trailing '\', as in: - # - # foo.o : \ - # foo.c \ - # foo.h \ - # - # It will put a trailing '\' even on the last line, and will use leading - # spaces rather than leading tabs (at least since its commit 0394caf7 - # "Emit spaces for -MD"). - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. - # We have to change lines of the first kind to '$object: \'. - sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" - # And for each line of the second kind, we have to emit a 'dep.h:' - # dummy dependency, to avoid the deleted-header problem. - sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" - rm -f "$tmpdepfile" - ;; - -## The order of this option in the case statement is important, since the -## shell code in configure will try each of these formats in the order -## listed in this file. A plain '-MD' option would be understood by many -## compilers, so we must ensure this comes after the gcc and icc options. -pgcc) - # Portland's C compiler understands '-MD'. - # Will always output deps to 'file.d' where file is the root name of the - # source file under compilation, even if file resides in a subdirectory. - # The object file name does not affect the name of the '.d' file. - # pgcc 10.2 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\' : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - set_dir_from "$object" - # Use the source, not the object, to determine the base name, since - # that's sadly what pgcc will do too. - set_base_from "$source" - tmpdepfile=$base.d - - # For projects that build the same source file twice into different object - # files, the pgcc approach of using the *source* file root name can cause - # problems in parallel builds. Use a locking strategy to avoid stomping on - # the same $tmpdepfile. - lockdir=$base.d-lock - trap " - echo '$0: caught signal, cleaning up...' >&2 - rmdir '$lockdir' - exit 1 - " 1 2 13 15 - numtries=100 - i=$numtries - while test $i -gt 0; do - # mkdir is a portable test-and-set. - if mkdir "$lockdir" 2>/dev/null; then - # This process acquired the lock. - "$@" -MD - stat=$? - # Release the lock. - rmdir "$lockdir" - break - else - # If the lock is being held by a different process, wait - # until the winning process is done or we timeout. - while test -d "$lockdir" && test $i -gt 0; do - sleep 1 - i=`expr $i - 1` - done - fi - i=`expr $i - 1` - done - trap - 1 2 13 15 - if test $i -le 0; then - echo "$0: failed to acquire lock after $numtries attempts" >&2 - echo "$0: check lockdir '$lockdir'" >&2 - exit 1 - fi - - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" - # Add 'dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - set_dir_from "$object" - set_base_from "$object" - - if test "$libtool" = yes; then - # Libtool generates 2 separate objects for the 2 libraries. These - # two compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir$base.o.d # libtool 1.5 - tmpdepfile2=$dir.libs/$base.o.d # Likewise. - tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - # Same post-processing that is required for AIX mode. - aix_post_process_depfile - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/'"$tab"'\1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/'"$tab"'/ - G - p -}' >> "$depfile" - echo >> "$depfile" # make sure the fragment doesn't end with a backslash - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for ':' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. - "$@" $dashmflag | - sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this sed invocation - # correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process the last invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed '1,2d' "$tmpdepfile" \ - | tr ' ' "$nl" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E \ - | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - | sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" - echo "$tab" >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/pcre2/install-sh b/pcre2/install-sh deleted file mode 100755 index 0b0fdcbba..000000000 --- a/pcre2/install-sh +++ /dev/null @@ -1,501 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2013-12-25.23; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -tab=' ' -nl=' -' -IFS=" $tab$nl" - -# Set DOITPROG to "echo" to test this script. - -doit=${DOITPROG-} -doit_exec=${doit:-exec} - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -is_target_a_directory=possibly - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) - is_target_a_directory=always - dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) is_target_a_directory=never;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -# We allow the use of options -d and -T together, by making -d -# take the precedence; this is for compatibility with GNU install. - -if test -n "$dir_arg"; then - if test -n "$dst_arg"; then - echo "$0: target directory not allowed when installing a directory." >&2 - exit 1 - fi -fi - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - if test $# -gt 1 || test "$is_target_a_directory" = always; then - if test ! -d "$dst_arg"; then - echo "$0: $dst_arg: Is not a directory." >&2 - exit 1 - fi - fi -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test "$is_target_a_directory" = never; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - dstdir=`dirname "$dst"` - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - oIFS=$IFS - IFS=/ - set -f - set fnord $dstdir - shift - set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - set +f && - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/pcre2/libpcre2-16.pc.in b/pcre2/libpcre2-16.pc.in deleted file mode 100644 index 978040dfe..000000000 --- a/pcre2/libpcre2-16.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -# Package Information for pkg-config - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libpcre2-16 -Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 16 bit character support -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lpcre2-16 -Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ -Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-32.pc.in b/pcre2/libpcre2-32.pc.in deleted file mode 100644 index d8fb18713..000000000 --- a/pcre2/libpcre2-32.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -# Package Information for pkg-config - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libpcre2-32 -Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 32 bit character support -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lpcre2-32 -Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ -Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-8.pc.in b/pcre2/libpcre2-8.pc.in deleted file mode 100644 index 5c872d0b3..000000000 --- a/pcre2/libpcre2-8.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -# Package Information for pkg-config - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libpcre2-8 -Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 8 bit character support -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lpcre2-8 -Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ -Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ diff --git a/pcre2/libpcre2-posix.pc.in b/pcre2/libpcre2-posix.pc.in deleted file mode 100644 index 96415558e..000000000 --- a/pcre2/libpcre2-posix.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -# Package Information for pkg-config - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libpcre2-posix -Description: Posix compatible interface to libpcre2-8 -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lpcre2-posix -Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@ -Requires.private: libpcre2-8 diff --git a/pcre2/ltmain.sh b/pcre2/ltmain.sh deleted file mode 100644 index 0f0a2da3f..000000000 --- a/pcre2/ltmain.sh +++ /dev/null @@ -1,11147 +0,0 @@ -#! /bin/sh -## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 - -# libtool (GNU libtool) 2.4.6 -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -PROGRAM=libtool -PACKAGE=libtool -VERSION=2.4.6 -package_revision=2.4.6 - - -## ------ ## -## Usage. ## -## ------ ## - -# Run './libtool --help' for help with using this script from the -# command line. - - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# After configure completes, it has a better idea of some of the -# shell tools we need than the defaults used by the functions shared -# with bootstrap, so set those here where they can still be over- -# ridden by the user, but otherwise take precedence. - -: ${AUTOCONF="autoconf"} -: ${AUTOMAKE="automake"} - - -## -------------------------- ## -## Source external libraries. ## -## -------------------------- ## - -# Much of our low-level functionality needs to be sourced from external -# libraries, which are installed to $pkgauxdir. - -# Set a version string for this script. -scriptversion=2015-01-20.17; # UTC - -# General shell script boiler plate, and helper functions. -# Written by Gary V. Vaughan, 2004 - -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# Evaluate this file near the top of your script to gain access to -# the functions and variables defined here: -# -# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh -# -# If you need to override any of the default environment variable -# settings, do that before evaluating this file. - - -## -------------------- ## -## Shell normalisation. ## -## -------------------- ## - -# Some shells need a little help to be as Bourne compatible as possible. -# Before doing anything else, make sure all that help has been provided! - -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac -fi - -# NLS nuisances: We save the old values in case they are required later. -_G_user_locale= -_G_safe_locale= -for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test set = \"\${$_G_var+set}\"; then - save_$_G_var=\$$_G_var - $_G_var=C - export $_G_var - _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" - _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" - fi" -done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Make sure IFS has a sensible default -sp=' ' -nl=' -' -IFS="$sp $nl" - -# There are apparently some retarded systems that use ';' as a PATH separator! -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - - -## ------------------------- ## -## Locate command utilities. ## -## ------------------------- ## - - -# func_executable_p FILE -# ---------------------- -# Check that FILE is an executable regular file. -func_executable_p () -{ - test -f "$1" && test -x "$1" -} - - -# func_path_progs PROGS_LIST CHECK_FUNC [PATH] -# -------------------------------------------- -# Search for either a program that responds to --version with output -# containing "GNU", or else returned by CHECK_FUNC otherwise, by -# trying all the directories in PATH with each of the elements of -# PROGS_LIST. -# -# CHECK_FUNC should accept the path to a candidate program, and -# set $func_check_prog_result if it truncates its output less than -# $_G_path_prog_max characters. -func_path_progs () -{ - _G_progs_list=$1 - _G_check_func=$2 - _G_PATH=${3-"$PATH"} - - _G_path_prog_max=0 - _G_path_prog_found=false - _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} - for _G_dir in $_G_PATH; do - IFS=$_G_save_IFS - test -z "$_G_dir" && _G_dir=. - for _G_prog_name in $_G_progs_list; do - for _exeext in '' .EXE; do - _G_path_prog=$_G_dir/$_G_prog_name$_exeext - func_executable_p "$_G_path_prog" || continue - case `"$_G_path_prog" --version 2>&1` in - *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; - *) $_G_check_func $_G_path_prog - func_path_progs_result=$func_check_prog_result - ;; - esac - $_G_path_prog_found && break 3 - done - done - done - IFS=$_G_save_IFS - test -z "$func_path_progs_result" && { - echo "no acceptable sed could be found in \$PATH" >&2 - exit 1 - } -} - - -# We want to be able to use the functions in this file before configure -# has figured out where the best binaries are kept, which means we have -# to search for them ourselves - except when the results are already set -# where we skip the searches. - -# Unless the user overrides by setting SED, search the path for either GNU -# sed, or the sed that truncates its output the least. -test -z "$SED" && { - _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for _G_i in 1 2 3 4 5 6 7; do - _G_sed_script=$_G_sed_script$nl$_G_sed_script - done - echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed - _G_sed_script= - - func_check_prog_sed () - { - _G_path_prog=$1 - - _G_count=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo '' >> conftest.nl - "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin - rm -f conftest.sed - SED=$func_path_progs_result -} - - -# Unless the user overrides by setting GREP, search the path for either GNU -# grep, or the grep that truncates its output the least. -test -z "$GREP" && { - func_check_prog_grep () - { - _G_path_prog=$1 - - _G_count=0 - _G_path_prog_max=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo 'GREP' >> conftest.nl - "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin - GREP=$func_path_progs_result -} - - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# All uppercase variable names are used for environment variables. These -# variables can be overridden by the user before calling a script that -# uses them if a suitable command of that name is not already available -# in the command search PATH. - -: ${CP="cp -f"} -: ${ECHO="printf %s\n"} -: ${EGREP="$GREP -E"} -: ${FGREP="$GREP -F"} -: ${LN_S="ln -s"} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} - - -## -------------------- ## -## Useful sed snippets. ## -## -------------------- ## - -sed_dirname='s|/[^/]*$||' -sed_basename='s|^.*/||' - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s|\([`"$\\]\)|\\\1|g' - -# Same as above, but do not quote variable references. -sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' - -# Sed substitution that converts a w32 file name or path -# that contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-'\' parameter expansions in output of sed_double_quote_subst that -# were '\'-ed in input to the same. If an odd number of '\' preceded a -# '$' in input to sed_double_quote_subst, that '$' was protected from -# expansion. Since each input '\' is now two '\'s, look for any number -# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. -_G_bs='\\' -_G_bs2='\\\\' -_G_bs4='\\\\\\\\' -_G_dollar='\$' -sed_double_backslash="\ - s/$_G_bs4/&\\ -/g - s/^$_G_bs2$_G_dollar/$_G_bs&/ - s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g - s/\n//g" - - -## ----------------- ## -## Global variables. ## -## ----------------- ## - -# Except for the global variables explicitly listed below, the following -# functions in the '^func_' namespace, and the '^require_' namespace -# variables initialised in the 'Resource management' section, sourcing -# this file will not pollute your global namespace with anything -# else. There's no portable way to scope variables in Bourne shell -# though, so actually running these functions will sometimes place -# results into a variable named after the function, and often use -# temporary variables in the '^_G_' namespace. If you are careful to -# avoid using those namespaces casually in your sourcing script, things -# should continue to work as you expect. And, of course, you can freely -# overwrite any of the functions or variables defined here before -# calling anything to customize them. - -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -# Allow overriding, eg assuming that you follow the convention of -# putting '$debug_cmd' at the start of all your functions, you can get -# bash to show function call trace with: -# -# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name -debug_cmd=${debug_cmd-":"} -exit_cmd=: - -# By convention, finish your script with: -# -# exit $exit_status -# -# so that you can set exit_status to non-zero if you want to indicate -# something went wrong during execution without actually bailing out at -# the point of failure. -exit_status=$EXIT_SUCCESS - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath=$0 - -# The name of this program. -progname=`$ECHO "$progpath" |$SED "$sed_basename"` - -# Make sure we have an absolute progpath for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` - progdir=`cd "$progdir" && pwd` - progpath=$progdir/$progname - ;; - *) - _G_IFS=$IFS - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS=$_G_IFS - test -x "$progdir/$progname" && break - done - IFS=$_G_IFS - test -n "$progdir" || progdir=`pwd` - progpath=$progdir/$progname - ;; -esac - - -## ----------------- ## -## Standard options. ## -## ----------------- ## - -# The following options affect the operation of the functions defined -# below, and should be set appropriately depending on run-time para- -# meters passed on the command line. - -opt_dry_run=false -opt_quiet=false -opt_verbose=false - -# Categories 'all' and 'none' are always available. Append any others -# you will pass as the first argument to func_warning from your own -# code. -warning_categories= - -# By default, display warnings according to 'opt_warning_types'. Set -# 'warning_func' to ':' to elide all warnings, or func_fatal_error to -# treat the next displayed warning as a fatal error. -warning_func=func_warn_and_continue - -# Set to 'all' to display all warnings, 'none' to suppress all -# warnings, or a space delimited list of some subset of -# 'warning_categories' to display only the listed warnings. -opt_warning_types=all - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# This section contains definitions for functions that each ensure a -# particular resource (a file, or a non-empty configuration variable for -# example) is available, and if appropriate to extract default values -# from pertinent package files. Call them using their associated -# 'require_*' variable to ensure that they are executed, at most, once. -# -# It's entirely deliberate that calling these functions can set -# variables that don't obey the namespace limitations obeyed by the rest -# of this file, in order that that they be as useful as possible to -# callers. - - -# require_term_colors -# ------------------- -# Allow display of bold text on terminals that support it. -require_term_colors=func_require_term_colors -func_require_term_colors () -{ - $debug_cmd - - test -t 1 && { - # COLORTERM and USE_ANSI_COLORS environment variables take - # precedence, because most terminfo databases neglect to describe - # whether color sequences are supported. - test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} - - if test 1 = "$USE_ANSI_COLORS"; then - # Standard ANSI escape sequences - tc_reset='' - tc_bold=''; tc_standout='' - tc_red=''; tc_green='' - tc_blue=''; tc_cyan='' - else - # Otherwise trust the terminfo database after all. - test -n "`tput sgr0 2>/dev/null`" && { - tc_reset=`tput sgr0` - test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` - tc_standout=$tc_bold - test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` - test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` - test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` - test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` - test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` - } - fi - } - - require_term_colors=: -} - - -## ----------------- ## -## Function library. ## -## ----------------- ## - -# This section contains a variety of useful functions to call in your -# scripts. Take note of the portable wrappers for features provided by -# some modern shells, which will fall back to slower equivalents on -# less featureful shells. - - -# func_append VAR VALUE -# --------------------- -# Append VALUE onto the existing contents of VAR. - - # We should try to minimise forks, especially on Windows where they are - # unreasonably slow, so skip the feature probes when bash or zsh are - # being used: - if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then - : ${_G_HAVE_ARITH_OP="yes"} - : ${_G_HAVE_XSI_OPS="yes"} - # The += operator was introduced in bash 3.1 - case $BASH_VERSION in - [12].* | 3.0 | 3.0*) ;; - *) - : ${_G_HAVE_PLUSEQ_OP="yes"} - ;; - esac - fi - - # _G_HAVE_PLUSEQ_OP - # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. - test -z "$_G_HAVE_PLUSEQ_OP" \ - && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ - && _G_HAVE_PLUSEQ_OP=yes - -if test yes = "$_G_HAVE_PLUSEQ_OP" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_append () - { - $debug_cmd - - eval "$1+=\$2" - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_append () - { - $debug_cmd - - eval "$1=\$$1\$2" - } -fi - - -# func_append_quoted VAR VALUE -# ---------------------------- -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -if test yes = "$_G_HAVE_PLUSEQ_OP"; then - eval 'func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" - }' -else - func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" - } -fi - - -# func_append_uniq VAR VALUE -# -------------------------- -# Append unique VALUE onto the existing contents of VAR, assuming -# entries are delimited by the first character of VALUE. For example: -# -# func_append_uniq options " --another-option option-argument" -# -# will only append to $options if " --another-option option-argument " -# is not already present somewhere in $options already (note spaces at -# each end implied by leading space in second argument). -func_append_uniq () -{ - $debug_cmd - - eval _G_current_value='`$ECHO $'$1'`' - _G_delim=`expr "$2" : '\(.\)'` - - case $_G_delim$_G_current_value$_G_delim in - *"$2$_G_delim"*) ;; - *) func_append "$@" ;; - esac -} - - -# func_arith TERM... -# ------------------ -# Set func_arith_result to the result of evaluating TERMs. - test -z "$_G_HAVE_ARITH_OP" \ - && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ - && _G_HAVE_ARITH_OP=yes - -if test yes = "$_G_HAVE_ARITH_OP"; then - eval 'func_arith () - { - $debug_cmd - - func_arith_result=$(( $* )) - }' -else - func_arith () - { - $debug_cmd - - func_arith_result=`expr "$@"` - } -fi - - -# func_basename FILE -# ------------------ -# Set func_basename_result to FILE with everything up to and including -# the last / stripped. -if test yes = "$_G_HAVE_XSI_OPS"; then - # If this shell supports suffix pattern removal, then use it to avoid - # forking. Hide the definitions single quotes in case the shell chokes - # on unsupported syntax... - _b='func_basename_result=${1##*/}' - _d='case $1 in - */*) func_dirname_result=${1%/*}$2 ;; - * ) func_dirname_result=$3 ;; - esac' - -else - # ...otherwise fall back to using sed. - _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' - _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` - if test "X$func_dirname_result" = "X$1"; then - func_dirname_result=$3 - else - func_append func_dirname_result "$2" - fi' -fi - -eval 'func_basename () -{ - $debug_cmd - - '"$_b"' -}' - - -# func_dirname FILE APPEND NONDIR_REPLACEMENT -# ------------------------------------------- -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -eval 'func_dirname () -{ - $debug_cmd - - '"$_d"' -}' - - -# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT -# -------------------------------------------------------- -# Perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# For efficiency, we do not delegate to the functions above but instead -# duplicate the functionality here. -eval 'func_dirname_and_basename () -{ - $debug_cmd - - '"$_b"' - '"$_d"' -}' - - -# func_echo ARG... -# ---------------- -# Echo program name prefixed message. -func_echo () -{ - $debug_cmd - - _G_message=$* - - func_echo_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_IFS - $ECHO "$progname: $_G_line" - done - IFS=$func_echo_IFS -} - - -# func_echo_all ARG... -# -------------------- -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - - -# func_echo_infix_1 INFIX ARG... -# ------------------------------ -# Echo program name, followed by INFIX on the first line, with any -# additional lines not showing INFIX. -func_echo_infix_1 () -{ - $debug_cmd - - $require_term_colors - - _G_infix=$1; shift - _G_indent=$_G_infix - _G_prefix="$progname: $_G_infix: " - _G_message=$* - - # Strip color escape sequences before counting printable length - for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" - do - test -n "$_G_tc" && { - _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` - _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` - } - done - _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes - - func_echo_infix_1_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_infix_1_IFS - $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 - _G_prefix=$_G_indent - done - IFS=$func_echo_infix_1_IFS -} - - -# func_error ARG... -# ----------------- -# Echo program name prefixed message to standard error. -func_error () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 -} - - -# func_fatal_error ARG... -# ----------------------- -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - $debug_cmd - - func_error "$*" - exit $EXIT_FAILURE -} - - -# func_grep EXPRESSION FILENAME -# ----------------------------- -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $debug_cmd - - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_len STRING -# --------------- -# Set func_len_result to the length of STRING. STRING may not -# start with a hyphen. - test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_len () - { - $debug_cmd - - func_len_result=${#1} - }' -else - func_len () - { - $debug_cmd - - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` - } -fi - - -# func_mkdir_p DIRECTORY-PATH -# --------------------------- -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - $debug_cmd - - _G_directory_path=$1 - _G_dir_list= - - if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then - - # Protect directory names starting with '-' - case $_G_directory_path in - -*) _G_directory_path=./$_G_directory_path ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$_G_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - _G_dir_list=$_G_directory_path:$_G_dir_list - - # If the last portion added has no slash in it, the list is done - case $_G_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` - done - _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` - - func_mkdir_p_IFS=$IFS; IFS=: - for _G_dir in $_G_dir_list; do - IFS=$func_mkdir_p_IFS - # mkdir can fail with a 'File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$_G_dir" 2>/dev/null || : - done - IFS=$func_mkdir_p_IFS - - # Bail out if we (or some other process) failed to create a directory. - test -d "$_G_directory_path" || \ - func_fatal_error "Failed to create '$1'" - fi -} - - -# func_mktempdir [BASENAME] -# ------------------------- -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, BASENAME is the basename for that directory. -func_mktempdir () -{ - $debug_cmd - - _G_template=${TMPDIR-/tmp}/${1-$progname} - - if test : = "$opt_dry_run"; then - # Return a directory name, but don't create it in dry-run mode - _G_tmpdir=$_G_template-$$ - else - - # If mktemp works, use that first and foremost - _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` - - if test ! -d "$_G_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - _G_tmpdir=$_G_template-${RANDOM-0}$$ - - func_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$_G_tmpdir" - umask $func_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$_G_tmpdir" || \ - func_fatal_error "cannot create temporary directory '$_G_tmpdir'" - fi - - $ECHO "$_G_tmpdir" -} - - -# func_normal_abspath PATH -# ------------------------ -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -func_normal_abspath () -{ - $debug_cmd - - # These SED scripts presuppose an absolute path with a trailing slash. - _G_pathcar='s|^/\([^/]*\).*$|\1|' - _G_pathcdr='s|^/[^/]*||' - _G_removedotparts=':dotsl - s|/\./|/|g - t dotsl - s|/\.$|/|' - _G_collapseslashes='s|/\{1,\}|/|g' - _G_finalslash='s|/*$|/|' - - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` - while :; do - # Processed it all yet? - if test / = "$func_normal_abspath_tpath"; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result"; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - - -# func_notquiet ARG... -# -------------------- -# Echo program name prefixed message only when not in quiet mode. -func_notquiet () -{ - $debug_cmd - - $opt_quiet || func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - - -# func_relative_path SRCDIR DSTDIR -# -------------------------------- -# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. -func_relative_path () -{ - $debug_cmd - - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=$func_dirname_result - if test -z "$func_relative_path_tlibdir"; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test -n "$func_stripname_result"; then - func_append func_relative_path_result "/$func_stripname_result" - fi - - # Normalisation. If bindir is libdir, return '.' else relative path. - if test -n "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - fi - - test -n "$func_relative_path_result" || func_relative_path_result=. - - : -} - - -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () -{ - $debug_cmd - - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" - fi - - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" - ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; - esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift - done -} - - -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd - - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; - esac - - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" - ;; - esac - - func_quote_for_expand_result=$_G_arg -} - - -# func_stripname PREFIX SUFFIX NAME -# --------------------------------- -# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_stripname () - { - $debug_cmd - - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary variable first. - func_stripname_result=$3 - func_stripname_result=${func_stripname_result#"$1"} - func_stripname_result=${func_stripname_result%"$2"} - }' -else - func_stripname () - { - $debug_cmd - - case $2 in - .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; - *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; - esac - } -fi - - -# func_show_eval CMD [FAIL_EXP] -# ----------------------------- -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" - - $opt_dry_run || { - eval "$_G_cmd" - _G_status=$? - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_show_eval_locale CMD [FAIL_EXP] -# ------------------------------------ -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - $opt_dry_run || { - eval "$_G_user_locale - $_G_cmd" - _G_status=$? - eval "$_G_safe_locale" - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_tr_sh -# ---------- -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - $debug_cmd - - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_verbose ARG... -# ------------------- -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $debug_cmd - - $opt_verbose && func_echo "$*" - - : -} - - -# func_warn_and_continue ARG... -# ----------------------------- -# Echo program name prefixed warning message to standard error. -func_warn_and_continue () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 -} - - -# func_warning CATEGORY ARG... -# ---------------------------- -# Echo program name prefixed warning message to standard error. Warning -# messages can be filtered according to CATEGORY, where this function -# elides messages where CATEGORY is not listed in the global variable -# 'opt_warning_types'. -func_warning () -{ - $debug_cmd - - # CATEGORY must be in the warning_categories list! - case " $warning_categories " in - *" $1 "*) ;; - *) func_internal_error "invalid warning category '$1'" ;; - esac - - _G_category=$1 - shift - - case " $opt_warning_types " in - *" $_G_category "*) $warning_func ${1+"$@"} ;; - esac -} - - -# func_sort_ver VER1 VER2 -# ----------------------- -# 'sort -V' is not generally available. -# Note this deviates from the version comparison in automake -# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a -# but this should suffice as we won't be specifying old -# version formats or redundant trailing .0 in bootstrap.conf. -# If we did want full compatibility then we should probably -# use m4_version_compare from autoconf. -func_sort_ver () -{ - $debug_cmd - - printf '%s\n%s\n' "$1" "$2" \ - | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n -} - -# func_lt_ver PREV CURR -# --------------------- -# Return true if PREV and CURR are in the correct order according to -# func_sort_ver, otherwise false. Use it like this: -# -# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." -func_lt_ver () -{ - $debug_cmd - - test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: -#! /bin/sh - -# Set a version string for this script. -scriptversion=2014-01-07.03; # UTC - -# A portable, pluggable option parser for Bourne shell. -# Written by Gary V. Vaughan, 2010 - -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# This file is a library for parsing options in your shell scripts along -# with assorted other useful supporting features that you can make use -# of too. -# -# For the simplest scripts you might need only: -# -# #!/bin/sh -# . relative/path/to/funclib.sh -# . relative/path/to/options-parser -# scriptversion=1.0 -# func_options ${1+"$@"} -# eval set dummy "$func_options_result"; shift -# ...rest of your script... -# -# In order for the '--version' option to work, you will need to have a -# suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. -# -# For '-h' and '--help' to work, you will also need a one line -# description of your script's purpose in a comment directly above the -# '# Written by ' line, like the one at the top of this file. -# -# The default options also support '--debug', which will turn on shell -# execution tracing (see the comment above debug_cmd below for another -# use), and '--verbose' and the func_verbose function to allow your script -# to display verbose messages only when your user has specified -# '--verbose'. -# -# After sourcing this file, you can plug processing for additional -# options by amending the variables from the 'Configuration' section -# below, and following the instructions in the 'Option parsing' -# section further down. - -## -------------- ## -## Configuration. ## -## -------------- ## - -# You should override these variables in your script after sourcing this -# file so that they reflect the customisations you have added to the -# option parser. - -# The usage line for option parsing errors and the start of '-h' and -# '--help' output messages. You can embed shell variables for delayed -# expansion at the time the message is displayed, but you will need to -# quote other shell meta-characters carefully to prevent them being -# expanded when the contents are evaled. -usage='$progpath [OPTION]...' - -# Short help message in response to '-h' and '--help'. Add to this or -# override it after sourcing this library to reflect the full set of -# options your script accepts. -usage_message="\ - --debug enable verbose shell tracing - -W, --warnings=CATEGORY - report the warnings falling in CATEGORY [all] - -v, --verbose verbosely report processing - --version print version information and exit - -h, --help print short or long help message and exit -" - -# Additional text appended to 'usage_message' in response to '--help'. -long_help_message=" -Warning categories include: - 'all' show all warnings - 'none' turn off all the warnings - 'error' warnings are treated as fatal errors" - -# Help message printed before fatal option parsing errors. -fatal_help="Try '\$progname --help' for more information." - - - -## ------------------------- ## -## Hook function management. ## -## ------------------------- ## - -# This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. - -# func_hookable FUNC_NAME -# ----------------------- -# Declare that FUNC_NAME will run hooks added with -# 'func_add_hook FUNC_NAME ...'. -func_hookable () -{ - $debug_cmd - - func_append hookable_fns " $1" -} - - -# func_add_hook FUNC_NAME HOOK_FUNC -# --------------------------------- -# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must -# first have been declared "hookable" by a call to 'func_hookable'. -func_add_hook () -{ - $debug_cmd - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not accept hook functions." ;; - esac - - eval func_append ${1}_hooks '" $2"' -} - - -# func_remove_hook FUNC_NAME HOOK_FUNC -# ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. -func_remove_hook () -{ - $debug_cmd - - eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' -} - - -# func_run_hooks FUNC_NAME [ARG]... -# --------------------------------- -# Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more -# than a whitespace-delimited list of legal shell function names, and -# no effort is wasted trying to catch shell meta-characters or preserve -# whitespace. -func_run_hooks () -{ - $debug_cmd - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; - esac - - eval _G_hook_fns=\$$1_hooks; shift - - for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift - done - - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result -} - - - -## --------------- ## -## Option parsing. ## -## --------------- ## - -# In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. Like this: -# -# my_options_prep () -# { -# $debug_cmd -# -# # Extend the existing usage message. -# usage_message=$usage_message' -# -s, --silent don'\''t print informational messages -# ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result -# } -# func_add_hook func_options_prep my_options_prep -# -# -# my_silent_option () -# { -# $debug_cmd -# -# # Note that for efficiency, we parse as many options as we can -# # recognise in a loop before passing the remainder back to the -# # caller on the first unrecognised argument we encounter. -# while test $# -gt 0; do -# opt=$1; shift -# case $opt in -# --silent|-s) opt_silent=: ;; -# # Separate non-argument short options: -# -s*) func_split_short_opt "$_G_opt" -# set dummy "$func_split_short_opt_name" \ -# "-$func_split_short_opt_arg" ${1+"$@"} -# shift -# ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; -# esac -# done -# -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result -# } -# func_add_hook func_parse_options my_silent_option -# -# -# my_option_validation () -# { -# $debug_cmd -# -# $opt_silent && $opt_verbose && func_fatal_help "\ -# '--silent' and '--verbose' options are mutually exclusive." -# -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result -# } -# func_add_hook func_validate_options my_option_validation -# -# You'll alse need to manually amend $usage_message to reflect the extra -# options you parse. It's preferable to append if you can, so that -# multiple option parsing hooks can be added safely. - - -# func_options [ARG]... -# --------------------- -# All the functions called inside func_options are hookable. See the -# individual implementations for details. -func_hookable func_options -func_options () -{ - $debug_cmd - - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} - - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} - - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result -} - - -# func_options_prep [ARG]... -# -------------------------- -# All initialisations required before starting the option parse loop. -# Note that when calling hook functions, we pass through the list of -# positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning. -func_hookable func_options_prep -func_options_prep () -{ - $debug_cmd - - # Option defaults: - opt_verbose=false - opt_warning_types= - - func_run_hooks func_options_prep ${1+"$@"} - - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result -} - - -# func_parse_options [ARG]... -# --------------------------- -# The main option parsing loop. -func_hookable func_parse_options -func_parse_options () -{ - $debug_cmd - - func_parse_options_result= - - # this just eases exit handling - while test $# -gt 0; do - # Defer to hook functions for initial option parsing, so they - # get priority in the event of reusing an option name. - func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift - - # Break out of the loop if we already parsed every option. - test $# -gt 0 || break - - _G_opt=$1 - shift - case $_G_opt in - --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" - $debug_cmd - ;; - - --no-warnings|--no-warning|--no-warn) - set dummy --warnings none ${1+"$@"} - shift - ;; - - --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break - case " $warning_categories $1" in - *" $1 "*) - # trailing space prevents matching last $1 above - func_append_uniq opt_warning_types " $1" - ;; - *all) - opt_warning_types=$warning_categories - ;; - *none) - opt_warning_types=none - warning_func=: - ;; - *error) - opt_warning_types=$warning_categories - warning_func=func_fatal_error - ;; - *) - func_fatal_error \ - "unsupported warning category: '$1'" - ;; - esac - shift - ;; - - --verbose|-v) opt_verbose=: ;; - --version) func_version ;; - -\?|-h) func_usage ;; - --help) func_help ;; - - # Separate optargs to long options (plugins may need this): - --*=*) func_split_equals "$_G_opt" - set dummy "$func_split_equals_lhs" \ - "$func_split_equals_rhs" ${1+"$@"} - shift - ;; - - # Separate optargs to short options: - -W*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-v*|-x*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; - esac - done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result -} - - -# func_validate_options [ARG]... -# ------------------------------ -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -func_hookable func_validate_options -func_validate_options () -{ - $debug_cmd - - # Display all warnings if -W was not given. - test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - - func_run_hooks func_validate_options ${1+"$@"} - - # Bail if the options were screwed! - $exit_cmd $EXIT_FAILURE - - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result -} - - - -## ----------------- ## -## Helper functions. ## -## ----------------- ## - -# This section contains the helper functions used by the rest of the -# hookable option parser framework in ascii-betical order. - - -# func_fatal_help ARG... -# ---------------------- -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - eval \$ECHO \""$fatal_help"\" - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - - -# func_help -# --------- -# Echo long help message to standard output and exit. -func_help () -{ - $debug_cmd - - func_usage_message - $ECHO "$long_help_message" - exit 0 -} - - -# func_missing_arg ARGNAME -# ------------------------ -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $debug_cmd - - func_error "Missing argument for '$1'." - exit_cmd=exit -} - - -# func_split_equals STRING -# ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. -test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=${1%%=*} - func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` - func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ - || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` - } -fi #func_split_equals - - -# func_split_short_opt SHORTOPT -# ----------------------------- -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"} - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` - func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` - } -fi #func_split_short_opt - - -# func_usage -# ---------- -# Echo short help message to standard output and exit. -func_usage () -{ - $debug_cmd - - func_usage_message - $ECHO "Run '$progname --help |${PAGER-more}' for full usage" - exit 0 -} - - -# func_usage_message -# ------------------ -# Echo short help message to standard output. -func_usage_message () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - echo - $SED -n 's|^# || - /^Written by/{ - x;p;x - } - h - /^Written by/q' < "$progpath" - echo - eval \$ECHO \""$usage_message"\" -} - - -# func_version -# ------------ -# Echo version message to standard output and exit. -func_version () -{ - $debug_cmd - - printf '%s\n' "$progname $scriptversion" - $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p - } - /^# Written by / { - s|^# || - p - } - /^warranty; /q' < "$progpath" - - exit $? -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: - -# Set a version string. -scriptversion='(GNU libtool) 2.4.6' - - -# func_echo ARG... -# ---------------- -# Libtool also displays the current mode in messages, so override -# funclib.sh func_echo with this custom definition. -func_echo () -{ - $debug_cmd - - _G_message=$* - - func_echo_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_IFS - $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" - done - IFS=$func_echo_IFS -} - - -# func_warning ARG... -# ------------------- -# Libtool warnings are not categorized, so override funclib.sh -# func_warning with this simpler definition. -func_warning () -{ - $debug_cmd - - $warning_func ${1+"$@"} -} - - -## ---------------- ## -## Options parsing. ## -## ---------------- ## - -# Hook in the functions to make sure our own options are parsed during -# the option parsing loop. - -usage='$progpath [OPTION]... [MODE-ARG]...' - -# Short help message in response to '-h'. -usage_message="Options: - --config show all configuration variables - --debug enable verbose shell tracing - -n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --mode=MODE use operation mode MODE - --no-warnings equivalent to '-Wnone' - --preserve-dup-deps don't remove duplicate dependency libraries - --quiet, --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - -v, --verbose print more informational messages than default - --version print version information - -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] - -h, --help, --help-all print short, long, or detailed help message -" - -# Additional text appended to 'usage_message' in response to '--help'. -func_help () -{ - $debug_cmd - - func_usage_message - $ECHO "$long_help_message - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. When passed as first option, -'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. -Try '$progname --help --mode=MODE' for a more detailed description of MODE. - -When reporting a bug, please describe a test case to reproduce it and -include the following information: - - host-triplet: $host - shell: $SHELL - compiler: $LTCC - compiler flags: $LTCFLAGS - linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 - automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` - autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` - -Report bugs to . -GNU libtool home page: . -General help using GNU software: ." - exit 0 -} - - -# func_lo2o OBJECT-NAME -# --------------------- -# Transform OBJECT-NAME from a '.lo' suffix to the platform specific -# object suffix. - -lo2o=s/\\.lo\$/.$objext/ -o2lo=s/\\.$objext\$/.lo/ - -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_lo2o () - { - case $1 in - *.lo) func_lo2o_result=${1%.lo}.$objext ;; - * ) func_lo2o_result=$1 ;; - esac - }' - - # func_xform LIBOBJ-OR-SOURCE - # --------------------------- - # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) - # suffix to a '.lo' libtool-object suffix. - eval 'func_xform () - { - func_xform_result=${1%.*}.lo - }' -else - # ...otherwise fall back to using sed. - func_lo2o () - { - func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` - } - - func_xform () - { - func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` - } -fi - - -# func_fatal_configuration ARG... -# ------------------------------- -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func__fatal_error ${1+"$@"} \ - "See the $PACKAGE documentation for more information." \ - "Fatal configuration error." -} - - -# func_config -# ----------- -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - - -# func_features -# ------------- -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test yes = "$build_libtool_libs"; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test yes = "$build_old_libs"; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - - -# func_enable_tag TAGNAME -# ----------------------- -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname=$1 - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf=/$re_begincf/,/$re_endcf/p - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - - -# func_check_version_match -# ------------------------ -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# libtool_options_prep [ARG]... -# ----------------------------- -# Preparation for options parsed by libtool. -libtool_options_prep () -{ - $debug_mode - - # Option defaults: - opt_config=false - opt_dlopen= - opt_dry_run=false - opt_help=false - opt_mode= - opt_preserve_dup_deps=false - opt_quiet=false - - nonopt= - preserve_args= - - # Shorthand for --mode=foo, only valid as the first argument - case $1 in - clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; - compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; - execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; - finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; - install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; - link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; - uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; - esac - - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result -} -func_add_hook func_options_prep libtool_options_prep - - -# libtool_parse_options [ARG]... -# --------------------------------- -# Provide handling for libtool specific options. -libtool_parse_options () -{ - $debug_cmd - - # Perform our own loop to consume as many options as possible in - # each iteration. - while test $# -gt 0; do - _G_opt=$1 - shift - case $_G_opt in - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - - --config) func_config ;; - - --dlopen|-dlopen) - opt_dlopen="${opt_dlopen+$opt_dlopen -}$1" - shift - ;; - - --preserve-dup-deps) - opt_preserve_dup_deps=: ;; - - --features) func_features ;; - - --finish) set dummy --mode finish ${1+"$@"}; shift ;; - - --help) opt_help=: ;; - - --help-all) opt_help=': help-all' ;; - - --mode) test $# = 0 && func_missing_arg $_G_opt && break - opt_mode=$1 - case $1 in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $_G_opt" - exit_cmd=exit - break - ;; - esac - shift - ;; - - --no-silent|--no-quiet) - opt_quiet=false - func_append preserve_args " $_G_opt" - ;; - - --no-warnings|--no-warning|--no-warn) - opt_warning=false - func_append preserve_args " $_G_opt" - ;; - - --no-verbose) - opt_verbose=false - func_append preserve_args " $_G_opt" - ;; - - --silent|--quiet) - opt_quiet=: - opt_verbose=false - func_append preserve_args " $_G_opt" - ;; - - --tag) test $# = 0 && func_missing_arg $_G_opt && break - opt_tag=$1 - func_append preserve_args " $_G_opt $1" - func_enable_tag "$1" - shift - ;; - - --verbose|-v) opt_quiet=false - opt_verbose=: - func_append preserve_args " $_G_opt" - ;; - - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; - esac - done - - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result -} -func_add_hook func_parse_options libtool_parse_options - - - -# libtool_validate_options [ARG]... -# --------------------------------- -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -libtool_validate_options () -{ - # save first non-option argument - if test 0 -lt $#; then - nonopt=$1 - shift - fi - - # preserve --debug - test : = "$debug_cmd" || func_append preserve_args " --debug" - - case $host in - # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 - # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 - *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - test yes != "$build_libtool_libs" \ - && test yes != "$build_old_libs" \ - && func_fatal_configuration "not configured to build any kind of library" - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test execute != "$opt_mode"; then - func_error "unrecognized option '-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help=$help - help="Try '$progname --help --mode=$opt_mode' for more information." - } - - # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result -} -func_add_hook func_validate_options libtool_validate_options - - -# Process options as early as possible so that --help and --version -# can return quickly. -func_options ${1+"$@"} -eval set dummy "$func_options_result"; shift - - - -## ----------- ## -## Main. ## -## ----------- ## - -magic='%%%MAGIC variable%%%' -magic_exe='%%%MAGIC EXE variable%%%' - -# Global variables. -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# func_generated_by_libtool -# True iff stdin has been generated by Libtool. This function is only -# a basic sanity check; it will hardly flush out determined imposters. -func_generated_by_libtool_p () -{ - $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_p file -# True iff FILE is a libtool '.la' library or '.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool '.la' library or '.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if 'file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case $lalib_p_line in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test yes = "$lalib_p" -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - test -f "$1" && - $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $debug_cmd - - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$sp$nl - eval cmd=\"$cmd\" - IFS=$save_ifs - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# 'FILE.' does not work on cygwin managed mounts. -func_source () -{ - $debug_cmd - - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case $lt_sysroot:$1 in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result='='$func_stripname_result - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $debug_cmd - - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with '--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=$1 - if test yes = "$build_libtool_libs"; then - write_lobj=\'$2\' - else - write_lobj=none - fi - - if test yes = "$build_old_libs"; then - write_oldobj=\'$3\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $debug_cmd - - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result= - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result"; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $debug_cmd - - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $debug_cmd - - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $debug_cmd - - if test -z "$2" && test -n "$1"; then - func_error "Could not determine host file name corresponding to" - func_error " '$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result=$1 - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $debug_cmd - - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " '$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result=$3 - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $debug_cmd - - case $4 in - $1 ) func_to_host_path_result=$3$func_to_host_path_result - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via '$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $debug_cmd - - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $debug_cmd - - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result=$1 -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result=$func_convert_core_msys_to_w32_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result=$func_convert_core_file_wine_to_w32_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result=$func_cygpath_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result=$func_cygpath_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via '$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $debug_cmd - - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd=func_convert_path_$func_stripname_result - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $debug_cmd - - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result=$1 -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result=$func_convert_core_msys_to_w32_result - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result=$func_convert_core_path_wine_to_w32_result - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result=$func_cygpath_result - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result=$func_cygpath_result - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_dll_def_p FILE -# True iff FILE is a Windows DLL '.def' file. -# Keep in sync with _LT_DLL_DEF_P in libtool.m4 -func_dll_def_p () -{ - $debug_cmd - - func_dll_def_p_tmp=`$SED -n \ - -e 's/^[ ]*//' \ - -e '/^\(;.*\)*$/d' \ - -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ - -e q \ - "$1"` - test DEF = "$func_dll_def_p_tmp" -} - - -# func_mode_compile arg... -func_mode_compile () -{ - $debug_cmd - - # Get the compilation command and the source file. - base_compile= - srcfile=$nonopt # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg=$arg - arg_mode=normal - ;; - - target ) - libobj=$arg - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify '-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs=$IFS; IFS=, - for arg in $args; do - IFS=$save_ifs - func_append_quoted lastarg "$arg" - done - IFS=$save_ifs - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg=$srcfile - srcfile=$arg - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with '-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj=$func_basename_result - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from '$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test yes = "$build_libtool_libs" \ - || func_fatal_configuration "cannot build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name '$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname=$func_basename_result - xdir=$func_dirname_result - lobj=$xdir$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test yes = "$build_old_libs"; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test no = "$compiler_c_o"; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext - lockfile=$output_obj.lock - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test yes = "$need_locks"; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test warn = "$need_locks"; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test yes = "$build_libtool_libs"; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test no != "$pic_mode"; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test warn = "$need_locks" && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test yes = "$suppress_opt"; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test yes = "$build_old_libs"; then - if test yes != "$pic_mode"; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test yes = "$compiler_c_o"; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test warn = "$need_locks" && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test no != "$need_locks"; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test compile = "$opt_mode" && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a '.o' file suitable for static linking - -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a 'standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix '.c' with the -library object suffix, '.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to '-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the '--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the 'install' or 'cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE use a list of object files found in FILE to specify objects - -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with '-') are ignored. - -Every other argument is treated as a filename. Files ending in '.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in '.la', then a libtool library is created, -only library objects ('.lo' files) may be specified, and '-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created -using 'ar' and 'ranlib', or on Windows using 'lib'. - -If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode '$opt_mode'" - ;; - esac - - echo - $ECHO "Try '$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test : = "$opt_help"; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | $SED -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - $SED '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $debug_cmd - - # The first argument is the command name. - cmd=$nonopt - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "'$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "'$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "'$file' was not linked with '-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir=$func_dirname_result - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir=$func_dirname_result - ;; - - *) - func_warning "'-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir=$absdir - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic=$magic - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file=$progdir/$program - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file=$progdir/$program - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if $opt_dry_run; then - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - else - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd=\$cmd$args - fi -} - -test execute = "$opt_mode" && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $debug_cmd - - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "'$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument '$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and '=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_quiet && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the '-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the '$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the '$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the '$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test finish = "$opt_mode" && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $debug_cmd - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac - then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=false - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=: ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test X-m = "X$prev" && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the '$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=: - if $isdir; then - destdir=$dest - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir=$func_dirname_result - destname=$func_basename_result - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "'$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "'$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic=$magic - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "'$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir=$func_dirname_result - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking '$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname=$1 - shift - - srcname=$realname - test -n "$relink_command" && srcname=${realname}T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme=$stripme - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme= - ;; - esac - ;; - os2*) - case $realname in - *_dll.a) - tstripme= - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try 'ln -sf' first, because the 'ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib=$destdir/$realname - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name=$func_basename_result - instname=$dir/${name}i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile=$destdir/$destname - else - func_basename "$file" - destfile=$func_basename_result - destfile=$destdir/$destfile - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest=$destfile - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to '$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test yes = "$build_old_libs"; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile=$destdir/$destname - else - func_basename "$file" - destfile=$func_basename_result - destfile=$destdir/$destfile - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext= - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=.exe - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script '$wrapper'" - - finalize=: - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "'$lib' has not been installed in '$libdir'" - finalize=false - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test no = "$fast_install" && test -n "$relink_command"; then - $opt_dry_run || { - if $finalize; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file=$func_basename_result - outputname=$tmpdir/$file - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink '$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file=$outputname - else - func_warning "cannot relink '$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name=$func_basename_result - - # Set up the ranlib parameters. - oldlib=$destdir/$name - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $tool_oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run '$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test install = "$opt_mode" && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $debug_cmd - - my_outputname=$1 - my_originator=$2 - my_pic_p=${3-false} - my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms=${my_outputname}S.c - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist=$output_objdir/$my_outputname.nm - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) - -/* External symbol declarations for the compiler. */\ -" - - if test yes = "$dlself"; then - func_verbose "generating symbol list for '$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from '$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols=$output_objdir/$outputname.exp - $opt_dry_run || { - $RM $export_symbols - eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from '$dlprefile'" - func_basename "$dlprefile" - name=$func_basename_result - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename= - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname"; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename=$func_basename_result - else - # no lafile. user explicitly requested -dlpreopen . - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename"; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - func_show_eval '$RM "${nlist}I"' - if test -n "$global_symbol_to_import"; then - eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[];\ -" - - if test -s "$nlist"I; then - echo >> "$output_objdir/$my_dlsyms" "\ -static void lt_syminit(void) -{ - LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; - for (; symbol->name; ++symbol) - {" - $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" - echo >> "$output_objdir/$my_dlsyms" "\ - } -}" - fi - echo >> "$output_objdir/$my_dlsyms" "\ -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{ {\"$my_originator\", (void *) 0}," - - if test -s "$nlist"I; then - echo >> "$output_objdir/$my_dlsyms" "\ - {\"@INIT@\", (void *) <_syminit}," - fi - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - $my_pic_p && pic_flag_for_symtable=" $pic_flag" - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' - - # Transform the symbol file into the correct name. - symfileobj=$output_objdir/${my_outputname}S.$objext - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for '$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $debug_cmd - - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $debug_cmd - - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $debug_cmd - - win32_libid_type=unknown - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - case $nm_interface in - "MS dumpbin") - if func_cygming_ms_implib_p "$1" || - func_cygming_gnu_implib_p "$1" - then - win32_nmres=import - else - win32_nmres= - fi - ;; - *) - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s|.*|import| - p - q - } - }'` - ;; - esac - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $debug_cmd - - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $debug_cmd - - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive that possess that section. Heuristic: eliminate - # all those that have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $debug_cmd - - if func_cygming_gnu_implib_p "$1"; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1"; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result= - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $debug_cmd - - f_ex_an_ar_dir=$1; shift - f_ex_an_ar_oldlib=$1 - if test yes = "$lock_old_archive_extraction"; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test yes = "$lock_old_archive_extraction"; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $debug_cmd - - my_gentop=$1; shift - my_oldlibs=${1+"$@"} - my_oldobjs= - my_xlib= - my_xabs= - my_xdir= - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib=$func_basename_result - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir=$my_gentop/$my_xlib_u - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - func_basename "$darwin_archive" - darwin_base_archive=$func_basename_result - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches; do - func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" - $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" - cd "unfat-$$/$darwin_base_archive-$darwin_arch" - func_extract_an_archive "`pwd`" "$darwin_base_archive" - cd "$darwin_curdir" - $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result=$my_oldobjs -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory where it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ that is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options that match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case \" \$* \" in - *\\ --lt-*) - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done ;; - esac - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test yes = "$fast_install"; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - \$ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -#else -# include -# include -# ifdef __CYGWIN__ -# include -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) - -/* declarations of non-ANSI functions */ -#if defined __MINGW32__ -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined __CYGWIN__ -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined other_platform || defined ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined _MSC_VER -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -#elif defined __MINGW32__ -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined __CYGWIN__ -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined other platforms ... */ -#endif - -#if defined PATH_MAX -# define LT_PATHMAX PATH_MAX -#elif defined MAXPATHLEN -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ - defined __OS2__ -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free (stale); stale = 0; } \ -} while (0) - -#if defined LT_DEBUGWRAPPER -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - size_t tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined HAVE_DOS_BASED_FILE_SYSTEM - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined HAVE_DOS_BASED_FILE_SYSTEM - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = (size_t) (q - p); - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (STREQ (str, pat)) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - size_t len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - size_t orig_value_len = strlen (orig_value); - size_t add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - size_t len = strlen (new_value); - while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[--len] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -n -e ' -s/^\(.\{79\}\)\(..*\)/\1\ -\2/ -h -s/\([\\"]\)/\\\1/g -s/$/\\n/ -s/\([^\n]*\).*/ fputs ("\1", f);/p -g -D' - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $debug_cmd - - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_suncc_cstd_abi -# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! -# Several compiler flags select an ABI that is incompatible with the -# Cstd library. Avoid specifying it if any are in CXXFLAGS. -func_suncc_cstd_abi () -{ - $debug_cmd - - case " $compile_command " in - *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) - suncc_use_cstd_abi=no - ;; - *) - suncc_use_cstd_abi=yes - ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $debug_cmd - - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # what system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll that has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - os2dllname= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=false - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module=$wl-single_module - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test yes != "$build_libtool_libs" \ - && func_fatal_configuration "cannot build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg=$1 - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir=$arg - prev= - continue - ;; - dlfiles|dlprefiles) - $preload || { - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=: - } - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test no = "$dlself"; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test dlprefiles = "$prev"; then - dlself=yes - elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test dlfiles = "$prev"; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols=$arg - test -f "$arg" \ - || func_fatal_error "symbol file '$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex=$arg - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir=$arg - prev= - continue - ;; - mllvm) - # Clang does not use LLVM to link, so we can simply discard any - # '-mllvm $arg' options when doing the link step. - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test none = "$pic_object" && - test none = "$non_pic_object"; then - func_fatal_error "cannot find name of object for '$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - if test none != "$pic_object"; then - # Prepend the subdirectory the object is found in. - pic_object=$xdir$pic_object - - if test dlfiles = "$prev"; then - if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test dlprefiles = "$prev"; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg=$pic_object - fi - - # Non-PIC object. - if test none != "$non_pic_object"; then - # Prepend the subdirectory the object is found in. - non_pic_object=$xdir$non_pic_object - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test none = "$pic_object"; then - arg=$non_pic_object - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object=$pic_object - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "'$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file '$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - os2dllname) - os2dllname=$arg - prev= - continue - ;; - precious_regex) - precious_files_regex=$arg - prev= - continue - ;; - release) - release=-$arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test rpath = "$prev"; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds=$arg - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg=$arg - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "'-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test X-export-symbols = "X$arg"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between '-L' and '$1'" - else - func_fatal_error "need path for '-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of '$dir'" - dir=$absdir - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test X-lc = "X$arg" || test X-lm = "X$arg"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test X-lc = "X$arg" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) - # Do not include libc due to us having libc/libc_r. - test X-lc = "X$arg" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test X-lc = "X$arg" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test X-lc = "X$arg" && continue - ;; - esac - elif test X-lc_r = "X$arg"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -mllvm) - prev=mllvm - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module=$wl-multi_module - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "'-no-install' is ignored for $host" - func_warning "assuming '-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -os2dllname) - prev=os2dllname - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs=$IFS; IFS=, - for flag in $args; do - IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS=$save_ifs - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs=$IFS; IFS=, - for flag in $args; do - IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS=$save_ifs - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # -fstack-protector* stack protector flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - # -stdlib=* select c++ std lib with clang - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - -Z*) - if test os2 = "`expr $host : '.*\(os2\)'`"; then - # OS/2 uses -Zxxx to specify OS/2-specific options - compiler_flags="$compiler_flags $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case $arg in - -Zlinker | -Zstack) - prev=xcompiler - ;; - esac - continue - else - # Otherwise treat like 'Some other compiler flag' below - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - fi - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test none = "$pic_object" && - test none = "$non_pic_object"; then - func_fatal_error "cannot find name of object for '$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - test none = "$pic_object" || { - # Prepend the subdirectory the object is found in. - pic_object=$xdir$pic_object - - if test dlfiles = "$prev"; then - if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test dlprefiles = "$prev"; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg=$pic_object - } - - # Non-PIC object. - if test none != "$non_pic_object"; then - # Prepend the subdirectory the object is found in. - non_pic_object=$xdir$non_pic_object - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test none = "$pic_object"; then - arg=$non_pic_object - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object=$pic_object - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "'$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test dlfiles = "$prev"; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test dlprefiles = "$prev"; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the '$prevarg' option requires an argument" - - if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname=$func_basename_result - libobjs_save=$libobjs - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - # Definition is injected by LT_CONFIG during libtool generation. - func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" - - func_dirname "$output" "/" "" - output_objdir=$func_dirname_result$objdir - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test lib = "$linkmode"; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=false - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test lib,link = "$linkmode,$pass"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs=$tmp_deplibs - fi - - if test lib,link = "$linkmode,$pass" || - test prog,scan = "$linkmode,$pass"; then - libs=$deplibs - deplibs= - fi - if test prog = "$linkmode"; then - case $pass in - dlopen) libs=$dlfiles ;; - dlpreopen) libs=$dlprefiles ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test lib,dlpreopen = "$linkmode,$pass"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs=$dlprefiles - fi - if test dlopen = "$pass"; then - # Collect dlpreopened libraries - save_deplibs=$deplibs - deplibs= - fi - - for deplib in $libs; do - lib= - found=false - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test lib = "$linkmode"; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test lib != "$linkmode" && test prog != "$linkmode"; then - func_warning "'-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test lib = "$linkmode"; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib=$searchdir/lib$name$search_ext - if test -f "$lib"; then - if test .la = "$search_ext"; then - found=: - else - found=false - fi - break 2 - fi - done - done - if $found; then - # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll=$l - done - if test "X$ll" = "X$old_library"; then # only static version available - found=false - func_dirname "$lib" "" "." - ladir=$func_dirname_result - lib=$ladir/$old_library - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - else - # deplib doesn't seem to be a libtool library - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - *.ltframework) - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test lib = "$linkmode"; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test conv = "$pass" && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - continue - fi - if test scan = "$pass"; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "'-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test link = "$pass"; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=false - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=: - fi - ;; - pass_all) - valid_a_lib=: - ;; - esac - if $valid_a_lib; then - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - else - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - fi - ;; - esac - continue - ;; - prog) - if test link != "$pass"; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - elif test prog = "$linkmode"; then - if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=: - continue - ;; - esac # case $deplib - - $found || test -f "$lib" \ - || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "'$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir=$func_dirname_result - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test lib,link = "$linkmode,$pass" || - test prog,scan = "$linkmode,$pass" || - { test prog != "$linkmode" && test lib != "$linkmode"; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test conv = "$pass"; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for '$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - elif test prog != "$linkmode" && test lib != "$linkmode"; then - func_fatal_error "'$lib' is not a convenience library" - fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test yes = "$prefer_static_libs" || - test built,no = "$prefer_static_libs,$installed"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib=$l - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for '$lib'" - fi - - # This library was specified with -dlopen. - if test dlopen = "$pass"; then - test -z "$libdir" \ - && func_fatal_error "cannot -dlopen a convenience library: '$lib'" - if test -z "$dlname" || - test yes != "$dlopen_support" || - test no = "$build_libtool_libs" - then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of '$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir=$ladir - fi - ;; - esac - func_basename "$lib" - laname=$func_basename_result - - # Find the relevant object directory and library name. - if test yes = "$installed"; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library '$lib' was moved." - dir=$ladir - absdir=$abs_ladir - libdir=$abs_ladir - else - dir=$lt_sysroot$libdir - absdir=$lt_sysroot$libdir - fi - test yes = "$hardcode_automatic" && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir=$ladir - absdir=$abs_ladir - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir=$ladir/$objdir - absdir=$abs_ladir/$objdir - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test dlpreopen = "$pass"; then - if test -z "$libdir" && test prog = "$linkmode"; then - func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" - fi - case $host in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test lib = "$linkmode"; then - deplibs="$dir/$old_library $deplibs" - elif test prog,link = "$linkmode,$pass"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test prog = "$linkmode" && test link != "$pass"; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=false - if test no != "$link_all_deplibs" || test -z "$library_names" || - test no = "$build_libtool_libs"; then - linkalldeplibs=: - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if $linkalldeplibs; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test prog,link = "$linkmode,$pass"; then - if test -n "$library_names" && - { { test no = "$prefer_static_libs" || - test built,yes = "$prefer_static_libs,$installed"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then - # Make sure the rpath contains only unique directories. - case $temp_rpath: in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if $alldeplibs && - { test pass_all = "$deplibs_check_method" || - { test yes = "$build_libtool_libs" && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test built = "$use_static_libs" && test yes = "$installed"; then - use_static_libs=no - fi - if test -n "$library_names" && - { test no = "$use_static_libs" || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc* | *os2*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test no = "$installed"; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule= - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule=$dlpremoduletest - break - fi - done - if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then - echo - if test prog = "$linkmode"; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test lib = "$linkmode" && - test yes = "$hardcode_into_libs"; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname=$1 - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname=$dlname - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc* | *os2*) - func_arith $current - $age - major=$func_arith_result - versuffix=-$major - ;; - esac - eval soname=\"$soname_spec\" - else - soname=$realname - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot=$soname - func_basename "$soroot" - soname=$func_basename_result - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from '$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for '$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test prog = "$linkmode" || test relink != "$opt_mode"; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test no = "$hardcode_direct"; then - add=$dir/$linklib - case $host in - *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; - *-*-sysv4*uw2*) add_dir=-L$dir ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir=-L$dir ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we cannot - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library"; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add=$dir/$old_library - fi - elif test -n "$old_library"; then - add=$dir/$old_library - fi - fi - esac - elif test no = "$hardcode_minus_L"; then - case $host in - *-*-sunos*) add_shlibpath=$dir ;; - esac - add_dir=-L$dir - add=-l$name - elif test no = "$hardcode_shlibpath_var"; then - add_shlibpath=$dir - add=-l$name - else - lib_linked=no - fi - ;; - relink) - if test yes = "$hardcode_direct" && - test no = "$hardcode_direct_absolute"; then - add=$dir/$linklib - elif test yes = "$hardcode_minus_L"; then - add_dir=-L$absdir - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add=-l$name - elif test yes = "$hardcode_shlibpath_var"; then - add_shlibpath=$dir - add=-l$name - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test yes != "$lib_linked"; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test prog = "$linkmode"; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test yes != "$hardcode_direct" && - test yes != "$hardcode_minus_L" && - test yes = "$hardcode_shlibpath_var"; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test prog = "$linkmode" || test relink = "$opt_mode"; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test yes = "$hardcode_direct" && - test no = "$hardcode_direct_absolute"; then - add=$libdir/$linklib - elif test yes = "$hardcode_minus_L"; then - add_dir=-L$libdir - add=-l$name - elif test yes = "$hardcode_shlibpath_var"; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add=-l$name - elif test yes = "$hardcode_automatic"; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib"; then - add=$inst_prefix_dir$libdir/$linklib - else - add=$libdir/$linklib - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir=-L$libdir - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add=-l$name - fi - - if test prog = "$linkmode"; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test prog = "$linkmode"; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test unsupported != "$hardcode_direct"; then - test -n "$old_library" && linklib=$old_library - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test yes = "$build_libtool_libs"; then - # Not a shared library - if test pass_all != "$deplibs_check_method"; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system cannot link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test yes = "$module"; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using 'nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** 'nm' from GNU binutils and a full rebuild may help." - fi - if test no = "$build_old_libs"; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test lib = "$linkmode"; then - if test -n "$dependency_libs" && - { test yes != "$hardcode_into_libs" || - test yes = "$build_old_libs" || - test yes = "$link_static"; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs=$temp_deplibs - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test no != "$link_all_deplibs"; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path=$deplib ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of '$dir'" - absdir=$dir - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names"; then - for tmp in $deplibrary_names; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl"; then - depdepl=$absdir/$objdir/$depdepl - darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" - func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" - path= - fi - fi - ;; - *) - path=-L$absdir/$objdir - ;; - esac - else - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "'$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "'$deplib' seems to be moved" - - path=-L$absdir - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test link = "$pass"; then - if test prog = "$linkmode"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs=$newdependency_libs - if test dlpreopen = "$pass"; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test dlopen != "$pass"; then - test conv = "$pass" || { - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - } - - if test prog,link = "$linkmode,$pass"; then - vars="compile_deplibs finalize_deplibs" - else - vars=deplibs - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - - # Add Sun CC postdeps if required: - test CXX = "$tagname" && { - case $host_os in - linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C++ 5.9 - func_suncc_cstd_abi - - if test no != "$suncc_use_cstd_abi"; then - func_append postdeps ' -library=Cstd -library=Crun' - fi - ;; - esac - ;; - - solaris*) - func_cc_basename "$CC" - case $func_cc_basename_result in - CC* | sunCC*) - func_suncc_cstd_abi - - if test no != "$suncc_use_cstd_abi"; then - func_append postdeps ' -library=Cstd -library=Crun' - fi - ;; - esac - ;; - esac - } - - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i= - ;; - esac - if test -n "$i"; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test prog = "$linkmode"; then - dlfiles=$newdlfiles - fi - if test prog = "$linkmode" || test lib = "$linkmode"; then - dlprefiles=$newdlprefiles - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - func_warning "'-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "'-l' and '-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "'-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "'-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "'-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "'-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "'-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs=$output - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form 'libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test no = "$module" \ - && func_fatal_help "libtool library '$output' must begin with 'lib'" - - if test no != "$need_lib_prefix"; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test pass_all != "$deplibs_check_method"; then - func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test no = "$dlself" \ - || func_warning "'-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test 1 -lt "$#" \ - && func_warning "ignoring multiple '-rpath's for a libtool library" - - install_libdir=$1 - - oldlibs= - if test -z "$rpath"; then - if test yes = "$build_libtool_libs"; then - # Building a libtool convenience library. - # Some compilers have problems with a '.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "'-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "'-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs=$IFS; IFS=: - set dummy $vinfo 0 0 0 - shift - IFS=$save_ifs - - test -n "$7" && \ - func_fatal_help "too many parameters to '-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major=$1 - number_minor=$2 - number_revision=$3 - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # that has an extra 1 added just for fun - # - case $version_type in - # correct linux to gnu/linux during the next big refactor - darwin|freebsd-elf|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age=$number_minor - revision=$number_revision - ;; - freebsd-aout|qnx|sunos) - current=$number_major - revision=$number_minor - age=0 - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age=$number_minor - revision=$number_minor - lt_irix_increment=no - ;; - esac - ;; - no) - current=$1 - revision=$2 - age=$3 - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT '$current' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION '$revision' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE '$age' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE '$age' is greater than the current interface number '$current'" - func_fatal_error "'$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - # On Darwin other compilers - case $CC in - nagfor*) - verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" - ;; - *) - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - esac - ;; - - freebsd-aout) - major=.$current - versuffix=.$current.$revision - ;; - - freebsd-elf) - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - ;; - - irix | nonstopux) - if test no = "$lt_irix_increment"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring=$verstring_prefix$major.$revision - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test 0 -ne "$loop"; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring=$verstring_prefix$major.$iface:$verstring - done - - # Before this point, $major must not contain '.'. - major=.$major - versuffix=$major.$revision - ;; - - linux) # correct to gnu/linux during the next big refactor - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=.$current.$age.$revision - verstring=$current.$age.$revision - - # Add in all the interfaces that we are compatible with. - loop=$age - while test 0 -ne "$loop"; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring=$verstring:$iface.0 - done - - # Make executables depend on our current version. - func_append verstring ":$current.0" - ;; - - qnx) - major=.$current - versuffix=.$current - ;; - - sco) - major=.$current - versuffix=.$current - ;; - - sunos) - major=.$current - versuffix=.$current.$revision - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 file systems. - func_arith $current - $age - major=$func_arith_result - versuffix=-$major - ;; - - *) - func_fatal_configuration "unknown library version type '$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring=0.0 - ;; - esac - if test no = "$need_version"; then - versuffix= - else - versuffix=.0.0 - fi - fi - - # Remove version info from name if versioning should be avoided - if test yes,no = "$avoid_version,$need_version"; then - major= - versuffix= - verstring= - fi - - # Check to see if the archive will have undefined symbols. - if test yes = "$allow_undefined"; then - if test unsupported = "$allow_undefined_flag"; then - if test yes = "$build_old_libs"; then - func_warning "undefined symbols not allowed in $host shared libraries; building static only" - build_libtool_libs=no - else - func_fatal_error "can't build $host shared library unless -no-undefined is specified" - fi - fi - else - # Don't allow undefined symbols. - allow_undefined_flag=$no_undefined_flag - fi - - fi - - func_generate_dlsyms "$libname" "$libname" : - func_append libobjs " $symfileobj" - test " " = "$libobjs" && libobjs= - - if test relink != "$opt_mode"; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) - if test -n "$precious_files_regex"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles=$dlfiles - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles=$dlprefiles - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test yes = "$build_libtool_libs"; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test yes = "$build_libtool_need_lc"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release= - versuffix= - major= - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib=$potent_lib - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | $SED 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; - *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib= - break 2 - fi - done - done - fi - if test -n "$a_deplib"; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib"; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib= - ;; - esac - fi - if test -n "$a_deplib"; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib=$potent_lib # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib= - break 2 - fi - done - done - fi - if test -n "$a_deplib"; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib"; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs= - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - for i in $predeps $postdeps; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test none = "$deplibs_check_method"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test yes = "$droppeddeps"; then - if test yes = "$module"; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using 'nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** 'nm' from GNU binutils and a full rebuild may help." - fi - if test no = "$build_old_libs"; then - oldlibs=$output_objdir/$libname.$libext - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test no = "$allow_undefined"; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test no = "$build_old_libs"; then - oldlibs=$output_objdir/$libname.$libext - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs=$new_libs - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test yes = "$build_libtool_libs"; then - # Remove $wl instances when linking with ld. - # FIXME: should test the right _cmds variable. - case $archive_cmds in - *\$LD\ *) wl= ;; - esac - if test yes = "$hardcode_into_libs"; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath=$finalize_rpath - test relink = "$opt_mode" || rpath=$compile_rpath$rpath - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath=$finalize_shlibpath - test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname=$1 - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname=$realname - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib=$output_objdir/$realname - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols=$output_objdir/$libname.uexp - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - func_dll_def_p "$export_symbols" || { - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols=$export_symbols - export_symbols= - always_export_symbols=yes - } - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for '$libname.la'" - export_symbols=$output_objdir/$libname.exp - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs=$IFS; IFS='~' - for cmd1 in $cmds; do - IFS=$save_ifs - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test yes = "$try_normal_branch" \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=$output_objdir/$output_la.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS=$save_ifs - if test -n "$export_symbols_regex" && test : != "$skipped_export"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols=$export_symbols - test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test : != "$skipped_export" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for '$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands, which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs=$tmp_deplibs - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test yes = "$compiler_needs_object" && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test relink = "$opt_mode"; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test yes = "$module" && test -n "$module_cmds"; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test : != "$skipped_export" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then - output=$output_objdir/$output_la.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then - output=$output_objdir/$output_la.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test yes = "$compiler_needs_object"; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-$k.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test -z "$objlist" || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test 1 -eq "$k"; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-$k.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-$k.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - ${skipped_export-false} && { - func_verbose "generating symbol list for '$libname.la'" - export_symbols=$output_objdir/$libname.exp - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - } - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs=$IFS; IFS='~' - for cmd in $concat_cmds; do - IFS=$save_ifs - $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS=$save_ifs - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - ${skipped_export-false} && { - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols=$export_symbols - test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for '$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands, which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - } - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test yes = "$module" && test -n "$module_cmds"; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs=$IFS; IFS='~' - for cmd in $cmds; do - IFS=$sp$nl - eval cmd=\"$cmd\" - IFS=$save_ifs - $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS=$save_ifs - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test yes = "$module" || test yes = "$export_dynamic"; then - # On all known operating systems, these are identical. - dlname=$soname - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - func_warning "'-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "'-l' and '-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "'-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "'-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "'-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "'-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object '$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj=$output - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # if reload_cmds runs $LD directly, get rid of -Wl from - # whole_archive_flag_spec and hope we can get by with turning comma - # into space. - case $reload_cmds in - *\$LD[\ \$]*) wl= ;; - esac - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags - else - gentop=$output_objdir/${obj}x - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test yes = "$build_libtool_libs" || libobjs=$non_pic_objects - - # Create the old-style object. - reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs - - output=$obj - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - test yes = "$build_libtool_libs" || { - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - } - - if test -n "$pic_flag" || test default != "$pic_mode"; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output=$libobj - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "'-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "'-release' is ignored for programs" - - $preload \ - && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ - && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test CXX = "$tagname"; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " $wl-bind_at_load" - func_append finalize_command " $wl-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs=$new_libs - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath=$rpath - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath=$rpath - - if test -n "$libobjs" && test yes = "$build_old_libs"; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" false - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=: - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=false - ;; - *cygwin* | *mingw* ) - test yes = "$build_libtool_libs" || wrappers_required=false - ;; - *) - if test no = "$need_relink" || test yes != "$build_libtool_libs"; then - wrappers_required=false - fi - ;; - esac - $wrappers_required || { - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command=$compile_command$compile_rpath - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.$objext"; then - func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' - fi - - exit $exit_status - } - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test yes = "$no_install"; then - # We don't need to create a wrapper script. - link_command=$compile_var$compile_command$compile_rpath - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - case $hardcode_action,$fast_install in - relink,*) - # Fast installation is not supported - link_command=$compile_var$compile_command$compile_rpath - relink_command=$finalize_var$finalize_command$finalize_rpath - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "'$output' will be relinked during installation" - ;; - *,yes) - link_command=$finalize_var$compile_command$finalize_rpath - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - ;; - *,no) - link_command=$compile_var$compile_command$compile_rpath - relink_command=$finalize_var$finalize_command$finalize_rpath - ;; - *,needless) - link_command=$finalize_var$compile_command$finalize_rpath - relink_command= - ;; - esac - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource=$output_path/$objdir/lt-$output_name.c - cwrapper=$output_path/$output_name.exe - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host"; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - case $build_libtool_libs in - convenience) - oldobjs="$libobjs_save $symfileobj" - addlibs=$convenience - build_libtool_libs=no - ;; - module) - oldobjs=$libobjs_save - addlibs=$old_convenience - build_libtool_libs=no - ;; - *) - oldobjs="$old_deplibs $non_pic_objects" - $preload && test -f "$symfileobj" \ - && func_append oldobjs " $symfileobj" - addlibs=$old_convenience - ;; - esac - - if test -n "$addlibs"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase=$func_basename_result - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj"; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test -z "$oldobjs"; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test yes = "$build_old_libs" && old_library=$libname.$libext - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test yes = "$hardcode_automatic"; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test yes = "$installed"; then - if test -z "$install_libdir"; then - break - fi - output=$output_objdir/${outputname}i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name=$func_basename_result - func_resolve_sysroot "$deplib" - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` - test -z "$libdir" && \ - func_fatal_error "'$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs=$newdependency_libs - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name=$func_basename_result - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "'$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles=$newdlfiles - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name=$func_basename_result - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "'$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles=$newdlprefiles - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles=$newdlfiles - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles=$newdlprefiles - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test -n "$bindir"; then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result/$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that cannot go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test no,yes = "$installed,$need_relink"; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -if test link = "$opt_mode" || test relink = "$opt_mode"; then - func_mode_link ${1+"$@"} -fi - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $debug_cmd - - RM=$nonopt - files= - rmforce=false - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic=$magic - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=: ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir=$func_dirname_result - if test . = "$dir"; then - odir=$objdir - else - odir=$dir/$objdir - fi - func_basename "$file" - name=$func_basename_result - test uninstall = "$opt_mode" && odir=$dir - - # Remember odir for removal later, being careful to avoid duplicates - if test clean = "$opt_mode"; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif $rmforce; then - continue - fi - - rmfiles=$file - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case $opt_mode in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && test none != "$pic_object"; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && test none != "$non_pic_object"; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test clean = "$opt_mode"; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.$objext" - if test yes = "$fast_install" && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name" - fi - if test "X$noexename" != "X$name"; then - func_append rmfiles " $odir/lt-$noexename.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the $objdir's in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then - func_mode_uninstall ${1+"$@"} -fi - -test -z "$opt_mode" && { - help=$generic_help - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode '$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# where we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/pcre2/m4/ax_pthread.m4 b/pcre2/m4/ax_pthread.m4 deleted file mode 100644 index d90de34d1..000000000 --- a/pcre2/m4/ax_pthread.m4 +++ /dev/null @@ -1,309 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro figures out how to build C programs using POSIX threads. It -# sets the PTHREAD_LIBS output variable to the threads library and linker -# flags, and the PTHREAD_CFLAGS output variable to any special C compiler -# flags that are needed. (The user can also force certain compiler -# flags/libs to be tested by setting these environment variables.) -# -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) -# -# NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with -# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS -# -# If you are only building threads programs, you may wish to use these -# variables in your default LIBS, CFLAGS, and CC: -# -# LIBS="$PTHREAD_LIBS $LIBS" -# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -# CC="$PTHREAD_CC" -# -# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). -# -# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the -# PTHREAD_PRIO_INHERIT symbol is defined when compiling with -# PTHREAD_CFLAGS. -# -# ACTION-IF-FOUND is a list of shell commands to run if a threads library -# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it -# is not found. If ACTION-IF-FOUND is not specified, the default action -# will define HAVE_PTHREAD. -# -# Please let the authors know if this macro fails on any platform, or if -# you have any other suggestions or comments. This macro was based on work -# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help -# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by -# Alejandro Forero Cuervo to the autoconf macro repository. We are also -# grateful for the helpful feedback of numerous users. -# -# Updated for Autoconf 2.68 by Daniel Richard G. -# -# LICENSE -# -# Copyright (c) 2008 Steven G. Johnson -# Copyright (c) 2011 Daniel Richard G. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 18 - -AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) -AC_DEFUN([AX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_LANG_PUSH([C]) -ax_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) - AC_MSG_RESULT($ax_pthread_ok) - if test x"$ax_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case ${host_os} in - solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" - ;; - - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" - ;; -esac - -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do - - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; - - pthread-config) - AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) - if test x"$ax_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - AC_MSG_RESULT($ax_pthread_ok) - if test "x$ax_pthread_ok" = xyes; then - break; - fi - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT($attr_name) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - ax_cv_PTHREAD_PRIO_INHERIT, [ - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - # More AIX lossage: must compile with xlc_r or cc_r - if test x"$GCC" != xyes; then - AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) - else - PTHREAD_CC=$CC - fi -else - PTHREAD_CC="$CC" -fi - -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) - : -else - ax_pthread_ok=no - $2 -fi -AC_LANG_POP -])dnl AX_PTHREAD diff --git a/pcre2/m4/libtool.m4 b/pcre2/m4/libtool.m4 deleted file mode 100644 index a3bc337b7..000000000 --- a/pcre2/m4/libtool.m4 +++ /dev/null @@ -1,8369 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program or library that is built -# using GNU Libtool, you may include this file under the same -# distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -]) - -# serial 58 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS=$ltmain - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_PREPARE_CC_BASENAME -# ----------------------- -m4_defun([_LT_PREPARE_CC_BASENAME], [ -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in @S|@*""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} -])# _LT_PREPARE_CC_BASENAME - - -# _LT_CC_BASENAME(CC) -# ------------------- -# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, -# but that macro is also expanded into generated libtool script, which -# arranges for $SED and $ECHO to be set by different means. -m4_defun([_LT_CC_BASENAME], -[m4_require([_LT_PREPARE_CC_BASENAME])dnl -AC_REQUIRE([_LT_DECL_SED])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl -func_cc_basename $1 -cc_basename=$func_cc_basename_result -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl -m4_require([_LT_CMD_TRUNCATE])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options that allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld=$lt_cv_prog_gnu_ld - -old_CC=$CC -old_CFLAGS=$CFLAGS - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from 'configure', and 'config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# 'config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain=$ac_aux_dir/ltmain.sh -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the 'libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to 'config.status' so that its -# declaration there will have the same value as in 'configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags='_LT_TAGS'dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into 'config.status', and then the shell code to quote escape them in -# for loops in 'config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# '#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test 0 = "$lt_write_fail" && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -'$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test 0 != $[#] -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try '$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try '$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test yes = "$silent" && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options that allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST - fi - - cfgfile=${ofile}T - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL -# Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. - -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit, 1996 - -_LT_COPYING -_LT_LIBTOOL_TAGS - -# Configured defaults for sys_lib_dlsearch_path munging. -: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - cat <<'_LT_EOF' >> "$cfgfile" - -# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE - -_LT_PREPARE_MUNGE_PATH_LIST -_LT_PREPARE_CC_BASENAME - -# ### END FUNCTIONS SHARED WITH CONFIGURE - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -m4_ifndef([AC_PROG_GO], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "$LT_MULTI_MODULE"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test 0 = "$_lt_result"; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS=$save_LDFLAGS - ]) - - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test yes = "$lt_cv_apple_cc_single_mod"; then - _lt_dar_single_mod='$single_module' - fi - if test yes = "$lt_cv_ld_exported_symbols_list"; then - _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' - fi - if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test yes = "$lt_cv_ld_force_load"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined - case $cc_basename in - ifort*|nagfor*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test yes = "$_lt_dar_can_shared"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" - m4_if([$1], [CXX], -[ if test yes != "$lt_cv_apple_cc_single_mod"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script that will find a shell with a builtin -# printf (that we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case $ECHO in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], - [Search for dependent libraries within DIR (or the compiler's sysroot - if not specified).])], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case $with_sysroot in #( - yes) - if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([$with_sysroot]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and where our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test no = "$enable_libtool_lock" || enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out what ABI is being produced by ac_compile, and set mode - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE=32 - ;; - *ELF-64*) - HPUX_IA64_MODE=64 - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -mips64*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - emul=elf - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - emul="${emul}32" - ;; - *64-bit*) - emul="${emul}64" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *MSB*) - emul="${emul}btsmip" - ;; - *LSB*) - emul="${emul}ltsmip" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *N32*) - emul="${emul}n32" - ;; - esac - LD="${LD-ld} -m $emul" - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. Note that the listed cases only cover the - # situations where additional linker options are needed (such as when - # doing 32-bit compilation for a host where ld defaults to 64-bit, or - # vice versa); the common cases where no linker options are needed do - # not appear in the list. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*linux*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*linux*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test yes != "$lt_cv_cc_needs_belf"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS=$SAVE_CFLAGS - fi - ;; -*-*solaris*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*|x86_64-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD=${LD-ld}_sol2 - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks=$enable_libtool_lock -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test 0 -eq "$ac_status"; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test 0 -ne "$ac_status"; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test no = "$lt_cv_ar_at_file"; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test yes = "[$]$2"; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS -]) - -if test yes = "[$]$2"; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring=ABCD - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test X`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test 17 != "$i" # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n "$lt_cv_sys_max_cmd_len"; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test yes = "$cross_compiling"; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test yes != "$enable_dlopen"; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen=load_add_on - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen=LoadLibrary - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ - lt_cv_dlopen=dyld - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - tpf*) - # Don't try to run any link tests for TPF. We know it's impossible - # because TPF is a cross-compiler, and we know how we open DSOs. - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - lt_cv_dlopen_self=no - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen=shl_load], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen=dlopen], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test no = "$lt_cv_dlopen"; then - enable_dlopen=no - else - enable_dlopen=yes - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS=$CPPFLAGS - test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS=$LDFLAGS - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS=$LIBS - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test yes = "$lt_cv_dlopen_self"; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS=$save_CPPFLAGS - LDFLAGS=$save_LDFLAGS - LIBS=$save_LIBS - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links=nottested -if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test no = "$hard_links"; then - AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", - [Define to the sub-directory where libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then - - # We can hardcode non-existent directories. - if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && - test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || - test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then - # Fast installation is not supported - enable_fast_install=no -elif test yes = "$shlibpath_overrides_runpath" || - test no = "$enable_shared"; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_PREPARE_MUNGE_PATH_LIST -# --------------------------- -# Make sure func_munge_path_list() is defined correctly. -m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], -[[# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x@S|@2 in - x) - ;; - *:) - eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" - ;; - x:*) - eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" - ;; - *) - eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" - ;; - esac -} -]])# _LT_PREPARE_PATH_LIST - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test yes = "$GCC"; then - case $host_os in - darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; - *) lt_awk_arg='/^libraries:/' ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; - *) lt_sed_strip_eq='s|=/|/|g' ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary... - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path component already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). - case "$lt_multi_os_dir; $lt_search_path_spec " in - "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) - lt_multi_os_dir= - ;; - esac - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" - elif test -n "$lt_multi_os_dir"; then - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS = " "; FS = "/|\n";} { - lt_foo = ""; - lt_count = 0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo = "/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=.so -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -AC_ARG_VAR([LT_SYS_LIBRARY_PATH], -[User-defined run-time library search path.]) - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='$libname$release$shared_ext$major' - ;; - -aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test ia64 = "$host_cpu"; then - # AIX 5 supports IA64 - library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line '#! .'. This would cause the generated library to - # depend on '.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # Using Import Files as archive members, it is possible to support - # filename-based versioning of shared library archives on AIX. While - # this would work for both with and without runtime linking, it will - # prevent static linking of such archives. So we do filename-based - # shared library versioning with .so extension only, which is used - # when both runtime linking and shared linking is enabled. - # Unfortunately, runtime linking may impact performance, so we do - # not want this to be the default eventually. Also, we use the - # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. - # To allow for filename-based versioning support, we need to create - # libNAME.so.V as an archive file, containing: - # *) an Import File, referring to the versioned filename of the - # archive as well as the shared archive member, telling the - # bitwidth (32 or 64) of that shared object, and providing the - # list of exported symbols of that shared object, eventually - # decorated with the 'weak' keyword - # *) the shared object with the F_LOADONLY flag set, to really avoid - # it being seen by the linker. - # At run time we better use the real file rather than another symlink, - # but for link time we create the symlink libNAME.so -> libNAME.so.V - - case $with_aix_soname,$aix_use_runtimelinking in - # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - aix,yes) # traditional libtool - dynamic_linker='AIX unversionable lib.so' - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - aix,no) # traditional AIX only - dynamic_linker='AIX lib.a[(]lib.so.V[)]' - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - ;; - svr4,*) # full svr4 only - dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,yes) # both, prefer svr4 - dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # unpreferred sharedlib libNAME.a needs extra handling - postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' - postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,no) # both, prefer aix - dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling - postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' - postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' - ;; - esac - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='$libname$shared_ext' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - library_names_spec='$libname.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec=$LIB - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' - soname_spec='$libname$release$major$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[23]].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - if test 32 = "$HPUX_IA64_MODE"; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - sys_lib_dlsearch_path_spec=/usr/lib/hpux32 - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - sys_lib_dlsearch_path_spec=/usr/lib/hpux64 - fi - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test yes = "$lt_cv_prog_gnu_ld"; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" - sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -linux*android*) - version_type=none # Android doesn't support versioned libraries. - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext' - soname_spec='$libname$release$shared_ext' - finish_cmds= - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Ideally, we could use ldconfig to report *all* directores which are - # searched for libraries, however this is still not possible. Aside from not - # being certain /sbin/ldconfig is available, command - # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, - # even though it is searched at run-time. Try to do the best guess by - # appending ld.so.conf contents (and includes) to the search path. - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd* | bitrig*) - version_type=sunos - sys_lib_dlsearch_path_spec=/usr/lib - need_lib_prefix=no - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - need_version=no - else - need_version=yes - fi - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -os2*) - libname_spec='$name' - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - # OS/2 can only load a DLL with a base name of 8 characters or less. - soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; - v=$($ECHO $release$versuffix | tr -d .-); - n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); - $ECHO $n$v`$shared_ext' - library_names_spec='${libname}_dll.$libext' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=BEGINLIBPATH - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test yes = "$with_gnu_ld"; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec; then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' - soname_spec='$libname$shared_ext.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=sco - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test yes = "$with_gnu_ld"; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test no = "$dynamic_linker" && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test yes = "$GCC"; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then - sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec -fi - -if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then - sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec -fi - -# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... -configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec - -# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code -func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" - -# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool -configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], - [Detected run-time system search path for libraries]) -_LT_DECL([], [configure_time_lt_sys_library_path], [2], - [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program that can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$1"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac]) -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program that can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test no = "$withval" || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test yes = "$GCC"; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return, which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD=$ac_prog - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test yes = "$with_gnu_ld"; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD=$ac_dir/$ac_prog - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i -cat conftest.i conftest.i >conftest2.i -: ${lt_DD:=$DD} -AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], -[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: -fi]) -rm -f conftest.i conftest2.i conftest.out]) -])# _LT_PATH_DD - - -# _LT_CMD_TRUNCATE -# ---------------- -# find command to truncate a binary pipe -m4_defun([_LT_CMD_TRUNCATE], -[m4_require([_LT_PATH_DD]) -AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], -[printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -lt_cv_truncate_bin= -if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" -fi -rm -f conftest.i conftest2.i conftest.out -test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) -_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], - [Command to truncate a binary pipe]) -])# _LT_CMD_TRUNCATE - - -# _LT_CHECK_MAGIC_METHOD -# ---------------------- -# how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_MAGIC_METHOD], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -AC_CACHE_CHECK([how to recognize dependent libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# 'unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# that responds to the $file_magic_cmd with a given extended regex. -# If you have 'file' or equivalent on your system and you're not sure -# whether 'pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[[4-9]]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[[45]]*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd* | bitrig*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -os2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM=$NM -else - lt_nm_to_check=${ac_tool_prefix}nm - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/$lt_tmp_nm - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the 'sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty - case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; - *) lt_bad_file=/dev/null ;; - esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in - *$lt_bad_file* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break 2 - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break 2 - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS=$lt_save_ifs - done - : ${lt_cv_path_NM=no} -fi]) -if test no != "$lt_cv_path_NM"; then - NM=$lt_cv_path_NM -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols -headers" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test : != "$DUMPBIN"; then - NM=$DUMPBIN - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh; - # decide which one to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd=$ECHO - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test yes != "$lt_cv_path_mainfest_tool"; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# _LT_DLL_DEF_P([FILE]) -# --------------------- -# True iff FILE is a Windows DLL '.def' file. -# Keep in sync with func_dll_def_p in the libtool script -AC_DEFUN([_LT_DLL_DEF_P], -[dnl - test DEF = "`$SED -n dnl - -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace - -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments - -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl - -e q dnl Only consider the first "real" line - $1`" dnl -])# _LT_DLL_DEF_P - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM=-lm) - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test yes = "$GCC"; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test ia64 = "$host_cpu"; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" - # Adjust the below global symbol transforms to fixup imported variables. - lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" - lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" - lt_c_name_lib_hook="\ - -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ - -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" -else - # Disable hooks by default. - lt_cv_sys_global_symbol_to_import= - lt_cdecl_hook= - lt_c_name_hook= - lt_c_name_lib_hook= -fi - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ -$lt_cdecl_hook\ -" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ -$lt_c_name_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" - -# Transform an extracted symbol line into symbol name with lib prefix and -# symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ -$lt_c_name_lib_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function, - # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ -" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ -" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ -" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ -" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS=conftstm.$ac_objext - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test yes = "$pipe_works"; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], - [Transform the output of nm into a list of symbols to manually relocate]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], - [The name lister interface]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test yes = "$GXX"; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - if test ia64 != "$host_cpu"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64, which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test yes = "$GCC"; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - case $cc_basename in - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64, which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms that do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ' (' and ')$', so one must not match beginning or - # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', - # as well as any symbol that contains 'd'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test yes != "$GCC"; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test yes = "$with_gnu_ld"; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test yes = "$lt_use_gnu_ld_interface"; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='$wl' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test ia64 != "$host_cpu"; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test linux-dietlibc = "$host_os"; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test no = "$tmp_diet" - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - nagfor*) # NAGFOR 5.3 - tmp_sharedflag='-Wl,-shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - tcc*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' - ;; - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then - aix_use_runtimelinking=yes - break - fi - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # traditional, no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - ;; - esac - - if test yes = "$GCC"; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag="$shared_flag "'$wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - ;; - - hpux10*) - if test yes,no = "$GCC,$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test yes,no = "$GCC,$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS=$save_LDFLAGS]) - if test yes = "$lt_cv_irix_exported_symbol"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - linux*) - case $cc_basename in - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - _LT_TAGVAR(ld_shlibs, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - osf3*) - if test yes = "$GCC"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test yes = "$GCC"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test yes = "$GCC"; then - wlarc='$wl' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='$wl' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. GCC discards it without '$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test yes = "$GCC"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test sequent = "$host_vendor"; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test sni = "$host_vendor"; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test yes,yes = "$GCC,$enable_shared"; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting $shlibpath_var if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC=$CC -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report what library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC=$lt_save_CC -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test no != "$CXX" && - ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || - (test g++ != "$CXX"))); then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_caught_CXX_error"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test yes = "$GXX"; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test yes = "$GXX"; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test yes = "$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='$wl' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - ;; - esac - - if test yes = "$GXX"; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag=$shared_flag' $wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - # The "-G" linker flag allows undefined symbols. - _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared - # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes = "$GXX"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes = "$GXX"; then - if test no = "$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test yes = "$GXX"; then - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes,no = "$GXX,$with_gnu_ld"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test yes,no = "$GXX,$with_gnu_ld"; then - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require '-G' NOT '-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - - _LT_TAGVAR(GCC, $1)=$GXX - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test yes != "$_lt_caught_CXX_error" - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case @S|@2 in - .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; - *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $prev$p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test x-L = "$p" || - test x-R = "$p"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test no = "$pre_test_object_deps_done"; then - case $prev in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)=$prev$p - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test no = "$pre_test_object_deps_done"; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)=$p - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)=$p - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test no = "$F77"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_disable_F77"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)=$G77 - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test yes != "$_lt_disable_F77" - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test no = "$FC"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_disable_FC"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test yes != "$_lt_disable_FC" - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)=$LD -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)=$LD -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code=$lt_simple_compile_test_code - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f "$lt_ac_sed" && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test 10 -lt "$lt_ac_count" && break - lt_ac_count=`expr $lt_ac_count + 1` - if test "$lt_ac_count" -gt "$lt_ac_max"; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine what file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/pcre2/m4/ltoptions.m4 b/pcre2/m4/ltoptions.m4 deleted file mode 100644 index 94b082976..000000000 --- a/pcre2/m4/ltoptions.m4 +++ /dev/null @@ -1,437 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 8 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option '$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl 'shared' nor 'disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], - [_LT_WITH_AIX_SONAME([aix])]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [1], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the 'shared' and -# 'disable-shared' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the 'static' and -# 'disable-static' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the 'fast-install' -# and 'disable-fast-install' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the 'fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the 'disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_AIX_SONAME([DEFAULT]) -# ---------------------------------- -# implement the --with-aix-soname flag, and support the `aix-soname=aix' -# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT -# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. -m4_define([_LT_WITH_AIX_SONAME], -[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl -shared_archive_member_spec= -case $host,$enable_shared in -power*-*-aix[[5-9]]*,yes) - AC_MSG_CHECKING([which variant of shared library versioning to provide]) - AC_ARG_WITH([aix-soname], - [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], - [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], - [case $withval in - aix|svr4|both) - ;; - *) - AC_MSG_ERROR([Unknown argument to --with-aix-soname]) - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname], - [AC_CACHE_VAL([lt_cv_with_aix_soname], - [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) - with_aix_soname=$lt_cv_with_aix_soname]) - AC_MSG_RESULT([$with_aix_soname]) - if test aix != "$with_aix_soname"; then - # For the AIX way of multilib, we name the shared archive member - # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', - # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. - # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, - # the AIX toolchain works better with OBJECT_MODE set (default 32). - if test 64 = "${OBJECT_MODE-32}"; then - shared_archive_member_spec=shr_64 - else - shared_archive_member_spec=shr - fi - fi - ;; -*) - with_aix_soname=aix - ;; -esac - -_LT_DECL([], [shared_archive_member_spec], [0], - [Shared archive member basename, for filename based shared library versioning on AIX])dnl -])# _LT_WITH_AIX_SONAME - -LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) -LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) -LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' -# LT_INIT options. -# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [pic_mode=m4_default([$1], [default])]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/pcre2/m4/ltsugar.m4 b/pcre2/m4/ltsugar.m4 deleted file mode 100644 index 48bc9344a..000000000 --- a/pcre2/m4/ltsugar.m4 +++ /dev/null @@ -1,124 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software -# Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59, which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/pcre2/m4/ltversion.m4 b/pcre2/m4/ltversion.m4 deleted file mode 100644 index fa04b52a3..000000000 --- a/pcre2/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# @configure_input@ - -# serial 4179 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/pcre2/m4/lt~obsolete.m4 b/pcre2/m4/lt~obsolete.m4 deleted file mode 100644 index c6b26f88f..000000000 --- a/pcre2/m4/lt~obsolete.m4 +++ /dev/null @@ -1,99 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software -# Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 5 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) -m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) -m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) -m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) -m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) -m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) -m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/pcre2/m4/pcre2_visibility.m4 b/pcre2/m4/pcre2_visibility.m4 deleted file mode 100644 index 480f2eefe..000000000 --- a/pcre2/m4/pcre2_visibility.m4 +++ /dev/null @@ -1,87 +0,0 @@ -# visibility.m4 serial 4 (gettext-0.18.2) -dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Tests whether the compiler supports the command-line option -dnl -fvisibility=hidden and the function and variable attributes -dnl __attribute__((__visibility__("hidden"))) and -dnl __attribute__((__visibility__("default"))). -dnl Does *not* test for __visibility__("protected") - which has tricky -dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on -dnl MacOS X. -dnl Does *not* test for __visibility__("internal") - which has processor -dnl dependent semantics. -dnl Does *not* test for #pragma GCC visibility push(hidden) - which is -dnl "really only recommended for legacy code". -dnl Set the variable CFLAG_VISIBILITY. -dnl Defines and sets the variable HAVE_VISIBILITY. - -dnl Modified to fit with PCRE build environment by Cristian Rodríguez. -dnl Adjusted for PCRE2 by PH - -AC_DEFUN([PCRE2_VISIBILITY], -[ - AC_REQUIRE([AC_PROG_CC]) - VISIBILITY_CFLAGS= - VISIBILITY_CXXFLAGS= - HAVE_VISIBILITY=0 - if test -n "$GCC"; then - dnl First, check whether -Werror can be added to the command line, or - dnl whether it leads to an error because of some other option that the - dnl user has put into $CC $CFLAGS $CPPFLAGS. - AC_MSG_CHECKING([whether the -Werror option is usable]) - AC_CACHE_VAL([pcre2_cv_cc_vis_werror], [ - pcre2_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[]])], - [pcre2_cv_cc_vis_werror=yes], - [pcre2_cv_cc_vis_werror=no]) - CFLAGS="$pcre2_save_CFLAGS"]) - AC_MSG_RESULT([$pcre2_cv_cc_vis_werror]) - dnl Now check whether visibility declarations are supported. - AC_MSG_CHECKING([for simple visibility declarations]) - AC_CACHE_VAL([pcre2_cv_cc_visibility], [ - pcre2_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fvisibility=hidden" - dnl We use the option -Werror and a function dummyfunc, because on some - dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning - dnl "visibility attribute not supported in this configuration; ignored" - dnl at the first function definition in every compilation unit, and we - dnl don't want to use the option in this case. - if test $pcre2_cv_cc_vis_werror = yes; then - CFLAGS="$CFLAGS -Werror" - fi - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; - extern __attribute__((__visibility__("default"))) int exportedvar; - extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); - extern __attribute__((__visibility__("default"))) int exportedfunc (void); - void dummyfunc (void) {} - ]], - [[]])], - [pcre2_cv_cc_visibility=yes], - [pcre2_cv_cc_visibility=no]) - CFLAGS="$pcre2_save_CFLAGS"]) - AC_MSG_RESULT([$pcre2_cv_cc_visibility]) - if test $pcre2_cv_cc_visibility = yes; then - VISIBILITY_CFLAGS="-fvisibility=hidden" - VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" - HAVE_VISIBILITY=1 - AC_DEFINE(PCRE2_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) - AC_DEFINE(PCRE2_EXP_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) - AC_DEFINE(PCRE2POSIX_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) - AC_DEFINE(PCRE2POSIX_EXP_DEFN, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) - fi - fi - AC_SUBST([VISIBILITY_CFLAGS]) - AC_SUBST([VISIBILITY_CXXFLAGS]) - AC_SUBST([HAVE_VISIBILITY]) - AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], - [Define to 1 if the compiler supports simple visibility declarations.]) -]) diff --git a/pcre2/missing b/pcre2/missing deleted file mode 100755 index f62bbae30..000000000 --- a/pcre2/missing +++ /dev/null @@ -1,215 +0,0 @@ -#! /bin/sh -# Common wrapper for a few potentially missing GNU programs. - -scriptversion=2013-10-28.13; # UTC - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'autom4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" - ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/pcre2/pcre2-config.in b/pcre2/pcre2-config.in deleted file mode 100644 index 932160ef5..000000000 --- a/pcre2/pcre2-config.in +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -exec_prefix_set=no - -cflags="[--cflags]" -libs= - -if test @enable_pcre2_16@ = yes ; then - libs="[--libs16] $libs" -fi - -if test @enable_pcre2_32@ = yes ; then - libs="[--libs32] $libs" -fi - -if test @enable_pcre2_8@ = yes ; then - libs="[--libs8] [--libs-posix] $libs" - cflags="$cflags [--cflags-posix]" -fi - -usage="Usage: pcre2-config [--prefix] [--exec-prefix] [--version] $libs $cflags" - -if test $# -eq 0; then - echo "${usage}" 1>&2 - exit 1 -fi - -libR= -case `uname -s` in - *SunOS*) - libR=" -R@libdir@" - ;; - *BSD*) - libR=" -Wl,-R@libdir@" - ;; -esac - -libS= -if test @libdir@ != /usr/lib ; then - libS=-L@libdir@ -fi - -while test $# -gt 0; do - case "$1" in - -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - case $1 in - --prefix=*) - prefix=$optarg - if test $exec_prefix_set = no ; then - exec_prefix=$optarg - fi - ;; - --prefix) - echo $prefix - ;; - --exec-prefix=*) - exec_prefix=$optarg - exec_prefix_set=yes - ;; - --exec-prefix) - echo $exec_prefix - ;; - --version) - echo @PACKAGE_VERSION@ - ;; - --cflags) - if test @includedir@ != /usr/include ; then - includes=-I@includedir@ - fi - echo $includes @PCRE2_STATIC_CFLAG@ - ;; - --cflags-posix) - if test @enable_pcre2_8@ = yes ; then - if test @includedir@ != /usr/include ; then - includes=-I@includedir@ - fi - echo $includes @PCRE2_STATIC_CFLAG@ - else - echo "${usage}" 1>&2 - fi - ;; - --libs-posix) - if test @enable_pcre2_8@ = yes ; then - echo $libS$libR -lpcre2posix -lpcre2-8 - else - echo "${usage}" 1>&2 - fi - ;; - --libs8) - if test @enable_pcre2_8@ = yes ; then - echo $libS$libR -lpcre2-8 - else - echo "${usage}" 1>&2 - fi - ;; - --libs16) - if test @enable_pcre2_16@ = yes ; then - echo $libS$libR -lpcre2-16 - else - echo "${usage}" 1>&2 - fi - ;; - --libs32) - if test @enable_pcre2_32@ = yes ; then - echo $libS$libR -lpcre2-32 - else - echo "${usage}" 1>&2 - fi - ;; - *) - echo "${usage}" 1>&2 - exit 1 - ;; - esac - shift -done diff --git a/pcre2/perltest.sh b/pcre2/perltest.sh deleted file mode 100755 index 9cf7b17f7..000000000 --- a/pcre2/perltest.sh +++ /dev/null @@ -1,297 +0,0 @@ -#! /bin/sh - -# Script for testing regular expressions with perl to check that PCRE2 handles -# them the same. The Perl code has to have "use utf8" and "require Encode" at -# the start when running UTF-8 tests, but *not* for non-utf8 tests. (The -# "require" would actually be OK for non-utf8-tests, but is not always -# installed, so this way the script will always run for these tests.) -# -# The desired effect is achieved by making this a shell script that passes the -# Perl script to Perl through a pipe. If the first argument is "-utf8", a -# suitable prefix is set up. -# -# The remaining arguments, if any, are passed to Perl. They are an input file -# and an output file. If there is one argument, the output is written to -# STDOUT. If Perl receives no arguments, it opens /dev/tty as input, and writes -# output to STDOUT. (I haven't found a way of getting it to use STDIN, because -# of the contorted piping input.) - -perl=perl -prefix='' -if [ $# -gt 0 -a "$1" = "-utf8" ] ; then - prefix="use utf8; require Encode;" - shift -fi - - -# The Perl script that follows has a similar specification to pcre2test, and so -# can be given identical input, except that input patterns can be followed only -# by Perl's lower case modifiers and certain other pcre2test modifiers that are -# either handled or ignored: -# -# aftertext interpreted as "print $' afterwards" -# afteralltext ignored -# dupnames ignored (Perl always allows) -# mark ignored -# no_auto_possess ignored -# no_start_optimize ignored -# ucp sets Perl's /u modifier -# utf invoke UTF-8 functionality -# -# The data lines must not have any pcre2test modifiers. They are processed as -# Perl double-quoted strings, so if they contain " $ or @ characters, these -# have to be escaped. For this reason, all such characters in the -# Perl-compatible testinput1 and testinput4 files are escaped so that they can -# be used for perltest as well as for pcre2test. The output from this script -# should be same as from pcre2test, apart from the initial identifying banner. -# -# The other testinput files are not suitable for feeding to perltest.sh, -# because they make use of the special modifiers that pcre2test uses for -# testing features of PCRE2. Some of these files also contain malformed regular -# expressions, in order to check that PCRE2 diagnoses them correctly. - -(echo "$prefix" ; cat <<'PERLEND' - -# Function for turning a string into a string of printing chars. - -sub pchars { -my($t) = ""; -if ($utf8) - { - @p = unpack('U*', $_[0]); - foreach $c (@p) - { - if ($c >= 32 && $c < 127) { $t .= chr $c; } - else { $t .= sprintf("\\x{%02x}", $c); - } - } - } -else - { - foreach $c (split(//, $_[0])) - { - if (ord $c >= 32 && ord $c < 127) { $t .= $c; } - else { $t .= sprintf("\\x%02x", ord $c); } - } - } -$t; -} - - -# Read lines from a named file or stdin and write to a named file or stdout; -# lines consist of a regular expression, in delimiters and optionally followed -# by options, followed by a set of test data, terminated by an empty line. - -# Sort out the input and output files - -if (@ARGV > 0) - { - open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; - $infile = "INFILE"; - $interact = 0; - } -else - { - open(INFILE, " 1) - { - open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; - $outfile = "OUTFILE"; - } -else { $outfile = "STDOUT"; } - -printf($outfile "Perl $] Regular Expressions\n\n"); - -# Main loop - -NEXT_RE: -for (;;) - { - printf " re> " if $interact; - last if ! ($_ = <$infile>); - printf $outfile "$_" if ! $interact; - next if ($_ =~ /^\s*$/ || $_ =~ /^#/); - - $pattern = $_; - - while ($pattern !~ /^\s*(.).*\1/s) - { - printf " > " if $interact; - last if ! ($_ = <$infile>); - printf $outfile "$_" if ! $interact; - $pattern .= $_; - } - - chomp($pattern); - $pattern =~ s/\s+$//; - - # Split the pattern from the modifiers and adjust them as necessary. - - $pattern =~ /^\s*((.).*\2)(.*)$/s; - $pat = $1; - $mod = $3; - - # The private "aftertext" modifier means "print $' afterwards". - - $showrest = ($mod =~ s/aftertext,?//); - - # "allaftertext" is used by pcre2test to print remainders after captures - - $mod =~ s/allaftertext,?//; - - # Detect utf - - $utf8 = $mod =~ s/utf,?//; - - # Remove "dupnames". - - $mod =~ s/dupnames,?//; - - # Remove "mark" (asks pcre2test to check MARK data) */ - - $mod =~ s/mark,?//; - - # "ucp" asks pcre2test to set PCRE2_UCP; change this to /u for Perl - - $mod =~ s/ucp,?/u/; - - # Remove "no_auto_possess" and "no_start_optimize" (disable PCRE2 optimizations) - - $mod =~ s/no_auto_possess,?//; - $mod =~ s/no_start_optimize,?//; - - # Add back retained modifiers and check that the pattern is valid. - - $mod =~ s/,//g; - $pattern = "$pat$mod"; - eval "\$_ =~ ${pattern}"; - if ($@) - { - printf $outfile "Error: $@"; - if (! $interact) - { - for (;;) - { - last if ! ($_ = <$infile>); - last if $_ =~ /^\s*$/; - } - } - next NEXT_RE; - } - - # If the /g modifier is present, we want to put a loop round the matching; - # otherwise just a single "if". - - $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; - - # If the pattern is actually the null string, Perl uses the most recently - # executed (and successfully compiled) regex is used instead. This is a - # nasty trap for the unwary! The PCRE2 test suite does contain null strings - # in places - if they are allowed through here all sorts of weird and - # unexpected effects happen. To avoid this, we replace such patterns with - # a non-null pattern that has the same effect. - - $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); - - # Read data lines and test them - - for (;;) - { - printf "data> " if $interact; - last NEXT_RE if ! ($_ = <$infile>); - chomp; - printf $outfile "%s", "$_\n" if ! $interact; - - s/\s+$//; # Remove trailing space - s/^\s+//; # Remove leading space - - last if ($_ eq ""); - next if $_ =~ /^\\=(?:\s|$)/; # Comment line - - $x = eval "\"$_\""; # To get escapes processed - - # Empty array for holding results, ensure $REGERROR and $REGMARK are - # unset, then do the matching. - - @subs = (); - - $pushes = "push \@subs,\$&;" . - "push \@subs,\$1;" . - "push \@subs,\$2;" . - "push \@subs,\$3;" . - "push \@subs,\$4;" . - "push \@subs,\$5;" . - "push \@subs,\$6;" . - "push \@subs,\$7;" . - "push \@subs,\$8;" . - "push \@subs,\$9;" . - "push \@subs,\$10;" . - "push \@subs,\$11;" . - "push \@subs,\$12;" . - "push \@subs,\$13;" . - "push \@subs,\$14;" . - "push \@subs,\$15;" . - "push \@subs,\$16;" . - "push \@subs,\$'; }"; - - undef $REGERROR; - undef $REGMARK; - - eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; - - if ($@) - { - printf $outfile "Error: $@\n"; - next NEXT_RE; - } - elsif (scalar(@subs) == 0) - { - printf $outfile "No match"; - if (defined $REGERROR && $REGERROR != 1) - { printf $outfile (", mark = %s", &pchars($REGERROR)); } - printf $outfile "\n"; - } - else - { - while (scalar(@subs) != 0) - { - printf $outfile (" 0: %s\n", &pchars($subs[0])); - printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; - $last_printed = 0; - for ($i = 1; $i <= 16; $i++) - { - if (defined $subs[$i]) - { - while ($last_printed++ < $i-1) - { printf $outfile ("%2d: \n", $last_printed); } - printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); - $last_printed = $i; - } - } - splice(@subs, 0, 18); - } - - # It seems that $REGMARK is not marked as UTF-8 even when use utf8 is - # set and the input pattern was a UTF-8 string. We can, however, force - # it to be so marked. - - if (defined $REGMARK && $REGMARK != 1) - { - $xx = $REGMARK; - $xx = Encode::decode_utf8($xx) if $utf8; - printf $outfile ("MK: %s\n", &pchars($xx)); - } - } - } - } - -# printf $outfile "\n"; - -PERLEND -) | $perl - $@ - -# End diff --git a/pcre2/src/config.h.generic b/pcre2/src/config.h.generic deleted file mode 100644 index 744f19898..000000000 --- a/pcre2/src/config.h.generic +++ /dev/null @@ -1,306 +0,0 @@ -/* src/config.h. Generated from config.h.in by configure. */ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* PCRE2 is written in Standard C, but there are a few non-standard things it -can cope with, allowing it to run on SunOS4 and other "close to standard" -systems. - -In environments that support the GNU autotools, config.h.in is converted into -config.h by the "configure" script. In environments that use CMake, -config-cmake.in is converted into config.h. If you are going to build PCRE2 "by -hand" without using "configure" or CMake, you should copy the distributed -config.h.generic to config.h, and edit the macro definitions to be the way you -need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, -so that config.h is included at the start of every source. - -Alternatively, you can avoid editing by using -D on the compiler command line -to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, -but if you do, default values will be taken from config.h for non-boolean -macros that are not defined on the command line. - -Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be defined -(conventionally to 1) for TRUE, and not defined at all for FALSE. All such -macros are listed as a commented #undef in config.h.generic. Macros such as -MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are -surrounded by #ifndef/#endif lines so that the value can be overridden by -D. - -PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if -HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make -sure both macros are undefined; an emulation function will then be used. */ - -/* By default, the \R escape sequence matches any Unicode line ending - character or sequence of characters. If BSR_ANYCRLF is defined (to any - value), this is changed so that backslash-R matches only CR, LF, or CRLF. - The build-time default can be overridden by the user of PCRE2 at runtime. - */ -/* #undef BSR_ANYCRLF */ - -/* If you are compiling for a system that uses EBCDIC instead of ASCII - character codes, define this macro to any value. When EBCDIC is set, PCRE2 - assumes that all input strings are in EBCDIC. If you do not define this - macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It - is not possible to build a version of PCRE2 that supports both EBCDIC and - UTF-8/16/32. */ -/* #undef EBCDIC */ - -/* In an EBCDIC environment, define this macro to any value to arrange for the - NL character to be 0x25 instead of the default 0x15. NL plays the role that - LF does in an ASCII/Unicode environment. */ -/* #undef EBCDIC_NL25 */ - -/* Define to 1 if you have the `bcopy' function. */ -/* #undef HAVE_BCOPY */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_BZLIB_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DIRENT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_EDITLINE_READLINE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_EDIT_READLINE_READLINE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIMITS_H */ - -/* Define to 1 if you have the `memmove' function. */ -/* #undef HAVE_MEMMOVE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MEMORY_H */ - -/* Define if you have POSIX threads libraries and header files. */ -/* #undef HAVE_PTHREAD */ - -/* Have PTHREAD_PRIO_INHERIT. */ -/* #undef HAVE_PTHREAD_PRIO_INHERIT */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_READLINE_HISTORY_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_READLINE_READLINE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDLIB_H */ - -/* Define to 1 if you have the `strerror' function. */ -/* #undef HAVE_STRERROR */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRING_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_STAT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define to 1 if the compiler supports simple visibility declarations. */ -/* #undef HAVE_VISIBILITY */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ZLIB_H */ - -/* PCRE2 uses recursive function calls to handle backtracking while matching. - This can sometimes be a problem on systems that have stacks of limited - size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't - use recursion in the match() function; instead it creates its own stack by - steam using memory from the heap. For more detail, see the comments and - other stuff just above the match() function. */ -/* #undef HEAP_MATCH_RECURSE */ - -/* The value of LINK_SIZE determines the number of bytes used to store links - as offsets within the compiled regex. The default is 2, which allows for - compiled patterns up to 64K long. This covers the vast majority of cases. - However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This - allows for longer patterns in extreme cases. */ -#ifndef LINK_SIZE -#define LINK_SIZE 2 -#endif - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -/* This is ignored unless you are using libtool. */ -#ifndef LT_OBJDIR -#define LT_OBJDIR ".libs/" -#endif - -/* The value of MATCH_LIMIT determines the default number of times the - internal match() function can be called during a single execution of - pcre2_match(). There is a runtime interface for setting a different limit. - The limit exists in order to catch runaway regular expressions that take - for ever to determine that they do not match. The default is set very large - so that it does not accidentally catch legitimate cases. */ -#ifndef MATCH_LIMIT -#define MATCH_LIMIT 10000000 -#endif - -/* The above limit applies to all calls of match(), whether or not they - increase the recursion depth. In some environments it is desirable to limit - the depth of recursive calls of match() more strictly, in order to restrict - the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined) - that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive - calls of match(). To have any useful effect, it must be less than the value - of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There - is a runtime method for setting a different limit. */ -#ifndef MATCH_LIMIT_RECURSION -#define MATCH_LIMIT_RECURSION MATCH_LIMIT -#endif - -/* This limit is parameterized just in case anybody ever wants to change it. - Care must be taken if it is increased, because it guards against integer - overflow caused by enormously large patterns. */ -#ifndef MAX_NAME_COUNT -#define MAX_NAME_COUNT 10000 -#endif - -/* This limit is parameterized just in case anybody ever wants to change it. - Care must be taken if it is increased, because it guards against integer - overflow caused by enormously large patterns. */ -#ifndef MAX_NAME_SIZE -#define MAX_NAME_SIZE 32 -#endif - -/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */ -/* #undef NEVER_BACKSLASH_C */ - -/* The value of NEWLINE_DEFAULT determines the default newline character - sequence. PCRE2 client programs can override this by selecting other values - at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5 - (ANYCRLF). */ -#ifndef NEWLINE_DEFAULT -#define NEWLINE_DEFAULT 2 -#endif - -/* Name of package */ -#define PACKAGE "pcre2" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "PCRE2" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE2 10.21" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "pcre2" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "10.21" - -/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested - parentheses (of any kind) in a pattern. This limits the amount of system - stack that is used while compiling a pattern. */ -#ifndef PARENS_NEST_LIMIT -#define PARENS_NEST_LIMIT 250 -#endif - -/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by - pcre2grep to hold parts of the file it is searching. This is also the - minimum value. The actual amount of memory used by pcre2grep is three times - this number, because it allows for the buffering of "before" and "after" - lines. */ -#ifndef PCRE2GREP_BUFSIZE -#define PCRE2GREP_BUFSIZE 20480 -#endif - -/* Define to any value to include debugging code. */ -/* #undef PCRE2_DEBUG */ - -/* If you are compiling for a system other than a Unix-like system or - Win32, and it needs some magic to be inserted before the definition - of a function that is exported by the library, define this macro to - contain the relevant magic. If you do not define this macro, a suitable - __declspec value is used for Windows systems; in other environments - "extern" is used for a C compiler and "extern C" for a C++ compiler. - This macro apears at the start of every exported function that is part - of the external API. It does not appear on functions that are "external" - in the C sense, but which are internal to the library. */ -/* #undef PCRE2_EXP_DEFN */ - -/* Define to any value if linking statically (TODO: make nice with Libtool) */ -/* #undef PCRE2_STATIC */ - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* Define to 1 if you have the ANSI C header files. */ -/* #undef STDC_HEADERS */ - -/* Define to any value to enable support for Just-In-Time compiling. */ -/* #undef SUPPORT_JIT */ - -/* Define to any value to allow pcre2grep to be linked with libbz2, so that it - is able to handle .bz2 files. */ -/* #undef SUPPORT_LIBBZ2 */ - -/* Define to any value to allow pcre2test to be linked with libedit. */ -/* #undef SUPPORT_LIBEDIT */ - -/* Define to any value to allow pcre2test to be linked with libreadline. */ -/* #undef SUPPORT_LIBREADLINE */ - -/* Define to any value to allow pcre2grep to be linked with libz, so that it - is able to handle .gz files. */ -/* #undef SUPPORT_LIBZ */ - -/* Define to any value to enable JIT support in pcre2grep. */ -/* #undef SUPPORT_PCRE2GREP_JIT */ - -/* Define to any value to enable the 16 bit PCRE2 library. */ -/* #undef SUPPORT_PCRE2_16 */ - -/* Define to any value to enable the 32 bit PCRE2 library. */ -/* #undef SUPPORT_PCRE2_32 */ - -/* Define to any value to enable the 8 bit PCRE2 library. */ -/* #undef SUPPORT_PCRE2_8 */ - -/* Define to any value to enable support for Unicode and UTF encoding. This - will work even in an EBCDIC environment, but it is incompatible with the - EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or* - ASCII/Unicode, but not both at once. */ -/* #undef SUPPORT_UNICODE */ - -/* Define to any value for valgrind support to find invalid memory reads. */ -/* #undef SUPPORT_VALGRIND */ - -/* Version number of package */ -#define VERSION "10.21" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int64_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ diff --git a/pcre2/src/config.h.in b/pcre2/src/config.h.in deleted file mode 100644 index e55d0a048..000000000 --- a/pcre2/src/config.h.in +++ /dev/null @@ -1,297 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - - -/* PCRE2 is written in Standard C, but there are a few non-standard things it -can cope with, allowing it to run on SunOS4 and other "close to standard" -systems. - -In environments that support the GNU autotools, config.h.in is converted into -config.h by the "configure" script. In environments that use CMake, -config-cmake.in is converted into config.h. If you are going to build PCRE2 "by -hand" without using "configure" or CMake, you should copy the distributed -config.h.generic to config.h, and edit the macro definitions to be the way you -need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, -so that config.h is included at the start of every source. - -Alternatively, you can avoid editing by using -D on the compiler command line -to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, -but if you do, default values will be taken from config.h for non-boolean -macros that are not defined on the command line. - -Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be defined -(conventionally to 1) for TRUE, and not defined at all for FALSE. All such -macros are listed as a commented #undef in config.h.generic. Macros such as -MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are -surrounded by #ifndef/#endif lines so that the value can be overridden by -D. - -PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if -HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make -sure both macros are undefined; an emulation function will then be used. */ - -/* By default, the \R escape sequence matches any Unicode line ending - character or sequence of characters. If BSR_ANYCRLF is defined (to any - value), this is changed so that backslash-R matches only CR, LF, or CRLF. - The build-time default can be overridden by the user of PCRE2 at runtime. - */ -#undef BSR_ANYCRLF - -/* If you are compiling for a system that uses EBCDIC instead of ASCII - character codes, define this macro to any value. When EBCDIC is set, PCRE2 - assumes that all input strings are in EBCDIC. If you do not define this - macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It - is not possible to build a version of PCRE2 that supports both EBCDIC and - UTF-8/16/32. */ -#undef EBCDIC - -/* In an EBCDIC environment, define this macro to any value to arrange for the - NL character to be 0x25 instead of the default 0x15. NL plays the role that - LF does in an ASCII/Unicode environment. */ -#undef EBCDIC_NL25 - -/* Define to 1 if you have the `bcopy' function. */ -#undef HAVE_BCOPY - -/* Define to 1 if you have the header file. */ -#undef HAVE_BZLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EDITLINE_READLINE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EDIT_READLINE_READLINE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the `memmove' function. */ -#undef HAVE_MEMMOVE - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Have PTHREAD_PRIO_INHERIT. */ -#undef HAVE_PTHREAD_PRIO_INHERIT - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_HISTORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_READLINE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if the compiler supports simple visibility declarations. */ -#undef HAVE_VISIBILITY - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ZLIB_H - -/* PCRE2 uses recursive function calls to handle backtracking while matching. - This can sometimes be a problem on systems that have stacks of limited - size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't - use recursion in the match() function; instead it creates its own stack by - steam using memory from the heap. For more detail, see the comments and - other stuff just above the match() function. */ -#undef HEAP_MATCH_RECURSE - -/* The value of LINK_SIZE determines the number of bytes used to store links - as offsets within the compiled regex. The default is 2, which allows for - compiled patterns up to 64K long. This covers the vast majority of cases. - However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This - allows for longer patterns in extreme cases. */ -#undef LINK_SIZE - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* The value of MATCH_LIMIT determines the default number of times the - internal match() function can be called during a single execution of - pcre2_match(). There is a runtime interface for setting a different limit. - The limit exists in order to catch runaway regular expressions that take - for ever to determine that they do not match. The default is set very large - so that it does not accidentally catch legitimate cases. */ -#undef MATCH_LIMIT - -/* The above limit applies to all calls of match(), whether or not they - increase the recursion depth. In some environments it is desirable to limit - the depth of recursive calls of match() more strictly, in order to restrict - the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined) - that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive - calls of match(). To have any useful effect, it must be less than the value - of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There - is a runtime method for setting a different limit. */ -#undef MATCH_LIMIT_RECURSION - -/* This limit is parameterized just in case anybody ever wants to change it. - Care must be taken if it is increased, because it guards against integer - overflow caused by enormously large patterns. */ -#undef MAX_NAME_COUNT - -/* This limit is parameterized just in case anybody ever wants to change it. - Care must be taken if it is increased, because it guards against integer - overflow caused by enormously large patterns. */ -#undef MAX_NAME_SIZE - -/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */ -#undef NEVER_BACKSLASH_C - -/* The value of NEWLINE_DEFAULT determines the default newline character - sequence. PCRE2 client programs can override this by selecting other values - at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5 - (ANYCRLF). */ -#undef NEWLINE_DEFAULT - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested - parentheses (of any kind) in a pattern. This limits the amount of system - stack that is used while compiling a pattern. */ -#undef PARENS_NEST_LIMIT - -/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by - pcre2grep to hold parts of the file it is searching. This is also the - minimum value. The actual amount of memory used by pcre2grep is three times - this number, because it allows for the buffering of "before" and "after" - lines. */ -#undef PCRE2GREP_BUFSIZE - -/* to make a symbol visible */ -#undef PCRE2POSIX_EXP_DECL - -/* to make a symbol visible */ -#undef PCRE2POSIX_EXP_DEFN - -/* Define to any value to include debugging code. */ -#undef PCRE2_DEBUG - -/* to make a symbol visible */ -#undef PCRE2_EXP_DECL - - -/* If you are compiling for a system other than a Unix-like system or - Win32, and it needs some magic to be inserted before the definition - of a function that is exported by the library, define this macro to - contain the relevant magic. If you do not define this macro, a suitable - __declspec value is used for Windows systems; in other environments - "extern" is used for a C compiler and "extern C" for a C++ compiler. - This macro apears at the start of every exported function that is part - of the external API. It does not appear on functions that are "external" - in the C sense, but which are internal to the library. */ -#undef PCRE2_EXP_DEFN - -/* Define to any value if linking statically (TODO: make nice with Libtool) */ -#undef PCRE2_STATIC - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to any value to enable support for Just-In-Time compiling. */ -#undef SUPPORT_JIT - -/* Define to any value to allow pcre2grep to be linked with libbz2, so that it - is able to handle .bz2 files. */ -#undef SUPPORT_LIBBZ2 - -/* Define to any value to allow pcre2test to be linked with libedit. */ -#undef SUPPORT_LIBEDIT - -/* Define to any value to allow pcre2test to be linked with libreadline. */ -#undef SUPPORT_LIBREADLINE - -/* Define to any value to allow pcre2grep to be linked with libz, so that it - is able to handle .gz files. */ -#undef SUPPORT_LIBZ - -/* Define to any value to enable JIT support in pcre2grep. */ -#undef SUPPORT_PCRE2GREP_JIT - -/* Define to any value to enable the 16 bit PCRE2 library. */ -#undef SUPPORT_PCRE2_16 - -/* Define to any value to enable the 32 bit PCRE2 library. */ -#undef SUPPORT_PCRE2_32 - -/* Define to any value to enable the 8 bit PCRE2 library. */ -#undef SUPPORT_PCRE2_8 - -/* Define to any value to enable support for Unicode and UTF encoding. This - will work even in an EBCDIC environment, but it is incompatible with the - EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or* - ASCII/Unicode, but not both at once. */ -#undef SUPPORT_UNICODE - -/* Define to any value for valgrind support to find invalid memory reads. */ -#undef SUPPORT_VALGRIND - -/* Version number of package */ -#undef VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef int64_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t diff --git a/pcre2/src/dftables.c b/pcre2/src/dftables.c deleted file mode 100644 index dfb90b594..000000000 --- a/pcre2/src/dftables.c +++ /dev/null @@ -1,214 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This is a freestanding support program to generate a file containing -character tables for PCRE2. The tables are built according to the current -locale using the pcre2_maketables() function, which is part of the PCRE2 API. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -#define PCRE2_CODE_UNIT_WIDTH 0 /* Must be set, but not relevant here */ -#include "pcre2_internal.h" - -#define DFTABLES /* pcre2_maketables.c notices this */ -#include "pcre2_maketables.c" - -int main(int argc, char **argv) -{ -FILE *f; -int i = 1; -const unsigned char *tables; -const unsigned char *base_of_tables; - -/* By default, the default C locale is used rather than what the building user -happens to have set. However, if the -L option is given, set the locale from -the LC_xxx environment variables. */ - -if (argc > 1 && strcmp(argv[1], "-L") == 0) - { - setlocale(LC_ALL, ""); /* Set from environment variables */ - i++; - } - -if (argc < i + 1) - { - fprintf(stderr, "dftables: one filename argument is required\n"); - return 1; - } - -tables = maketables(); -base_of_tables = tables; - -f = fopen(argv[i], "wb"); -if (f == NULL) - { - fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); - return 1; - } - -/* There are several fprintf() calls here, because gcc in pedantic mode -complains about the very long string otherwise. */ - -fprintf(f, - "/*************************************************\n" - "* Perl-Compatible Regular Expressions *\n" - "*************************************************/\n\n" - "/* This file was automatically written by the dftables auxiliary\n" - "program. It contains character tables that are used when no external\n" - "tables are passed to PCRE2 by the application that calls it. The tables\n" - "are used only for characters whose code values are less than 256. */\n\n"); - -/* Force config.h in z/OS */ - -#if defined NATIVE_ZOS -fprintf(f, - "/* For z/OS, config.h is forced */\n" - "#ifndef HAVE_CONFIG_H\n" - "#define HAVE_CONFIG_H 1\n" - "#endif\n\n"); -#endif - -fprintf(f, - "/* The following #includes are present because without them gcc 4.x may remove\n" - "the array definition from the final binary if PCRE2 is built into a static\n" - "library and dead code stripping is activated. This leads to link errors.\n" - "Pulling in the header ensures that the array gets flagged as \"someone\n" - "outside this compilation unit might reference this\" and so it will always\n" - "be supplied to the linker. */\n\n"); - -fprintf(f, - "#ifdef HAVE_CONFIG_H\n" - "#include \"config.h\"\n" - "#endif\n\n" - "#include \"pcre2_internal.h\"\n\n"); - -fprintf(f, - "const uint8_t PRIV(default_tables)[] = {\n\n" - "/* This table is a lower casing table. */\n\n"); - -fprintf(f, " "); -for (i = 0; i < 256; i++) - { - if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); - fprintf(f, "%3d", *tables++); - if (i != 255) fprintf(f, ","); - } -fprintf(f, ",\n\n"); - -fprintf(f, "/* This table is a case flipping table. */\n\n"); - -fprintf(f, " "); -for (i = 0; i < 256; i++) - { - if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); - fprintf(f, "%3d", *tables++); - if (i != 255) fprintf(f, ","); - } -fprintf(f, ",\n\n"); - -fprintf(f, - "/* This table contains bit maps for various character classes.\n" - "Each map is 32 bytes long and the bits run from the least\n" - "significant end of each byte. The classes that have their own\n" - "maps are: space, xdigit, digit, upper, lower, word, graph\n" - "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); - -fprintf(f, " "); -for (i = 0; i < cbit_length; i++) - { - if ((i & 7) == 0 && i != 0) - { - if ((i & 31) == 0) fprintf(f, "\n"); - fprintf(f, "\n "); - } - fprintf(f, "0x%02x", *tables++); - if (i != cbit_length - 1) fprintf(f, ","); - } -fprintf(f, ",\n\n"); - -fprintf(f, - "/* This table identifies various classes of character by individual bits:\n" - " 0x%02x white space character\n" - " 0x%02x letter\n" - " 0x%02x decimal digit\n" - " 0x%02x hexadecimal digit\n" - " 0x%02x alphanumeric or '_'\n" - " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", - ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, - ctype_meta); - -fprintf(f, " "); -for (i = 0; i < 256; i++) - { - if ((i & 7) == 0 && i != 0) - { - fprintf(f, " /* "); - if (isprint(i-8)) fprintf(f, " %c -", i-8); - else fprintf(f, "%3d-", i-8); - if (isprint(i-1)) fprintf(f, " %c ", i-1); - else fprintf(f, "%3d", i-1); - fprintf(f, " */\n "); - } - fprintf(f, "0x%02x", *tables++); - if (i != 255) fprintf(f, ","); - } - -fprintf(f, "};/* "); -if (isprint(i-8)) fprintf(f, " %c -", i-8); - else fprintf(f, "%3d-", i-8); -if (isprint(i-1)) fprintf(f, " %c ", i-1); - else fprintf(f, "%3d", i-1); -fprintf(f, " */\n\n/* End of pcre2_chartables.c */\n"); - -fclose(f); -free((void *)base_of_tables); -return 0; -} - -/* End of dftables.c */ diff --git a/pcre2/src/pcre2.h.generic b/pcre2/src/pcre2.h.generic deleted file mode 100644 index 7f9ba4f19..000000000 --- a/pcre2/src/pcre2.h.generic +++ /dev/null @@ -1,722 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* This is the public header file for the PCRE library, second API, to be -#included by applications that call PCRE2 functions. - - Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef _PCRE2_H -#define _PCRE2_H - -/* The current PCRE version information. */ - -#define PCRE2_MAJOR 10 -#define PCRE2_MINOR 21 -#define PCRE2_PRERELEASE -#define PCRE2_DATE 2016-01-12 - -/* When an application links to a PCRE DLL in Windows, the symbols that are -imported have to be identified as such. When building PCRE2, the appropriate -export setting is defined in pcre2_internal.h, which includes this file. So we -don't change existing definitions of PCRE2_EXP_DECL. */ - -#if defined(_WIN32) && !defined(PCRE2_STATIC) -# ifndef PCRE2_EXP_DECL -# define PCRE2_EXP_DECL extern __declspec(dllimport) -# endif -#endif - -/* By default, we use the standard "extern" declarations. */ - -#ifndef PCRE2_EXP_DECL -# ifdef __cplusplus -# define PCRE2_EXP_DECL extern "C" -# else -# define PCRE2_EXP_DECL extern -# endif -#endif - -/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and -uint8_t, UCHAR_MAX, etc are defined. */ - -#include -#include -#include - -/* Allow for C++ users compiling this directly. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* The following option bits can be passed to pcre2_compile(), pcre2_match(), -or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it -is passed. Put these bits at the most significant end of the options word so -others can be added next to them */ - -#define PCRE2_ANCHORED 0x80000000u -#define PCRE2_NO_UTF_CHECK 0x40000000u - -/* The following option bits can be passed only to pcre2_compile(). However, -they may affect compilation, JIT compilation, and/or interpretive execution. -The following tags indicate which: - -C alters what is compiled by pcre2_compile() -J alters what is compiled by pcre2_jit_compile() -M is inspected during pcre2_match() execution -D is inspected during pcre2_dfa_match() execution -*/ - -#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */ -#define PCRE2_ALT_BSUX 0x00000002u /* C */ -#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */ -#define PCRE2_CASELESS 0x00000008u /* C */ -#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */ -#define PCRE2_DOTALL 0x00000020u /* C */ -#define PCRE2_DUPNAMES 0x00000040u /* C */ -#define PCRE2_EXTENDED 0x00000080u /* C */ -#define PCRE2_FIRSTLINE 0x00000100u /* J M D */ -#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */ -#define PCRE2_MULTILINE 0x00000400u /* C */ -#define PCRE2_NEVER_UCP 0x00000800u /* C */ -#define PCRE2_NEVER_UTF 0x00001000u /* C */ -#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */ -#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */ -#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */ -#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */ -#define PCRE2_UCP 0x00020000u /* C J M D */ -#define PCRE2_UNGREEDY 0x00040000u /* C */ -#define PCRE2_UTF 0x00080000u /* C J M D */ -#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */ -#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */ -#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */ -#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */ - -/* These are for pcre2_jit_compile(). */ - -#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */ -#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u -#define PCRE2_JIT_PARTIAL_HARD 0x00000004u - -/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note -that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these -functions (though pcre2_jit_match() ignores the latter since it bypasses all -sanity checks). */ - -#define PCRE2_NOTBOL 0x00000001u -#define PCRE2_NOTEOL 0x00000002u -#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ -#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ -#define PCRE2_PARTIAL_SOFT 0x00000010u -#define PCRE2_PARTIAL_HARD 0x00000020u - -/* These are additional options for pcre2_dfa_match(). */ - -#define PCRE2_DFA_RESTART 0x00000040u -#define PCRE2_DFA_SHORTEST 0x00000080u - -/* These are additional options for pcre2_substitute(). */ - -#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u -#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u -#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u -#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u -#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u - -/* Newline and \R settings, for use in compile contexts. The newline values -must be kept in step with values set in config.h and both sets must all be -greater than zero. */ - -#define PCRE2_NEWLINE_CR 1 -#define PCRE2_NEWLINE_LF 2 -#define PCRE2_NEWLINE_CRLF 3 -#define PCRE2_NEWLINE_ANY 4 -#define PCRE2_NEWLINE_ANYCRLF 5 - -#define PCRE2_BSR_UNICODE 1 -#define PCRE2_BSR_ANYCRLF 2 - -/* Error codes: no match and partial match are "expected" errors. */ - -#define PCRE2_ERROR_NOMATCH (-1) -#define PCRE2_ERROR_PARTIAL (-2) - -/* Error codes for UTF-8 validity checks */ - -#define PCRE2_ERROR_UTF8_ERR1 (-3) -#define PCRE2_ERROR_UTF8_ERR2 (-4) -#define PCRE2_ERROR_UTF8_ERR3 (-5) -#define PCRE2_ERROR_UTF8_ERR4 (-6) -#define PCRE2_ERROR_UTF8_ERR5 (-7) -#define PCRE2_ERROR_UTF8_ERR6 (-8) -#define PCRE2_ERROR_UTF8_ERR7 (-9) -#define PCRE2_ERROR_UTF8_ERR8 (-10) -#define PCRE2_ERROR_UTF8_ERR9 (-11) -#define PCRE2_ERROR_UTF8_ERR10 (-12) -#define PCRE2_ERROR_UTF8_ERR11 (-13) -#define PCRE2_ERROR_UTF8_ERR12 (-14) -#define PCRE2_ERROR_UTF8_ERR13 (-15) -#define PCRE2_ERROR_UTF8_ERR14 (-16) -#define PCRE2_ERROR_UTF8_ERR15 (-17) -#define PCRE2_ERROR_UTF8_ERR16 (-18) -#define PCRE2_ERROR_UTF8_ERR17 (-19) -#define PCRE2_ERROR_UTF8_ERR18 (-20) -#define PCRE2_ERROR_UTF8_ERR19 (-21) -#define PCRE2_ERROR_UTF8_ERR20 (-22) -#define PCRE2_ERROR_UTF8_ERR21 (-23) - -/* Error codes for UTF-16 validity checks */ - -#define PCRE2_ERROR_UTF16_ERR1 (-24) -#define PCRE2_ERROR_UTF16_ERR2 (-25) -#define PCRE2_ERROR_UTF16_ERR3 (-26) - -/* Error codes for UTF-32 validity checks */ - -#define PCRE2_ERROR_UTF32_ERR1 (-27) -#define PCRE2_ERROR_UTF32_ERR2 (-28) - -/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context -functions, and serializing functions. They are in numerical order. Originally -they were in alphabetical order too, but now that PCRE2 is released, the -numbers must not be changed. */ - -#define PCRE2_ERROR_BADDATA (-29) -#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */ -#define PCRE2_ERROR_BADMAGIC (-31) -#define PCRE2_ERROR_BADMODE (-32) -#define PCRE2_ERROR_BADOFFSET (-33) -#define PCRE2_ERROR_BADOPTION (-34) -#define PCRE2_ERROR_BADREPLACEMENT (-35) -#define PCRE2_ERROR_BADUTFOFFSET (-36) -#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */ -#define PCRE2_ERROR_DFA_BADRESTART (-38) -#define PCRE2_ERROR_DFA_RECURSE (-39) -#define PCRE2_ERROR_DFA_UCOND (-40) -#define PCRE2_ERROR_DFA_UFUNC (-41) -#define PCRE2_ERROR_DFA_UITEM (-42) -#define PCRE2_ERROR_DFA_WSSIZE (-43) -#define PCRE2_ERROR_INTERNAL (-44) -#define PCRE2_ERROR_JIT_BADOPTION (-45) -#define PCRE2_ERROR_JIT_STACKLIMIT (-46) -#define PCRE2_ERROR_MATCHLIMIT (-47) -#define PCRE2_ERROR_NOMEMORY (-48) -#define PCRE2_ERROR_NOSUBSTRING (-49) -#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) -#define PCRE2_ERROR_NULL (-51) -#define PCRE2_ERROR_RECURSELOOP (-52) -#define PCRE2_ERROR_RECURSIONLIMIT (-53) -#define PCRE2_ERROR_UNAVAILABLE (-54) -#define PCRE2_ERROR_UNSET (-55) -#define PCRE2_ERROR_BADOFFSETLIMIT (-56) -#define PCRE2_ERROR_BADREPESCAPE (-57) -#define PCRE2_ERROR_REPMISSINGBRACE (-58) -#define PCRE2_ERROR_BADSUBSTITUTION (-59) -#define PCRE2_ERROR_BADSUBSPATTERN (-60) -#define PCRE2_ERROR_TOOMANYREPLACE (-61) - -/* Request types for pcre2_pattern_info() */ - -#define PCRE2_INFO_ALLOPTIONS 0 -#define PCRE2_INFO_ARGOPTIONS 1 -#define PCRE2_INFO_BACKREFMAX 2 -#define PCRE2_INFO_BSR 3 -#define PCRE2_INFO_CAPTURECOUNT 4 -#define PCRE2_INFO_FIRSTCODEUNIT 5 -#define PCRE2_INFO_FIRSTCODETYPE 6 -#define PCRE2_INFO_FIRSTBITMAP 7 -#define PCRE2_INFO_HASCRORLF 8 -#define PCRE2_INFO_JCHANGED 9 -#define PCRE2_INFO_JITSIZE 10 -#define PCRE2_INFO_LASTCODEUNIT 11 -#define PCRE2_INFO_LASTCODETYPE 12 -#define PCRE2_INFO_MATCHEMPTY 13 -#define PCRE2_INFO_MATCHLIMIT 14 -#define PCRE2_INFO_MAXLOOKBEHIND 15 -#define PCRE2_INFO_MINLENGTH 16 -#define PCRE2_INFO_NAMECOUNT 17 -#define PCRE2_INFO_NAMEENTRYSIZE 18 -#define PCRE2_INFO_NAMETABLE 19 -#define PCRE2_INFO_NEWLINE 20 -#define PCRE2_INFO_RECURSIONLIMIT 21 -#define PCRE2_INFO_SIZE 22 -#define PCRE2_INFO_HASBACKSLASHC 23 - -/* Request types for pcre2_config(). */ - -#define PCRE2_CONFIG_BSR 0 -#define PCRE2_CONFIG_JIT 1 -#define PCRE2_CONFIG_JITTARGET 2 -#define PCRE2_CONFIG_LINKSIZE 3 -#define PCRE2_CONFIG_MATCHLIMIT 4 -#define PCRE2_CONFIG_NEWLINE 5 -#define PCRE2_CONFIG_PARENSLIMIT 6 -#define PCRE2_CONFIG_RECURSIONLIMIT 7 -#define PCRE2_CONFIG_STACKRECURSE 8 -#define PCRE2_CONFIG_UNICODE 9 -#define PCRE2_CONFIG_UNICODE_VERSION 10 -#define PCRE2_CONFIG_VERSION 11 - -/* Types for code units in patterns and subject strings. */ - -typedef uint8_t PCRE2_UCHAR8; -typedef uint16_t PCRE2_UCHAR16; -typedef uint32_t PCRE2_UCHAR32; - -typedef const PCRE2_UCHAR8 *PCRE2_SPTR8; -typedef const PCRE2_UCHAR16 *PCRE2_SPTR16; -typedef const PCRE2_UCHAR32 *PCRE2_SPTR32; - -/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2, -including pattern offsets for errors and subject offsets after a match. We -define special values to indicate zero-terminated strings and unset offsets in -the offset vector (ovector). */ - -#define PCRE2_SIZE size_t -#define PCRE2_SIZE_MAX SIZE_MAX -#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0) -#define PCRE2_UNSET (~(PCRE2_SIZE)0) - -/* Generic types for opaque structures and JIT callback functions. These -declarations are defined in a macro that is expanded for each width later. */ - -#define PCRE2_TYPES_LIST \ -struct pcre2_real_general_context; \ -typedef struct pcre2_real_general_context pcre2_general_context; \ -\ -struct pcre2_real_compile_context; \ -typedef struct pcre2_real_compile_context pcre2_compile_context; \ -\ -struct pcre2_real_match_context; \ -typedef struct pcre2_real_match_context pcre2_match_context; \ -\ -struct pcre2_real_code; \ -typedef struct pcre2_real_code pcre2_code; \ -\ -struct pcre2_real_match_data; \ -typedef struct pcre2_real_match_data pcre2_match_data; \ -\ -struct pcre2_real_jit_stack; \ -typedef struct pcre2_real_jit_stack pcre2_jit_stack; \ -\ -typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *); - - -/* The structure for passing out data via the pcre_callout_function. We use a -structure so that new fields can be added on the end in future versions, -without changing the API of the function, thereby allowing old clients to work -without modification. Define the generic version in a macro; the width-specific -versions are generated from this macro below. */ - -#define PCRE2_STRUCTURE_LIST \ -typedef struct pcre2_callout_block { \ - uint32_t version; /* Identifies version of block */ \ - /* ------------------------ Version 0 ------------------------------- */ \ - uint32_t callout_number; /* Number compiled into pattern */ \ - uint32_t capture_top; /* Max current capture */ \ - uint32_t capture_last; /* Most recently closed capture */ \ - PCRE2_SIZE *offset_vector; /* The offset vector */ \ - PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \ - PCRE2_SPTR subject; /* The subject being matched */ \ - PCRE2_SIZE subject_length; /* The length of the subject */ \ - PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \ - PCRE2_SIZE current_position; /* Where we currently are in the subject */ \ - PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ - PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ - /* ------------------- Added for Version 1 -------------------------- */ \ - PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ - PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ - PCRE2_SPTR callout_string; /* String compiled into pattern */ \ - /* ------------------------------------------------------------------ */ \ -} pcre2_callout_block; \ -\ -typedef struct pcre2_callout_enumerate_block { \ - uint32_t version; /* Identifies version of block */ \ - /* ------------------------ Version 0 ------------------------------- */ \ - PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ - PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ - uint32_t callout_number; /* Number compiled into pattern */ \ - PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ - PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ - PCRE2_SPTR callout_string; /* String compiled into pattern */ \ - /* ------------------------------------------------------------------ */ \ -} pcre2_callout_enumerate_block; - - -/* List the generic forms of all other functions in macros, which will be -expanded for each width below. Start with functions that give general -information. */ - -#define PCRE2_GENERAL_INFO_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_config(uint32_t, void *); - - -/* Functions for manipulating contexts. */ - -#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_general_context *pcre2_general_context_create( \ - void *(*)(PCRE2_SIZE, void *), \ - void (*)(void *, void *), void *); \ -PCRE2_EXP_DECL void pcre2_general_context_free(pcre2_general_context *); - -#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \ -PCRE2_EXP_DECL \ - pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\ -PCRE2_EXP_DECL void pcre2_compile_context_free(pcre2_compile_context *); \ -PCRE2_EXP_DECL int pcre2_set_bsr(pcre2_compile_context *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_character_tables(pcre2_compile_context *, \ - const unsigned char *); \ -PCRE2_EXP_DECL int pcre2_set_max_pattern_length(pcre2_compile_context *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_set_newline(pcre2_compile_context *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_parens_nest_limit(pcre2_compile_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_compile_recursion_guard(\ - pcre2_compile_context *, int (*)(uint32_t, void *), \ - void *); - -#define PCRE2_MATCH_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_match_context *pcre2_match_context_copy(pcre2_match_context *); \ -PCRE2_EXP_DECL \ - pcre2_match_context *pcre2_match_context_create(pcre2_general_context *); \ -PCRE2_EXP_DECL void pcre2_match_context_free(pcre2_match_context *); \ -PCRE2_EXP_DECL int pcre2_set_callout(pcre2_match_context *, \ - int (*)(pcre2_callout_block *, void *), void *); \ -PCRE2_EXP_DECL int pcre2_set_match_limit(pcre2_match_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_offset_limit(pcre2_match_context *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_set_recursion_limit(pcre2_match_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ - pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \ - void (*)(void *, void *), void *); - - -/* Functions concerned with compiling a pattern to PCRE internal code. */ - -#define PCRE2_COMPILE_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ - int *, PCRE2_SIZE *, pcre2_compile_context *); \ -PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); - - -/* Functions that give information about a compiled pattern. */ - -#define PCRE2_PATTERN_INFO_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_pattern_info(const pcre2_code *, uint32_t, \ - void *); \ -PCRE2_EXP_DECL int pcre2_callout_enumerate(const pcre2_code *, \ - int (*)(pcre2_callout_enumerate_block *, void *), \ - void *); - - -/* Functions for running a match and inspecting the result. */ - -#define PCRE2_MATCH_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_match_data *pcre2_match_data_create(uint32_t, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_match_data *pcre2_match_data_create_from_pattern(\ - const pcre2_code *, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL int pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \ - PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *, int *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_match(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *); \ -PCRE2_EXP_DECL void pcre2_match_data_free(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SPTR pcre2_get_mark(pcre2_match_data *); \ -PCRE2_EXP_DECL uint32_t pcre2_get_ovector_count(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SIZE pcre2_get_startchar(pcre2_match_data *); - - -/* Convenience functions for handling matched substrings. */ - -#define PCRE2_SUBSTRING_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_substring_copy_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_copy_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \ -PCRE2_EXP_DECL void pcre2_substring_free(PCRE2_UCHAR *); \ -PCRE2_EXP_DECL int pcre2_substring_get_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_get_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_length_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_length_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_nametable_scan(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \ -PCRE2_EXP_DECL int pcre2_substring_number_from_name(\ - const pcre2_code *, PCRE2_SPTR); \ -PCRE2_EXP_DECL void pcre2_substring_list_free(PCRE2_SPTR *); \ -PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \ - PCRE2_UCHAR ***, PCRE2_SIZE **); - -/* Functions for serializing / deserializing compiled patterns. */ - -#define PCRE2_SERIALIZE_FUNCTIONS \ -PCRE2_EXP_DECL int32_t pcre2_serialize_encode(const pcre2_code **, \ - int32_t, uint8_t **, PCRE2_SIZE *, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL int32_t pcre2_serialize_decode(pcre2_code **, int32_t, \ - const uint8_t *, pcre2_general_context *); \ -PCRE2_EXP_DECL int32_t pcre2_serialize_get_number_of_codes(const uint8_t *); \ -PCRE2_EXP_DECL void pcre2_serialize_free(uint8_t *); - - -/* Convenience function for match + substitute. */ - -#define PCRE2_SUBSTITUTE_FUNCTION \ -PCRE2_EXP_DECL int pcre2_substitute(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \ - PCRE2_SIZE *); - - -/* Functions for JIT processing */ - -#define PCRE2_JIT_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *); \ -PCRE2_EXP_DECL void pcre2_jit_free_unused_memory(pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_jit_stack *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL void pcre2_jit_stack_assign(pcre2_match_context *, \ - pcre2_jit_callback, void *); \ -PCRE2_EXP_DECL void pcre2_jit_stack_free(pcre2_jit_stack *); - - -/* Other miscellaneous functions. */ - -#define PCRE2_OTHER_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \ -PCRE2_EXP_DECL \ - const uint8_t *pcre2_maketables(pcre2_general_context *); \ - - -/* Define macros that generate width-specific names from generic versions. The -three-level macro scheme is necessary to get the macros expanded when we want -them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for -generating three versions of everything below. After that, PCRE2_SUFFIX will be -re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as -pcre2_compile are called by application code. */ - -#define PCRE2_JOIN(a,b) a ## b -#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b) -#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH) - - -/* Data types */ - -#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR) -#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR) - -#define pcre2_code PCRE2_SUFFIX(pcre2_code_) -#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_) -#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_) - -#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_) -#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_) -#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_) -#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_) -#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_) -#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_) - - -/* Data blocks */ - -#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_) -#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_) -#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_) -#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_) -#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_) -#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_) - - -/* Functions: the complete list in alphabetical order */ - -#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) -#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) -#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) -#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) -#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_) -#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_) -#define pcre2_config PCRE2_SUFFIX(pcre2_config_) -#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_) -#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_) -#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_) -#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) -#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) -#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) -#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) -#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) -#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_) -#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_) -#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_) -#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_) -#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_) -#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_) -#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_) -#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_) -#define pcre2_match PCRE2_SUFFIX(pcre2_match_) -#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_) -#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_) -#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_) -#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_) -#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_) -#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_) -#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_) -#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_) -#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_) -#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_) -#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_) -#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_) -#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) -#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) -#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) -#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) -#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) -#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) -#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) -#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) -#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_) -#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_) -#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) -#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) -#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) -#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_) -#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_) -#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_) -#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_) -#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_) -#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_) -#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_) -#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) -#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) - - -/* Now generate all three sets of width-specific structures and function -prototypes. */ - -#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \ -PCRE2_TYPES_LIST \ -PCRE2_STRUCTURE_LIST \ -PCRE2_GENERAL_INFO_FUNCTIONS \ -PCRE2_GENERAL_CONTEXT_FUNCTIONS \ -PCRE2_COMPILE_CONTEXT_FUNCTIONS \ -PCRE2_MATCH_CONTEXT_FUNCTIONS \ -PCRE2_COMPILE_FUNCTIONS \ -PCRE2_PATTERN_INFO_FUNCTIONS \ -PCRE2_MATCH_FUNCTIONS \ -PCRE2_SUBSTRING_FUNCTIONS \ -PCRE2_SERIALIZE_FUNCTIONS \ -PCRE2_SUBSTITUTE_FUNCTION \ -PCRE2_JIT_FUNCTIONS \ -PCRE2_OTHER_FUNCTIONS - -#define PCRE2_LOCAL_WIDTH 8 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -#define PCRE2_LOCAL_WIDTH 16 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -#define PCRE2_LOCAL_WIDTH 32 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -/* Undefine the list macros; they are no longer needed. */ - -#undef PCRE2_TYPES_LIST -#undef PCRE2_STRUCTURE_LIST -#undef PCRE2_GENERAL_INFO_FUNCTIONS -#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS -#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS -#undef PCRE2_MATCH_CONTEXT_FUNCTIONS -#undef PCRE2_COMPILE_FUNCTIONS -#undef PCRE2_PATTERN_INFO_FUNCTIONS -#undef PCRE2_MATCH_FUNCTIONS -#undef PCRE2_SUBSTRING_FUNCTIONS -#undef PCRE2_SERIALIZE_FUNCTIONS -#undef PCRE2_SUBSTITUTE_FUNCTION -#undef PCRE2_JIT_FUNCTIONS -#undef PCRE2_OTHER_FUNCTIONS -#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS - -/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine -PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make -PCRE2_SUFFIX a no-op. Otherwise, generate an error. */ - -#undef PCRE2_SUFFIX -#ifndef PCRE2_CODE_UNIT_WIDTH -#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h. -#error Use 8, 16, or 32; or 0 for a multi-width application. -#else /* PCRE2_CODE_UNIT_WIDTH is defined */ -#if PCRE2_CODE_UNIT_WIDTH == 8 || \ - PCRE2_CODE_UNIT_WIDTH == 16 || \ - PCRE2_CODE_UNIT_WIDTH == 32 -#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH) -#elif PCRE2_CODE_UNIT_WIDTH == 0 -#undef PCRE2_JOIN -#undef PCRE2_GLUE -#define PCRE2_SUFFIX(a) a -#else -#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32. -#endif -#endif /* PCRE2_CODE_UNIT_WIDTH is defined */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* End of pcre2.h */ diff --git a/pcre2/src/pcre2.h.in b/pcre2/src/pcre2.h.in deleted file mode 100644 index 49f190965..000000000 --- a/pcre2/src/pcre2.h.in +++ /dev/null @@ -1,722 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* This is the public header file for the PCRE library, second API, to be -#included by applications that call PCRE2 functions. - - Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef _PCRE2_H -#define _PCRE2_H - -/* The current PCRE version information. */ - -#define PCRE2_MAJOR @PCRE2_MAJOR@ -#define PCRE2_MINOR @PCRE2_MINOR@ -#define PCRE2_PRERELEASE @PCRE2_PRERELEASE@ -#define PCRE2_DATE @PCRE2_DATE@ - -/* When an application links to a PCRE DLL in Windows, the symbols that are -imported have to be identified as such. When building PCRE2, the appropriate -export setting is defined in pcre2_internal.h, which includes this file. So we -don't change existing definitions of PCRE2_EXP_DECL. */ - -#if defined(_WIN32) && !defined(PCRE2_STATIC) -# ifndef PCRE2_EXP_DECL -# define PCRE2_EXP_DECL extern __declspec(dllimport) -# endif -#endif - -/* By default, we use the standard "extern" declarations. */ - -#ifndef PCRE2_EXP_DECL -# ifdef __cplusplus -# define PCRE2_EXP_DECL extern "C" -# else -# define PCRE2_EXP_DECL extern -# endif -#endif - -/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and -uint8_t, UCHAR_MAX, etc are defined. */ - -#include -#include -#include - -/* Allow for C++ users compiling this directly. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* The following option bits can be passed to pcre2_compile(), pcre2_match(), -or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it -is passed. Put these bits at the most significant end of the options word so -others can be added next to them */ - -#define PCRE2_ANCHORED 0x80000000u -#define PCRE2_NO_UTF_CHECK 0x40000000u - -/* The following option bits can be passed only to pcre2_compile(). However, -they may affect compilation, JIT compilation, and/or interpretive execution. -The following tags indicate which: - -C alters what is compiled by pcre2_compile() -J alters what is compiled by pcre2_jit_compile() -M is inspected during pcre2_match() execution -D is inspected during pcre2_dfa_match() execution -*/ - -#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */ -#define PCRE2_ALT_BSUX 0x00000002u /* C */ -#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */ -#define PCRE2_CASELESS 0x00000008u /* C */ -#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */ -#define PCRE2_DOTALL 0x00000020u /* C */ -#define PCRE2_DUPNAMES 0x00000040u /* C */ -#define PCRE2_EXTENDED 0x00000080u /* C */ -#define PCRE2_FIRSTLINE 0x00000100u /* J M D */ -#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */ -#define PCRE2_MULTILINE 0x00000400u /* C */ -#define PCRE2_NEVER_UCP 0x00000800u /* C */ -#define PCRE2_NEVER_UTF 0x00001000u /* C */ -#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */ -#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */ -#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */ -#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */ -#define PCRE2_UCP 0x00020000u /* C J M D */ -#define PCRE2_UNGREEDY 0x00040000u /* C */ -#define PCRE2_UTF 0x00080000u /* C J M D */ -#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */ -#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */ -#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */ -#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */ - -/* These are for pcre2_jit_compile(). */ - -#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */ -#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u -#define PCRE2_JIT_PARTIAL_HARD 0x00000004u - -/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note -that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these -functions (though pcre2_jit_match() ignores the latter since it bypasses all -sanity checks). */ - -#define PCRE2_NOTBOL 0x00000001u -#define PCRE2_NOTEOL 0x00000002u -#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ -#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ -#define PCRE2_PARTIAL_SOFT 0x00000010u -#define PCRE2_PARTIAL_HARD 0x00000020u - -/* These are additional options for pcre2_dfa_match(). */ - -#define PCRE2_DFA_RESTART 0x00000040u -#define PCRE2_DFA_SHORTEST 0x00000080u - -/* These are additional options for pcre2_substitute(). */ - -#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u -#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u -#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u -#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u -#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u - -/* Newline and \R settings, for use in compile contexts. The newline values -must be kept in step with values set in config.h and both sets must all be -greater than zero. */ - -#define PCRE2_NEWLINE_CR 1 -#define PCRE2_NEWLINE_LF 2 -#define PCRE2_NEWLINE_CRLF 3 -#define PCRE2_NEWLINE_ANY 4 -#define PCRE2_NEWLINE_ANYCRLF 5 - -#define PCRE2_BSR_UNICODE 1 -#define PCRE2_BSR_ANYCRLF 2 - -/* Error codes: no match and partial match are "expected" errors. */ - -#define PCRE2_ERROR_NOMATCH (-1) -#define PCRE2_ERROR_PARTIAL (-2) - -/* Error codes for UTF-8 validity checks */ - -#define PCRE2_ERROR_UTF8_ERR1 (-3) -#define PCRE2_ERROR_UTF8_ERR2 (-4) -#define PCRE2_ERROR_UTF8_ERR3 (-5) -#define PCRE2_ERROR_UTF8_ERR4 (-6) -#define PCRE2_ERROR_UTF8_ERR5 (-7) -#define PCRE2_ERROR_UTF8_ERR6 (-8) -#define PCRE2_ERROR_UTF8_ERR7 (-9) -#define PCRE2_ERROR_UTF8_ERR8 (-10) -#define PCRE2_ERROR_UTF8_ERR9 (-11) -#define PCRE2_ERROR_UTF8_ERR10 (-12) -#define PCRE2_ERROR_UTF8_ERR11 (-13) -#define PCRE2_ERROR_UTF8_ERR12 (-14) -#define PCRE2_ERROR_UTF8_ERR13 (-15) -#define PCRE2_ERROR_UTF8_ERR14 (-16) -#define PCRE2_ERROR_UTF8_ERR15 (-17) -#define PCRE2_ERROR_UTF8_ERR16 (-18) -#define PCRE2_ERROR_UTF8_ERR17 (-19) -#define PCRE2_ERROR_UTF8_ERR18 (-20) -#define PCRE2_ERROR_UTF8_ERR19 (-21) -#define PCRE2_ERROR_UTF8_ERR20 (-22) -#define PCRE2_ERROR_UTF8_ERR21 (-23) - -/* Error codes for UTF-16 validity checks */ - -#define PCRE2_ERROR_UTF16_ERR1 (-24) -#define PCRE2_ERROR_UTF16_ERR2 (-25) -#define PCRE2_ERROR_UTF16_ERR3 (-26) - -/* Error codes for UTF-32 validity checks */ - -#define PCRE2_ERROR_UTF32_ERR1 (-27) -#define PCRE2_ERROR_UTF32_ERR2 (-28) - -/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context -functions, and serializing functions. They are in numerical order. Originally -they were in alphabetical order too, but now that PCRE2 is released, the -numbers must not be changed. */ - -#define PCRE2_ERROR_BADDATA (-29) -#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */ -#define PCRE2_ERROR_BADMAGIC (-31) -#define PCRE2_ERROR_BADMODE (-32) -#define PCRE2_ERROR_BADOFFSET (-33) -#define PCRE2_ERROR_BADOPTION (-34) -#define PCRE2_ERROR_BADREPLACEMENT (-35) -#define PCRE2_ERROR_BADUTFOFFSET (-36) -#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */ -#define PCRE2_ERROR_DFA_BADRESTART (-38) -#define PCRE2_ERROR_DFA_RECURSE (-39) -#define PCRE2_ERROR_DFA_UCOND (-40) -#define PCRE2_ERROR_DFA_UFUNC (-41) -#define PCRE2_ERROR_DFA_UITEM (-42) -#define PCRE2_ERROR_DFA_WSSIZE (-43) -#define PCRE2_ERROR_INTERNAL (-44) -#define PCRE2_ERROR_JIT_BADOPTION (-45) -#define PCRE2_ERROR_JIT_STACKLIMIT (-46) -#define PCRE2_ERROR_MATCHLIMIT (-47) -#define PCRE2_ERROR_NOMEMORY (-48) -#define PCRE2_ERROR_NOSUBSTRING (-49) -#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) -#define PCRE2_ERROR_NULL (-51) -#define PCRE2_ERROR_RECURSELOOP (-52) -#define PCRE2_ERROR_RECURSIONLIMIT (-53) -#define PCRE2_ERROR_UNAVAILABLE (-54) -#define PCRE2_ERROR_UNSET (-55) -#define PCRE2_ERROR_BADOFFSETLIMIT (-56) -#define PCRE2_ERROR_BADREPESCAPE (-57) -#define PCRE2_ERROR_REPMISSINGBRACE (-58) -#define PCRE2_ERROR_BADSUBSTITUTION (-59) -#define PCRE2_ERROR_BADSUBSPATTERN (-60) -#define PCRE2_ERROR_TOOMANYREPLACE (-61) - -/* Request types for pcre2_pattern_info() */ - -#define PCRE2_INFO_ALLOPTIONS 0 -#define PCRE2_INFO_ARGOPTIONS 1 -#define PCRE2_INFO_BACKREFMAX 2 -#define PCRE2_INFO_BSR 3 -#define PCRE2_INFO_CAPTURECOUNT 4 -#define PCRE2_INFO_FIRSTCODEUNIT 5 -#define PCRE2_INFO_FIRSTCODETYPE 6 -#define PCRE2_INFO_FIRSTBITMAP 7 -#define PCRE2_INFO_HASCRORLF 8 -#define PCRE2_INFO_JCHANGED 9 -#define PCRE2_INFO_JITSIZE 10 -#define PCRE2_INFO_LASTCODEUNIT 11 -#define PCRE2_INFO_LASTCODETYPE 12 -#define PCRE2_INFO_MATCHEMPTY 13 -#define PCRE2_INFO_MATCHLIMIT 14 -#define PCRE2_INFO_MAXLOOKBEHIND 15 -#define PCRE2_INFO_MINLENGTH 16 -#define PCRE2_INFO_NAMECOUNT 17 -#define PCRE2_INFO_NAMEENTRYSIZE 18 -#define PCRE2_INFO_NAMETABLE 19 -#define PCRE2_INFO_NEWLINE 20 -#define PCRE2_INFO_RECURSIONLIMIT 21 -#define PCRE2_INFO_SIZE 22 -#define PCRE2_INFO_HASBACKSLASHC 23 - -/* Request types for pcre2_config(). */ - -#define PCRE2_CONFIG_BSR 0 -#define PCRE2_CONFIG_JIT 1 -#define PCRE2_CONFIG_JITTARGET 2 -#define PCRE2_CONFIG_LINKSIZE 3 -#define PCRE2_CONFIG_MATCHLIMIT 4 -#define PCRE2_CONFIG_NEWLINE 5 -#define PCRE2_CONFIG_PARENSLIMIT 6 -#define PCRE2_CONFIG_RECURSIONLIMIT 7 -#define PCRE2_CONFIG_STACKRECURSE 8 -#define PCRE2_CONFIG_UNICODE 9 -#define PCRE2_CONFIG_UNICODE_VERSION 10 -#define PCRE2_CONFIG_VERSION 11 - -/* Types for code units in patterns and subject strings. */ - -typedef uint8_t PCRE2_UCHAR8; -typedef uint16_t PCRE2_UCHAR16; -typedef uint32_t PCRE2_UCHAR32; - -typedef const PCRE2_UCHAR8 *PCRE2_SPTR8; -typedef const PCRE2_UCHAR16 *PCRE2_SPTR16; -typedef const PCRE2_UCHAR32 *PCRE2_SPTR32; - -/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2, -including pattern offsets for errors and subject offsets after a match. We -define special values to indicate zero-terminated strings and unset offsets in -the offset vector (ovector). */ - -#define PCRE2_SIZE size_t -#define PCRE2_SIZE_MAX SIZE_MAX -#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0) -#define PCRE2_UNSET (~(PCRE2_SIZE)0) - -/* Generic types for opaque structures and JIT callback functions. These -declarations are defined in a macro that is expanded for each width later. */ - -#define PCRE2_TYPES_LIST \ -struct pcre2_real_general_context; \ -typedef struct pcre2_real_general_context pcre2_general_context; \ -\ -struct pcre2_real_compile_context; \ -typedef struct pcre2_real_compile_context pcre2_compile_context; \ -\ -struct pcre2_real_match_context; \ -typedef struct pcre2_real_match_context pcre2_match_context; \ -\ -struct pcre2_real_code; \ -typedef struct pcre2_real_code pcre2_code; \ -\ -struct pcre2_real_match_data; \ -typedef struct pcre2_real_match_data pcre2_match_data; \ -\ -struct pcre2_real_jit_stack; \ -typedef struct pcre2_real_jit_stack pcre2_jit_stack; \ -\ -typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *); - - -/* The structure for passing out data via the pcre_callout_function. We use a -structure so that new fields can be added on the end in future versions, -without changing the API of the function, thereby allowing old clients to work -without modification. Define the generic version in a macro; the width-specific -versions are generated from this macro below. */ - -#define PCRE2_STRUCTURE_LIST \ -typedef struct pcre2_callout_block { \ - uint32_t version; /* Identifies version of block */ \ - /* ------------------------ Version 0 ------------------------------- */ \ - uint32_t callout_number; /* Number compiled into pattern */ \ - uint32_t capture_top; /* Max current capture */ \ - uint32_t capture_last; /* Most recently closed capture */ \ - PCRE2_SIZE *offset_vector; /* The offset vector */ \ - PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \ - PCRE2_SPTR subject; /* The subject being matched */ \ - PCRE2_SIZE subject_length; /* The length of the subject */ \ - PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \ - PCRE2_SIZE current_position; /* Where we currently are in the subject */ \ - PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ - PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ - /* ------------------- Added for Version 1 -------------------------- */ \ - PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ - PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ - PCRE2_SPTR callout_string; /* String compiled into pattern */ \ - /* ------------------------------------------------------------------ */ \ -} pcre2_callout_block; \ -\ -typedef struct pcre2_callout_enumerate_block { \ - uint32_t version; /* Identifies version of block */ \ - /* ------------------------ Version 0 ------------------------------- */ \ - PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \ - PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \ - uint32_t callout_number; /* Number compiled into pattern */ \ - PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \ - PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ - PCRE2_SPTR callout_string; /* String compiled into pattern */ \ - /* ------------------------------------------------------------------ */ \ -} pcre2_callout_enumerate_block; - - -/* List the generic forms of all other functions in macros, which will be -expanded for each width below. Start with functions that give general -information. */ - -#define PCRE2_GENERAL_INFO_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_config(uint32_t, void *); - - -/* Functions for manipulating contexts. */ - -#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_general_context *pcre2_general_context_create( \ - void *(*)(PCRE2_SIZE, void *), \ - void (*)(void *, void *), void *); \ -PCRE2_EXP_DECL void pcre2_general_context_free(pcre2_general_context *); - -#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \ -PCRE2_EXP_DECL \ - pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\ -PCRE2_EXP_DECL void pcre2_compile_context_free(pcre2_compile_context *); \ -PCRE2_EXP_DECL int pcre2_set_bsr(pcre2_compile_context *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_character_tables(pcre2_compile_context *, \ - const unsigned char *); \ -PCRE2_EXP_DECL int pcre2_set_max_pattern_length(pcre2_compile_context *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_set_newline(pcre2_compile_context *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_parens_nest_limit(pcre2_compile_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_compile_recursion_guard(\ - pcre2_compile_context *, int (*)(uint32_t, void *), \ - void *); - -#define PCRE2_MATCH_CONTEXT_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_match_context *pcre2_match_context_copy(pcre2_match_context *); \ -PCRE2_EXP_DECL \ - pcre2_match_context *pcre2_match_context_create(pcre2_general_context *); \ -PCRE2_EXP_DECL void pcre2_match_context_free(pcre2_match_context *); \ -PCRE2_EXP_DECL int pcre2_set_callout(pcre2_match_context *, \ - int (*)(pcre2_callout_block *, void *), void *); \ -PCRE2_EXP_DECL int pcre2_set_match_limit(pcre2_match_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_offset_limit(pcre2_match_context *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_set_recursion_limit(pcre2_match_context *, \ - uint32_t); \ -PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ - pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \ - void (*)(void *, void *), void *); - - -/* Functions concerned with compiling a pattern to PCRE internal code. */ - -#define PCRE2_COMPILE_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ - int *, PCRE2_SIZE *, pcre2_compile_context *); \ -PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); - - -/* Functions that give information about a compiled pattern. */ - -#define PCRE2_PATTERN_INFO_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_pattern_info(const pcre2_code *, uint32_t, \ - void *); \ -PCRE2_EXP_DECL int pcre2_callout_enumerate(const pcre2_code *, \ - int (*)(pcre2_callout_enumerate_block *, void *), \ - void *); - - -/* Functions for running a match and inspecting the result. */ - -#define PCRE2_MATCH_FUNCTIONS \ -PCRE2_EXP_DECL \ - pcre2_match_data *pcre2_match_data_create(uint32_t, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_match_data *pcre2_match_data_create_from_pattern(\ - const pcre2_code *, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL int pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \ - PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *, int *, \ - PCRE2_SIZE); \ -PCRE2_EXP_DECL int pcre2_match(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *); \ -PCRE2_EXP_DECL void pcre2_match_data_free(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SPTR pcre2_get_mark(pcre2_match_data *); \ -PCRE2_EXP_DECL uint32_t pcre2_get_ovector_count(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \ -PCRE2_EXP_DECL PCRE2_SIZE pcre2_get_startchar(pcre2_match_data *); - - -/* Convenience functions for handling matched substrings. */ - -#define PCRE2_SUBSTRING_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_substring_copy_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_copy_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \ -PCRE2_EXP_DECL void pcre2_substring_free(PCRE2_UCHAR *); \ -PCRE2_EXP_DECL int pcre2_substring_get_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_get_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_length_byname(pcre2_match_data *, \ - PCRE2_SPTR, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_length_bynumber(pcre2_match_data *, \ - uint32_t, PCRE2_SIZE *); \ -PCRE2_EXP_DECL int pcre2_substring_nametable_scan(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \ -PCRE2_EXP_DECL int pcre2_substring_number_from_name(\ - const pcre2_code *, PCRE2_SPTR); \ -PCRE2_EXP_DECL void pcre2_substring_list_free(PCRE2_SPTR *); \ -PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \ - PCRE2_UCHAR ***, PCRE2_SIZE **); - -/* Functions for serializing / deserializing compiled patterns. */ - -#define PCRE2_SERIALIZE_FUNCTIONS \ -PCRE2_EXP_DECL int32_t pcre2_serialize_encode(const pcre2_code **, \ - int32_t, uint8_t **, PCRE2_SIZE *, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL int32_t pcre2_serialize_decode(pcre2_code **, int32_t, \ - const uint8_t *, pcre2_general_context *); \ -PCRE2_EXP_DECL int32_t pcre2_serialize_get_number_of_codes(const uint8_t *); \ -PCRE2_EXP_DECL void pcre2_serialize_free(uint8_t *); - - -/* Convenience function for match + substitute. */ - -#define PCRE2_SUBSTITUTE_FUNCTION \ -PCRE2_EXP_DECL int pcre2_substitute(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \ - PCRE2_SIZE *); - - -/* Functions for JIT processing */ - -#define PCRE2_JIT_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t); \ -PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ - PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ - pcre2_match_data *, pcre2_match_context *); \ -PCRE2_EXP_DECL void pcre2_jit_free_unused_memory(pcre2_general_context *); \ -PCRE2_EXP_DECL \ - pcre2_jit_stack *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \ - pcre2_general_context *); \ -PCRE2_EXP_DECL void pcre2_jit_stack_assign(pcre2_match_context *, \ - pcre2_jit_callback, void *); \ -PCRE2_EXP_DECL void pcre2_jit_stack_free(pcre2_jit_stack *); - - -/* Other miscellaneous functions. */ - -#define PCRE2_OTHER_FUNCTIONS \ -PCRE2_EXP_DECL int pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \ -PCRE2_EXP_DECL \ - const uint8_t *pcre2_maketables(pcre2_general_context *); \ - - -/* Define macros that generate width-specific names from generic versions. The -three-level macro scheme is necessary to get the macros expanded when we want -them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for -generating three versions of everything below. After that, PCRE2_SUFFIX will be -re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as -pcre2_compile are called by application code. */ - -#define PCRE2_JOIN(a,b) a ## b -#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b) -#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH) - - -/* Data types */ - -#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR) -#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR) - -#define pcre2_code PCRE2_SUFFIX(pcre2_code_) -#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_) -#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_) - -#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_) -#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_) -#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_) -#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_) -#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_) -#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_) - - -/* Data blocks */ - -#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_) -#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_) -#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_) -#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_) -#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_) -#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_) - - -/* Functions: the complete list in alphabetical order */ - -#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) -#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) -#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) -#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) -#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_) -#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_) -#define pcre2_config PCRE2_SUFFIX(pcre2_config_) -#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_) -#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_) -#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_) -#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) -#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) -#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) -#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) -#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) -#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_) -#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_) -#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_) -#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_) -#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_) -#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_) -#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_) -#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_) -#define pcre2_match PCRE2_SUFFIX(pcre2_match_) -#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_) -#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_) -#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_) -#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_) -#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_) -#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_) -#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_) -#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_) -#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_) -#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_) -#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_) -#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_) -#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) -#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) -#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) -#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) -#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) -#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) -#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) -#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) -#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_) -#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_) -#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) -#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) -#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) -#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_) -#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_) -#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_) -#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_) -#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_) -#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_) -#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_) -#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) -#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) - - -/* Now generate all three sets of width-specific structures and function -prototypes. */ - -#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \ -PCRE2_TYPES_LIST \ -PCRE2_STRUCTURE_LIST \ -PCRE2_GENERAL_INFO_FUNCTIONS \ -PCRE2_GENERAL_CONTEXT_FUNCTIONS \ -PCRE2_COMPILE_CONTEXT_FUNCTIONS \ -PCRE2_MATCH_CONTEXT_FUNCTIONS \ -PCRE2_COMPILE_FUNCTIONS \ -PCRE2_PATTERN_INFO_FUNCTIONS \ -PCRE2_MATCH_FUNCTIONS \ -PCRE2_SUBSTRING_FUNCTIONS \ -PCRE2_SERIALIZE_FUNCTIONS \ -PCRE2_SUBSTITUTE_FUNCTION \ -PCRE2_JIT_FUNCTIONS \ -PCRE2_OTHER_FUNCTIONS - -#define PCRE2_LOCAL_WIDTH 8 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -#define PCRE2_LOCAL_WIDTH 16 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -#define PCRE2_LOCAL_WIDTH 32 -PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS -#undef PCRE2_LOCAL_WIDTH - -/* Undefine the list macros; they are no longer needed. */ - -#undef PCRE2_TYPES_LIST -#undef PCRE2_STRUCTURE_LIST -#undef PCRE2_GENERAL_INFO_FUNCTIONS -#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS -#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS -#undef PCRE2_MATCH_CONTEXT_FUNCTIONS -#undef PCRE2_COMPILE_FUNCTIONS -#undef PCRE2_PATTERN_INFO_FUNCTIONS -#undef PCRE2_MATCH_FUNCTIONS -#undef PCRE2_SUBSTRING_FUNCTIONS -#undef PCRE2_SERIALIZE_FUNCTIONS -#undef PCRE2_SUBSTITUTE_FUNCTION -#undef PCRE2_JIT_FUNCTIONS -#undef PCRE2_OTHER_FUNCTIONS -#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS - -/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine -PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make -PCRE2_SUFFIX a no-op. Otherwise, generate an error. */ - -#undef PCRE2_SUFFIX -#ifndef PCRE2_CODE_UNIT_WIDTH -#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h. -#error Use 8, 16, or 32; or 0 for a multi-width application. -#else /* PCRE2_CODE_UNIT_WIDTH is defined */ -#if PCRE2_CODE_UNIT_WIDTH == 8 || \ - PCRE2_CODE_UNIT_WIDTH == 16 || \ - PCRE2_CODE_UNIT_WIDTH == 32 -#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH) -#elif PCRE2_CODE_UNIT_WIDTH == 0 -#undef PCRE2_JOIN -#undef PCRE2_GLUE -#define PCRE2_SUFFIX(a) a -#else -#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32. -#endif -#endif /* PCRE2_CODE_UNIT_WIDTH is defined */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* End of pcre2.h */ diff --git a/pcre2/src/pcre2_auto_possess.c b/pcre2/src/pcre2_auto_possess.c deleted file mode 100644 index d4d2334d8..000000000 --- a/pcre2/src/pcre2_auto_possess.c +++ /dev/null @@ -1,1287 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains functions that scan a compiled pattern and change -repeats into possessive repeats where possible. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -#include "pcre2_internal.h" - - -/************************************************* -* Tables for auto-possessification * -*************************************************/ - -/* This table is used to check whether auto-possessification is possible -between adjacent character-type opcodes. The left-hand (repeated) opcode is -used to select the row, and the right-hand opcode is use to select the column. -A value of 1 means that auto-possessification is OK. For example, the second -value in the first row means that \D+\d can be turned into \D++\d. - -The Unicode property types (\P and \p) have to be present to fill out the table -because of what their opcode values are, but the table values should always be -zero because property types are handled separately in the code. The last four -columns apply to items that cannot be repeated, so there is no need to have -rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is -*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ - -#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1) -#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1) - -static const uint8_t autoposstab[APTROWS][APTCOLS] = { -/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */ - { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */ - { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */ - { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */ - { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */ - { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */ - { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */ - { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */ - { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */ - { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */ -}; - -/* This table is used to check whether auto-possessification is possible -between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The -left-hand (repeated) opcode is used to select the row, and the right-hand -opcode is used to select the column. The values are as follows: - - 0 Always return FALSE (never auto-possessify) - 1 Character groups are distinct (possessify if both are OP_PROP) - 2 Check character categories in the same group (general or particular) - 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP) - - 4 Check left general category vs right particular category - 5 Check right general category vs left particular category - - 6 Left alphanum vs right general category - 7 Left space vs right general category - 8 Left word vs right general category - - 9 Right alphanum vs left general category - 10 Right space vs left general category - 11 Right word vs left general category - - 12 Left alphanum vs right particular category - 13 Left space vs right particular category - 14 Left word vs right particular category - - 15 Right alphanum vs left particular category - 16 Right space vs left particular category - 17 Right word vs left particular category -*/ - -static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = { -/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */ - { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */ - { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */ - { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */ - { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ - { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */ - { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */ - { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */ - { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */ -}; - -/* This table is used to check whether auto-possessification is possible -between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one -specifies a general category and the other specifies a particular category. The -row is selected by the general category and the column by the particular -category. The value is 1 if the particular category is not part of the general -category. */ - -static const uint8_t catposstab[7][30] = { -/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */ - { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* C */ - { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */ - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */ - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */ - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */ - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */ - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 } /* Z */ -}; - -/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against -a general or particular category. The properties in each row are those -that apply to the character set in question. Duplication means that a little -unnecessary work is done when checking, but this keeps things much simpler -because they can all use the same code. For more details see the comment where -this table is used. - -Note: SPACE and PXSPACE used to be different because Perl excluded VT from -"space", but from Perl 5.18 it's included, so both categories are treated the -same here. */ - -static const uint8_t posspropstab[3][4] = { - { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */ - { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */ - { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */ -}; - - - -#ifdef SUPPORT_UNICODE -/************************************************* -* Check a character and a property * -*************************************************/ - -/* This function is called by compare_opcodes() when a property item is -adjacent to a fixed character. - -Arguments: - c the character - ptype the property type - pdata the data for the type - negated TRUE if it's a negated property (\P or \p{^) - -Returns: TRUE if auto-possessifying is OK -*/ - -static BOOL -check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata, - BOOL negated) -{ -const uint32_t *p; -const ucd_record *prop = GET_UCD(c); - -switch(ptype) - { - case PT_LAMP: - return (prop->chartype == ucp_Lu || - prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == negated; - - case PT_GC: - return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; - - case PT_PC: - return (pdata == prop->chartype) == negated; - - case PT_SC: - return (pdata == prop->script) == negated; - - /* These are specials */ - - case PT_ALNUM: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, which - means that Perl space and POSIX space are now identical. PCRE was changed - at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - return negated; - - default: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; - } - break; /* Control never reaches here */ - - case PT_WORD: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE) == negated; - - case PT_CLIST: - p = PRIV(ucd_caseless_sets) + prop->caseset; - for (;;) - { - if (c < *p) return !negated; - if (c == *p++) return negated; - } - break; /* Control never reaches here */ - } - -return FALSE; -} -#endif /* SUPPORT_UNICODE */ - - - -/************************************************* -* Base opcode of repeated opcodes * -*************************************************/ - -/* Returns the base opcode for repeated single character type opcodes. If the -opcode is not a repeated character type, it returns with the original value. - -Arguments: c opcode -Returns: base opcode for the type -*/ - -static PCRE2_UCHAR -get_repeat_base(PCRE2_UCHAR c) -{ -return (c > OP_TYPEPOSUPTO)? c : - (c >= OP_TYPESTAR)? OP_TYPESTAR : - (c >= OP_NOTSTARI)? OP_NOTSTARI : - (c >= OP_NOTSTAR)? OP_NOTSTAR : - (c >= OP_STARI)? OP_STARI : - OP_STAR; -} - - -/************************************************* -* Fill the character property list * -*************************************************/ - -/* Checks whether the code points to an opcode that can take part in auto- -possessification, and if so, fills a list with its properties. - -Arguments: - code points to start of expression - utf TRUE if in UTF mode - fcc points to the case-flipping table - list points to output list - list[0] will be filled with the opcode - list[1] will be non-zero if this opcode - can match an empty character string - list[2..7] depends on the opcode - -Returns: points to the start of the next opcode if *code is accepted - NULL if *code is not accepted -*/ - -static PCRE2_SPTR -get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc, - uint32_t *list) -{ -PCRE2_UCHAR c = *code; -PCRE2_UCHAR base; -PCRE2_SPTR end; -uint32_t chr; - -#ifdef SUPPORT_UNICODE -uint32_t *clist_dest; -const uint32_t *clist_src; -#else -(void)utf; /* Suppress "unused parameter" compiler warning */ -#endif - -list[0] = c; -list[1] = FALSE; -code++; - -if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) - { - base = get_repeat_base(c); - c -= (base - OP_STAR); - - if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO) - code += IMM2_SIZE; - - list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT && - c != OP_POSPLUS); - - switch(base) - { - case OP_STAR: - list[0] = OP_CHAR; - break; - - case OP_STARI: - list[0] = OP_CHARI; - break; - - case OP_NOTSTAR: - list[0] = OP_NOT; - break; - - case OP_NOTSTARI: - list[0] = OP_NOTI; - break; - - case OP_TYPESTAR: - list[0] = *code; - code++; - break; - } - c = list[0]; - } - -switch(c) - { - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_EXTUNI: - case OP_EODN: - case OP_EOD: - case OP_DOLL: - case OP_DOLLM: - return code; - - case OP_CHAR: - case OP_NOT: - GETCHARINCTEST(chr, code); - list[2] = chr; - list[3] = NOTACHAR; - return code; - - case OP_CHARI: - case OP_NOTI: - list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT; - GETCHARINCTEST(chr, code); - list[2] = chr; - -#ifdef SUPPORT_UNICODE - if (chr < 128 || (chr < 256 && !utf)) - list[3] = fcc[chr]; - else - list[3] = UCD_OTHERCASE(chr); -#elif defined SUPPORT_WIDE_CHARS - list[3] = (chr < 256) ? fcc[chr] : chr; -#else - list[3] = fcc[chr]; -#endif - - /* The othercase might be the same value. */ - - if (chr == list[3]) - list[3] = NOTACHAR; - else - list[4] = NOTACHAR; - return code; - -#ifdef SUPPORT_UNICODE - case OP_PROP: - case OP_NOTPROP: - if (code[0] != PT_CLIST) - { - list[2] = code[0]; - list[3] = code[1]; - return code + 2; - } - - /* Convert only if we have enough space. */ - - clist_src = PRIV(ucd_caseless_sets) + code[1]; - clist_dest = list + 2; - code += 2; - - do { - if (clist_dest >= list + 8) - { - /* Early return if there is not enough space. This should never - happen, since all clists are shorter than 5 character now. */ - list[2] = code[0]; - list[3] = code[1]; - return code; - } - *clist_dest++ = *clist_src; - } - while(*clist_src++ != NOTACHAR); - - /* All characters are stored. The terminating NOTACHAR is copied from the - clist itself. */ - - list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT; - return code; -#endif - - case OP_NCLASS: - case OP_CLASS: -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - if (c == OP_XCLASS) - end = code + GET(code, 0) - 1; - else -#endif - end = code + 32 / sizeof(PCRE2_UCHAR); - - switch(*end) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSQUERY: - list[1] = TRUE; - end++; - break; - - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - end++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - list[1] = (GET2(end, 1) == 0); - end += 1 + 2 * IMM2_SIZE; - break; - } - list[2] = (uint32_t)(end - code); - return end; - } -return NULL; /* Opcode not accepted */ -} - - - -/************************************************* -* Scan further character sets for match * -*************************************************/ - -/* Checks whether the base and the current opcode have a common character, in -which case the base cannot be possessified. - -Arguments: - code points to the byte code - utf TRUE in UTF mode - cb compile data block - base_list the data list of the base opcode - base_end the end of the data list - rec_limit points to recursion depth counter - -Returns: TRUE if the auto-possessification is possible -*/ - -static BOOL -compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb, - const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit) -{ -PCRE2_UCHAR c; -uint32_t list[8]; -const uint32_t *chr_ptr; -const uint32_t *ochr_ptr; -const uint32_t *list_ptr; -PCRE2_SPTR next_code; -#ifdef SUPPORT_WIDE_CHARS -PCRE2_SPTR xclass_flags; -#endif -const uint8_t *class_bitset; -const uint8_t *set1, *set2, *set_end; -uint32_t chr; -BOOL accepted, invert_bits; -BOOL entered_a_group = FALSE; - -if (--(*rec_limit) <= 0) return FALSE; /* Recursion has gone too deep */ - -/* Note: the base_list[1] contains whether the current opcode has a greedy -(represented by a non-zero value) quantifier. This is a different from -other character type lists, which store here that the character iterator -matches to an empty string (also represented by a non-zero value). */ - -for(;;) - { - /* All operations move the code pointer forward. - Therefore infinite recursions are not possible. */ - - c = *code; - - /* Skip over callouts */ - - if (c == OP_CALLOUT) - { - code += PRIV(OP_lengths)[c]; - continue; - } - - if (c == OP_CALLOUT_STR) - { - code += GET(code, 1 + 2*LINK_SIZE); - continue; - } - - if (c == OP_ALT) - { - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - } - - switch(c) - { - case OP_END: - case OP_KETRPOS: - /* TRUE only in greedy case. The non-greedy case could be replaced by - an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT - uses more memory, which we cannot get at this stage.) */ - - return base_list[1] != 0; - - case OP_KET: - /* If the bracket is capturing, and referenced by an OP_RECURSE, or - it is an atomic sub-pattern (assert, once, etc.) the non-greedy case - cannot be converted to a possessive form. */ - - if (base_list[1] == 0) return FALSE; - - switch(*(code - GET(code, 1))) - { - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - /* Atomic sub-patterns and assertions can always auto-possessify their - last iterator. However, if the group was entered as a result of checking - a previous iterator, this is not possible. */ - - return !entered_a_group; - } - - code += PRIV(OP_lengths)[c]; - continue; - - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRA: - case OP_CBRA: - next_code = code + GET(code, 1); - code += PRIV(OP_lengths)[c]; - - while (*next_code == OP_ALT) - { - if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit)) - return FALSE; - code = next_code + 1 + LINK_SIZE; - next_code += GET(next_code, 1); - } - - entered_a_group = TRUE; - continue; - - case OP_BRAZERO: - case OP_BRAMINZERO: - - next_code = code + 1; - if (*next_code != OP_BRA && *next_code != OP_CBRA - && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE; - - do next_code += GET(next_code, 1); while (*next_code == OP_ALT); - - /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */ - - next_code += 1 + LINK_SIZE; - if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit)) - return FALSE; - - code += PRIV(OP_lengths)[c]; - continue; - - default: - break; - } - - /* Check for a supported opcode, and load its properties. */ - - code = get_chr_property_list(code, utf, cb->fcc, list); - if (code == NULL) return FALSE; /* Unsupported */ - - /* If either opcode is a small character list, set pointers for comparing - characters from that list with another list, or with a property. */ - - if (base_list[0] == OP_CHAR) - { - chr_ptr = base_list + 2; - list_ptr = list; - } - else if (list[0] == OP_CHAR) - { - chr_ptr = list + 2; - list_ptr = base_list; - } - - /* Character bitsets can also be compared to certain opcodes. */ - - else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS -#if PCRE2_CODE_UNIT_WIDTH == 8 - /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */ - || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS)) -#endif - ) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS)) -#else - if (base_list[0] == OP_CLASS) -#endif - { - set1 = (uint8_t *)(base_end - base_list[2]); - list_ptr = list; - } - else - { - set1 = (uint8_t *)(code - list[2]); - list_ptr = base_list; - } - - invert_bits = FALSE; - switch(list_ptr[0]) - { - case OP_CLASS: - case OP_NCLASS: - set2 = (uint8_t *) - ((list_ptr == list ? code : base_end) - list_ptr[2]); - break; - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE; - if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE; - if ((*xclass_flags & XCL_MAP) == 0) - { - /* No bits are set for characters < 256. */ - if (list[1] == 0) return TRUE; - /* Might be an empty repeat. */ - continue; - } - set2 = (uint8_t *)(xclass_flags + 1); - break; -#endif - - case OP_NOT_DIGIT: - invert_bits = TRUE; - /* Fall through */ - case OP_DIGIT: - set2 = (uint8_t *)(cb->cbits + cbit_digit); - break; - - case OP_NOT_WHITESPACE: - invert_bits = TRUE; - /* Fall through */ - case OP_WHITESPACE: - set2 = (uint8_t *)(cb->cbits + cbit_space); - break; - - case OP_NOT_WORDCHAR: - invert_bits = TRUE; - /* Fall through */ - case OP_WORDCHAR: - set2 = (uint8_t *)(cb->cbits + cbit_word); - break; - - default: - return FALSE; - } - - /* Because the bit sets are unaligned bytes, we need to perform byte - comparison here. */ - - set_end = set1 + 32; - if (invert_bits) - { - do - { - if ((*set1++ & ~(*set2++)) != 0) return FALSE; - } - while (set1 < set_end); - } - else - { - do - { - if ((*set1++ & *set2++) != 0) return FALSE; - } - while (set1 < set_end); - } - - if (list[1] == 0) return TRUE; - /* Might be an empty repeat. */ - continue; - } - - /* Some property combinations also acceptable. Unicode property opcodes are - processed specially; the rest can be handled with a lookup table. */ - - else - { - uint32_t leftop, rightop; - - leftop = base_list[0]; - rightop = list[0]; - -#ifdef SUPPORT_UNICODE - accepted = FALSE; /* Always set in non-unicode case. */ - if (leftop == OP_PROP || leftop == OP_NOTPROP) - { - if (rightop == OP_EOD) - accepted = TRUE; - else if (rightop == OP_PROP || rightop == OP_NOTPROP) - { - int n; - const uint8_t *p; - BOOL same = leftop == rightop; - BOOL lisprop = leftop == OP_PROP; - BOOL risprop = rightop == OP_PROP; - BOOL bothprop = lisprop && risprop; - - /* There's a table that specifies how each combination is to be - processed: - 0 Always return FALSE (never auto-possessify) - 1 Character groups are distinct (possessify if both are OP_PROP) - 2 Check character categories in the same group (general or particular) - 3 Return TRUE if the two opcodes are not the same - ... see comments below - */ - - n = propposstab[base_list[2]][list[2]]; - switch(n) - { - case 0: break; - case 1: accepted = bothprop; break; - case 2: accepted = (base_list[3] == list[3]) != same; break; - case 3: accepted = !same; break; - - case 4: /* Left general category, right particular category */ - accepted = risprop && catposstab[base_list[3]][list[3]] == same; - break; - - case 5: /* Right general category, left particular category */ - accepted = lisprop && catposstab[list[3]][base_list[3]] == same; - break; - - /* This code is logically tricky. Think hard before fiddling with it. - The posspropstab table has four entries per row. Each row relates to - one of PCRE's special properties such as ALNUM or SPACE or WORD. - Only WORD actually needs all four entries, but using repeats for the - others means they can all use the same code below. - - The first two entries in each row are Unicode general categories, and - apply always, because all the characters they include are part of the - PCRE character set. The third and fourth entries are a general and a - particular category, respectively, that include one or more relevant - characters. One or the other is used, depending on whether the check - is for a general or a particular category. However, in both cases the - category contains more characters than the specials that are defined - for the property being tested against. Therefore, it cannot be used - in a NOTPROP case. - - Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po. - Underscore is covered by ucp_P or ucp_Po. */ - - case 6: /* Left alphanum vs right general category */ - case 7: /* Left space vs right general category */ - case 8: /* Left word vs right general category */ - p = posspropstab[n-6]; - accepted = risprop && lisprop == - (list[3] != p[0] && - list[3] != p[1] && - (list[3] != p[2] || !lisprop)); - break; - - case 9: /* Right alphanum vs left general category */ - case 10: /* Right space vs left general category */ - case 11: /* Right word vs left general category */ - p = posspropstab[n-9]; - accepted = lisprop && risprop == - (base_list[3] != p[0] && - base_list[3] != p[1] && - (base_list[3] != p[2] || !risprop)); - break; - - case 12: /* Left alphanum vs right particular category */ - case 13: /* Left space vs right particular category */ - case 14: /* Left word vs right particular category */ - p = posspropstab[n-12]; - accepted = risprop && lisprop == - (catposstab[p[0]][list[3]] && - catposstab[p[1]][list[3]] && - (list[3] != p[3] || !lisprop)); - break; - - case 15: /* Right alphanum vs left particular category */ - case 16: /* Right space vs left particular category */ - case 17: /* Right word vs left particular category */ - p = posspropstab[n-15]; - accepted = lisprop && risprop == - (catposstab[p[0]][base_list[3]] && - catposstab[p[1]][base_list[3]] && - (base_list[3] != p[3] || !risprop)); - break; - } - } - } - - else -#endif /* SUPPORT_UNICODE */ - - accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP && - rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP && - autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP]; - - if (!accepted) return FALSE; - - if (list[1] == 0) return TRUE; - /* Might be an empty repeat. */ - continue; - } - - /* Control reaches here only if one of the items is a small character list. - All characters are checked against the other side. */ - - do - { - chr = *chr_ptr; - - switch(list_ptr[0]) - { - case OP_CHAR: - ochr_ptr = list_ptr + 2; - do - { - if (chr == *ochr_ptr) return FALSE; - ochr_ptr++; - } - while(*ochr_ptr != NOTACHAR); - break; - - case OP_NOT: - ochr_ptr = list_ptr + 2; - do - { - if (chr == *ochr_ptr) - break; - ochr_ptr++; - } - while(*ochr_ptr != NOTACHAR); - if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */ - break; - - /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not* - set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ - - case OP_DIGIT: - if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE; - break; - - case OP_NOT_DIGIT: - if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE; - break; - - case OP_WHITESPACE: - if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE; - break; - - case OP_NOT_WHITESPACE: - if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE; - break; - - case OP_WORDCHAR: - if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE; - break; - - case OP_NOT_WORDCHAR: - if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE; - break; - - case OP_HSPACE: - switch(chr) - { - HSPACE_CASES: return FALSE; - default: break; - } - break; - - case OP_NOT_HSPACE: - switch(chr) - { - HSPACE_CASES: break; - default: return FALSE; - } - break; - - case OP_ANYNL: - case OP_VSPACE: - switch(chr) - { - VSPACE_CASES: return FALSE; - default: break; - } - break; - - case OP_NOT_VSPACE: - switch(chr) - { - VSPACE_CASES: break; - default: return FALSE; - } - break; - - case OP_DOLL: - case OP_EODN: - switch (chr) - { - case CHAR_CR: - case CHAR_LF: - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - return FALSE; - } - break; - - case OP_EOD: /* Can always possessify before \z */ - break; - -#ifdef SUPPORT_UNICODE - case OP_PROP: - case OP_NOTPROP: - if (!check_char_prop(chr, list_ptr[2], list_ptr[3], - list_ptr[0] == OP_NOTPROP)) - return FALSE; - break; -#endif - - case OP_NCLASS: - if (chr > 255) return FALSE; - /* Fall through */ - - case OP_CLASS: - if (chr > 255) break; - class_bitset = (uint8_t *) - ((list_ptr == list ? code : base_end) - list_ptr[2]); - if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE; - break; - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) - - list_ptr[2] + LINK_SIZE, utf)) return FALSE; - break; -#endif - - default: - return FALSE; - } - - chr_ptr++; - } - while(*chr_ptr != NOTACHAR); - - /* At least one character must be matched from this opcode. */ - - if (list[1] == 0) return TRUE; - } - -/* Control never reaches here. There used to be a fail-save return FALSE; here, -but some compilers complain about an unreachable statement. */ -} - - - -/************************************************* -* Scan compiled regex for auto-possession * -*************************************************/ - -/* Replaces single character iterations with their possessive alternatives -if appropriate. This function modifies the compiled opcode! Hitting a -non-existant opcode may indicate a bug in PCRE2, but it can also be caused if a -bad UTF string was compiled with PCRE2_NO_UTF_CHECK. - -Arguments: - code points to start of the byte code - utf TRUE in UTF mode - cb compile data block - -Returns: 0 for success - -1 if a non-existant opcode is encountered -*/ - -int -PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb) -{ -register PCRE2_UCHAR c; -PCRE2_SPTR end; -PCRE2_UCHAR *repeat_opcode; -uint32_t list[8]; -int rec_limit; - -for (;;) - { - c = *code; - - if (c > OP_TABLE_LENGTH) return -1; /* Something gone wrong */ - - if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) - { - c -= get_repeat_base(c) - OP_STAR; - end = (c <= OP_MINUPTO) ? - get_chr_property_list(code, utf, cb->fcc, list) : NULL; - list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO; - - rec_limit = 1000; - if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit)) - { - switch(c) - { - case OP_STAR: - *code += OP_POSSTAR - OP_STAR; - break; - - case OP_MINSTAR: - *code += OP_POSSTAR - OP_MINSTAR; - break; - - case OP_PLUS: - *code += OP_POSPLUS - OP_PLUS; - break; - - case OP_MINPLUS: - *code += OP_POSPLUS - OP_MINPLUS; - break; - - case OP_QUERY: - *code += OP_POSQUERY - OP_QUERY; - break; - - case OP_MINQUERY: - *code += OP_POSQUERY - OP_MINQUERY; - break; - - case OP_UPTO: - *code += OP_POSUPTO - OP_UPTO; - break; - - case OP_MINUPTO: - *code += OP_POSUPTO - OP_MINUPTO; - break; - } - } - c = *code; - } - else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS) - { -#ifdef SUPPORT_WIDE_CHARS - if (c == OP_XCLASS) - repeat_opcode = code + GET(code, 1); - else -#endif - repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); - - c = *repeat_opcode; - if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) - { - /* end must not be NULL. */ - end = get_chr_property_list(code, utf, cb->fcc, list); - - list[1] = (c & 1) == 0; - - rec_limit = 1000; - if (compare_opcodes(end, utf, cb, list, end, &rec_limit)) - { - switch (c) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - *repeat_opcode = OP_CRPOSSTAR; - break; - - case OP_CRPLUS: - case OP_CRMINPLUS: - *repeat_opcode = OP_CRPOSPLUS; - break; - - case OP_CRQUERY: - case OP_CRMINQUERY: - *repeat_opcode = OP_CRPOSQUERY; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - *repeat_opcode = OP_CRPOSRANGE; - break; - } - } - } - c = *code; - } - - switch(c) - { - case OP_END: - return 0; - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; - break; - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; - break; - - case OP_CALLOUT_STR: - code += GET(code, 1 + 2*LINK_SIZE); - break; - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - code += GET(code, 1); - break; -#endif - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - code += code[1]; - break; - } - - /* Add in the fixed length from the table */ - - code += PRIV(OP_lengths)[c]; - - /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be - followed by a multi-byte character. The length in the table is a minimum, so - we have to arrange to skip the extra code units. */ - -#ifdef MAYBE_UTF_MULTI - if (utf) switch(c) - { - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_UPTO: - case OP_MINUPTO: - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); - break; - } -#else - (void)(utf); /* Keep compiler happy by referencing function argument */ -#endif /* SUPPORT_WIDE_CHARS */ - } -} - -/* End of pcre2_auto_possess.c */ diff --git a/pcre2/src/pcre2_chartables.c.dist b/pcre2/src/pcre2_chartables.c.dist deleted file mode 100644 index 203cb1a4a..000000000 --- a/pcre2/src/pcre2_chartables.c.dist +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* This file contains character tables that are used when no external tables -are passed to PCRE2 by the application that calls it. The tables are used only -for characters whose code values are less than 256. - -This is a default version of the tables that assumes ASCII encoding. A program -called dftables (which is distributed with PCRE2) can be used to build -alternative versions of this file. This is necessary if you are running in an -EBCDIC environment, or if you want to default to a different encoding, for -example ISO-8859-1. When dftables is run, it creates these tables in the -current locale. If PCRE2 is configured with --enable-rebuild-chartables, this -happens automatically. - -The following #includes are present because without them gcc 4.x may remove the -array definition from the final binary if PCRE2 is built into a static library -and dead code stripping is activated. This leads to link errors. Pulling in the -header ensures that the array gets flagged as "someone outside this compilation -unit might reference this" and so it will always be supplied to the linker. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - -const uint8_t PRIV(default_tables)[] = { - -/* This table is a lower casing table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table is a case flipping table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table contains bit maps for various character classes. Each map is 32 -bytes long and the bits run from the least significant end of each byte. The -classes that have their own maps are: space, xdigit, digit, upper, lower, word, -graph, print, punct, and cntrl. Other classes are built from combinations. */ - - 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, - 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - -/* This table identifies various classes of character by individual bits: - 0x01 white space character - 0x02 letter - 0x04 decimal digit - 0x08 hexadecimal digit - 0x10 alphanumeric or '_' - 0x80 regular expression metacharacter or binary zero -*/ - - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ - 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ - 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ - 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ - 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ - 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ - -/* End of pcre2_chartables.c */ diff --git a/pcre2/src/pcre2_compile.c b/pcre2/src/pcre2_compile.c deleted file mode 100644 index 876109036..000000000 --- a/pcre2/src/pcre2_compile.c +++ /dev/null @@ -1,9018 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define NLBLOCK cb /* Block containing newline information */ -#define PSSTART start_pattern /* Field containing processed string start */ -#define PSEND end_pattern /* Field containing processed string end */ - -#include "pcre2_internal.h" - -/* In rare error cases debugging might require calling pcre2_printint(). */ - -#if 0 -#ifdef EBCDIC -#define PRINTABLE(c) ((c) >= 64 && (c) < 255) -#else -#define PRINTABLE(c) ((c) >= 32 && (c) < 127) -#endif -#include "pcre2_printint.c" -#define CALL_PRINTINT -#endif - -/* There are a few things that vary with different code unit sizes. Handle them -by defining macros in order to minimize #if usage. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define STRING_UTFn_RIGHTPAR STRING_UTF8_RIGHTPAR, 5 -#define XDIGIT(c) xdigitab[c] - -#else /* Either 16-bit or 32-bit */ -#define XDIGIT(c) (MAX_255(c)? xdigitab[c] : 0xff) - -#if PCRE2_CODE_UNIT_WIDTH == 16 -#define STRING_UTFn_RIGHTPAR STRING_UTF16_RIGHTPAR, 6 - -#else /* 32-bit */ -#define STRING_UTFn_RIGHTPAR STRING_UTF32_RIGHTPAR, 6 -#endif -#endif - -/* Function definitions to allow mutual recursion */ - -static int - add_list_to_class(uint8_t *, PCRE2_UCHAR **, uint32_t, compile_block *, - const uint32_t *, unsigned int); - -static BOOL - compile_regex(uint32_t, PCRE2_UCHAR **, PCRE2_SPTR *, int *, BOOL, BOOL, - uint32_t, int, uint32_t *, int32_t *, uint32_t *, int32_t *, - branch_chain *, compile_block *, size_t *); - - - -/************************************************* -* Code parameters and static tables * -*************************************************/ - -/* This value specifies the size of stack workspace, which is used in different -ways in the different pattern scans. The group-identifying pre-scan uses it to -handle nesting, and needs it to be 16-bit aligned. - -During the first compiling phase, when determining how much memory is required, -the regex is partly compiled into this space, but the compiled parts are -discarded as soon as they can be, so that hopefully there will never be an -overrun. The code does, however, check for an overrun, which can occur for -pathological patterns. The size of the workspace depends on LINK_SIZE because -the length of compiled items varies with this. - -In the real compile phase, the workspace is used for remembering data about -numbered groups, provided there are not too many of them (if there are, extra -memory is acquired). For this phase the memory must be 32-bit aligned. Having -defined the size in code units, we set up C32_WORK_SIZE as the number of -elements in the 32-bit vector. */ - -#define COMPILE_WORK_SIZE (2048*LINK_SIZE) /* Size in code units */ - -#define C32_WORK_SIZE \ - ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint32_t)) - -/* The overrun tests check for a slightly smaller size so that they detect the -overrun before it actually does run off the end of the data block. */ - -#define WORK_SIZE_SAFETY_MARGIN (100) - -/* This value determines the size of the initial vector that is used for -remembering named groups during the pre-compile. It is allocated on the stack, -but if it is too small, it is expanded, in a similar way to the workspace. The -value is the number of slots in the list. */ - -#define NAMED_GROUP_LIST_SIZE 20 - -/* The original PCRE required patterns to be zero-terminated, and it simplifies -the compiling code if it is guaranteed that there is a zero code unit at the -end of the pattern, because this means that tests for coding sequences such as -(*SKIP) or even just (?<= can check a sequence of code units without having to -keep checking for the end of the pattern. The new PCRE2 API allows zero code -units within patterns if a positive length is given, but in order to keep most -of the compiling code as it was, we copy such patterns and add a zero on the -end. This value determines the size of space on the stack that is used if the -pattern fits; if not, heap memory is used. */ - -#define COPIED_PATTERN_SIZE 1024 - -/* Maximum length value to check against when making sure that the variable -that holds the compiled pattern length does not overflow. We make it a bit less -than INT_MAX to allow for adding in group terminating bytes, so that we don't -have to check them every time. */ - -#define OFLOW_MAX (INT_MAX - 20) - -/* Macro for setting individual bits in class bitmaps. */ - -#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7)) - -/* Private flags added to firstcu and reqcu. */ - -#define REQ_CASELESS (1 << 0) /* Indicates caselessness */ -#define REQ_VARY (1 << 1) /* reqcu followed non-literal item */ -/* Negative values for the firstcu and reqcu flags */ -#define REQ_UNSET (-2) /* Not yet found anything */ -#define REQ_NONE (-1) /* Found not fixed char */ - -/* These flags are used in the groupinfo vector. */ - -#define GI_SET_COULD_BE_EMPTY 0x80000000u -#define GI_COULD_BE_EMPTY 0x40000000u -#define GI_NOT_FIXED_LENGTH 0x20000000u -#define GI_SET_FIXED_LENGTH 0x10000000u -#define GI_FIXED_LENGTH_MASK 0x0000ffffu - -/* This bit (which is greater than any UTF value) is used to indicate that a -variable contains a number of code units instead of an actual code point. */ - -#define UTF_LENGTH 0x10000000l - -/* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC -and is fast (a good compiler can turn it into a subtraction and unsigned -comparison). */ - -#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9) - -/* Table to identify hex digits. The tables in chartables are dependent on the -locale, and may mark arbitrary characters as digits. We want to recognize only -0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It -costs 256 bytes, but it is a lot faster than doing character value tests (at -least in some simple cases I timed), and in some applications one wants PCRE to -compile efficiently as well as match efficiently. The value in the table is -the binary hex digit value, or 0xff for non-hex digits. */ - -/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in -UTF-8 mode. */ - -#ifndef EBCDIC -static const uint8_t xdigitab[] = - { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - ' */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ( - / */ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 */ - 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /* 8 - ? */ - 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* @ - G */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H - O */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* P - W */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* X - _ */ - 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* ` - g */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h - o */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* p - w */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* x -127 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */ - -#else - -/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ - -static const uint8_t xdigitab[] = - { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 10 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 32- 39 20 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 40- 47 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 48- 55 30 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 56- 63 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - 71 40 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 72- | */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* & - 87 50 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 88- 95 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - -103 60 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ? */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- " */ - 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g 80 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h -143 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p 90 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* q -159 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x A0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* y -175 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ^ -183 B0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */ - 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* { - G C0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H -207 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* } - P D0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Q -223 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* \ - X E0 */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Y -239 */ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 F0 */ - 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/* 8 -255 */ -#endif /* EBCDIC */ - - -/* Table for handling alphanumeric escaped characters. Positive returns are -simple data values; negative values are for special things like \d and so on. -Zero means further processing is needed (for things like \x), or the escape is -invalid. */ - -/* This is the "normal" table for ASCII systems or for EBCDIC systems running -in UTF-8 mode. It runs from '0' to 'z'. */ - -#ifndef EBCDIC -#define ESCAPES_FIRST CHAR_0 -#define ESCAPES_LAST CHAR_z -#define UPPER_CASE(c) (c-32) - -static const short int escapes[] = { - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - CHAR_COLON, CHAR_SEMICOLON, - CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, - CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK, - CHAR_COMMERCIAL_AT, -ESC_A, - -ESC_B, -ESC_C, - -ESC_D, -ESC_E, - 0, -ESC_G, - -ESC_H, 0, - 0, -ESC_K, - 0, 0, - -ESC_N, 0, - -ESC_P, -ESC_Q, - -ESC_R, -ESC_S, - 0, 0, - -ESC_V, -ESC_W, - -ESC_X, 0, - -ESC_Z, CHAR_LEFT_SQUARE_BRACKET, - CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET, - CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE, - CHAR_GRAVE_ACCENT, ESC_a, - -ESC_b, 0, - -ESC_d, ESC_e, - ESC_f, 0, - -ESC_h, 0, - 0, -ESC_k, - 0, 0, - ESC_n, 0, - -ESC_p, 0, - ESC_r, -ESC_s, - ESC_tee, 0, - -ESC_v, -ESC_w, - 0, 0, - -ESC_z -}; - -#else - -/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. -It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code -is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a -because it is defined as 'a', which of course picks up the ASCII value. */ - -#if 'a' == 0x81 /* Check for a real EBCDIC environment */ -#define ESCAPES_FIRST CHAR_a -#define ESCAPES_LAST CHAR_9 -#define UPPER_CASE(c) (c+64) -#else /* Testing in an ASCII environment */ -#define ESCAPES_FIRST ((unsigned char)'\x81') /* EBCDIC 'a' */ -#define ESCAPES_LAST ((unsigned char)'\xf9') /* EBCDIC '9' */ -#define UPPER_CASE(c) (c-32) -#endif - -static const short int escapes[] = { -/* 80 */ ESC_a, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, -/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0, -/* 90 */ 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p, -/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, -/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0, -/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, -/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, -/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', -/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, -/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0, -/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P, -/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0, -/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X, -/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, -/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, -/* F8 */ 0, 0 -}; - -/* We also need a table of characters that may follow \c in an EBCDIC -environment for characters 0-31. */ - -static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; - -#endif /* EBCDIC */ - - -/* Table of special "verbs" like (*PRUNE). This is a short table, so it is -searched linearly. Put all the names into a single string, in order to reduce -the number of relocations when a shared library is dynamically linked. The -string is built from string macros so that it works in UTF-8 mode on EBCDIC -platforms. */ - -typedef struct verbitem { - int len; /* Length of verb name */ - int op; /* Op when no arg, or -1 if arg mandatory */ - int op_arg; /* Op when arg present, or -1 if not allowed */ -} verbitem; - -static const char verbnames[] = - "\0" /* Empty name is a shorthand for MARK */ - STRING_MARK0 - STRING_ACCEPT0 - STRING_COMMIT0 - STRING_F0 - STRING_FAIL0 - STRING_PRUNE0 - STRING_SKIP0 - STRING_THEN; - -static const verbitem verbs[] = { - { 0, -1, OP_MARK }, - { 4, -1, OP_MARK }, - { 6, OP_ACCEPT, -1 }, - { 6, OP_COMMIT, -1 }, - { 1, OP_FAIL, -1 }, - { 4, OP_FAIL, -1 }, - { 5, OP_PRUNE, OP_PRUNE_ARG }, - { 4, OP_SKIP, OP_SKIP_ARG }, - { 4, OP_THEN, OP_THEN_ARG } -}; - -static const int verbcount = sizeof(verbs)/sizeof(verbitem); - - -/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in -another regex library. */ - -static const PCRE2_UCHAR sub_start_of_word[] = { - CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, - CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' }; - -static const PCRE2_UCHAR sub_end_of_word[] = { - CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, - CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, - CHAR_RIGHT_PARENTHESIS, '\0' }; - - -/* Tables of names of POSIX character classes and their lengths. The names are -now all in a single string, to reduce the number of relocations when a shared -library is dynamically loaded. The list of lengths is terminated by a zero -length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. The indices for graph, print, and punct are -needed, so identify them. */ - -static const char posix_names[] = - STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 - STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0 - STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 - STRING_word0 STRING_xdigit; - -static const uint8_t posix_name_lengths[] = { - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; - -#define PC_GRAPH 8 -#define PC_PRINT 9 -#define PC_PUNCT 10 - - -/* Table of class bit maps for each POSIX class. Each class is formed from a -base map, with an optional addition or removal of another map. Then, for some -classes, there is some additional tweaking: for [:blank:] the vertical space -characters are removed, and for [:alpha:] and [:alnum:] the underscore -character is removed. The triples in the table consist of the base map offset, -second map offset or -1 if no second map, and a non-negative value for map -addition or a negative value for map subtraction (if there are two maps). The -absolute value of the third field has these meanings: 0 => no tweaking, 1 => -remove vertical space characters, 2 => remove underscore. */ - -static const int posix_class_maps[] = { - cbit_word, cbit_digit, -2, /* alpha */ - cbit_lower, -1, 0, /* lower */ - cbit_upper, -1, 0, /* upper */ - cbit_word, -1, 2, /* alnum - word without underscore */ - cbit_print, cbit_cntrl, 0, /* ascii */ - cbit_space, -1, 1, /* blank - a GNU extension */ - cbit_cntrl, -1, 0, /* cntrl */ - cbit_digit, -1, 0, /* digit */ - cbit_graph, -1, 0, /* graph */ - cbit_print, -1, 0, /* print */ - cbit_punct, -1, 0, /* punct */ - cbit_space, -1, 0, /* space */ - cbit_word, -1, 0, /* word - a Perl extension */ - cbit_xdigit,-1, 0 /* xdigit */ -}; - -/* Table of substitutes for \d etc when PCRE2_UCP is set. They are replaced by -Unicode property escapes. */ - -#ifdef SUPPORT_UNICODE -static const PCRE2_UCHAR string_PNd[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pNd[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PXsp[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pXsp[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PXwd[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pXwd[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; - -static PCRE2_SPTR substitutes[] = { - string_PNd, /* \D */ - string_pNd, /* \d */ - string_PXsp, /* \S */ /* Xsp is Perl space, but from 8.34, Perl */ - string_pXsp, /* \s */ /* space and POSIX space are the same. */ - string_PXwd, /* \W */ - string_pXwd /* \w */ -}; - -/* The POSIX class substitutes must be in the order of the POSIX class names, -defined above, and there are both positive and negative cases. NULL means no -general substitute of a Unicode property escape (\p or \P). However, for some -POSIX classes (e.g. graph, print, punct) a special property code is compiled -directly. */ - -static const PCRE2_UCHAR string_pCc[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pL[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pLl[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pLu[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_pXan[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_h[] = { - CHAR_BACKSLASH, CHAR_h, '\0' }; -static const PCRE2_UCHAR string_pXps[] = { - CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PCc[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PL[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PLl[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PLu[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_PXan[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; -static const PCRE2_UCHAR string_H[] = { - CHAR_BACKSLASH, CHAR_H, '\0' }; -static const PCRE2_UCHAR string_PXps[] = { - CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, - CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; - -static PCRE2_SPTR posix_substitutes[] = { - string_pL, /* alpha */ - string_pLl, /* lower */ - string_pLu, /* upper */ - string_pXan, /* alnum */ - NULL, /* ascii */ - string_h, /* blank */ - string_pCc, /* cntrl */ - string_pNd, /* digit */ - NULL, /* graph */ - NULL, /* print */ - NULL, /* punct */ - string_pXps, /* space */ /* Xps is POSIX space, but from 8.34 */ - string_pXwd, /* word */ /* Perl and POSIX space are the same */ - NULL, /* xdigit */ - /* Negated cases */ - string_PL, /* ^alpha */ - string_PLl, /* ^lower */ - string_PLu, /* ^upper */ - string_PXan, /* ^alnum */ - NULL, /* ^ascii */ - string_H, /* ^blank */ - string_PCc, /* ^cntrl */ - string_PNd, /* ^digit */ - NULL, /* ^graph */ - NULL, /* ^print */ - NULL, /* ^punct */ - string_PXps, /* ^space */ /* Xps is POSIX space, but from 8.34 */ - string_PXwd, /* ^word */ /* Perl and POSIX space are the same */ - NULL /* ^xdigit */ -}; -#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(PCRE2_UCHAR *)) -#endif /* SUPPORT_UNICODE */ - -/* Masks for checking option settings. */ - -#define PUBLIC_COMPILE_OPTIONS \ - (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \ - PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \ - PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \ - PCRE2_MATCH_UNSET_BACKREF|PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C| \ - PCRE2_NEVER_UCP|PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE| \ - PCRE2_NO_AUTO_POSSESS|PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_NO_START_OPTIMIZE| \ - PCRE2_NO_UTF_CHECK|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_USE_OFFSET_LIMIT| \ - PCRE2_UTF) - -/* Compile time error code numbers. They are given names so that they can more -easily be tracked. When a new number is added, the tables called eint1 and -eint2 in pcre2posix.c may need to be updated, and a new error text must be -added to compile_error_texts in pcre2_error.c. */ - -enum { ERR0 = COMPILE_ERROR_BASE, - ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, - ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, - ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, - ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, - ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, - ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, - ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, - ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, - ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88 }; - -/* Error codes that correspond to negative error codes returned by -find_fixedlength(). */ - -static int fixed_length_errors[] = - { - ERR0, /* Not an error */ - ERR0, /* Not an error; -1 is used for "process later" */ - ERR25, /* Lookbehind is not fixed length */ - ERR36, /* \C in lookbehind is not allowed */ - ERR87, /* Lookbehind is too long */ - ERR86, /* Pattern too complicated */ - ERR70 /* Internal error: unknown opcode encountered */ - }; - -/* This is a table of start-of-pattern options such as (*UTF) and settings such -as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward -compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is -generic and always supported. */ - -enum { PSO_OPT, /* Value is an option bit */ - PSO_FLG, /* Value is a flag bit */ - PSO_NL, /* Value is a newline type */ - PSO_BSR, /* Value is a \R type */ - PSO_LIMM, /* Read integer value for match limit */ - PSO_LIMR }; /* Read integer value for recursion limit */ - -typedef struct pso { - const uint8_t *name; - uint16_t length; - uint16_t type; - uint32_t value; -} pso; - -/* NB: STRING_UTFn_RIGHTPAR contains the length as well */ - -static pso pso_list[] = { - { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, - { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, - { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, - { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, - { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, - { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS }, - { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR }, - { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, - { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE }, - { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, - { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMR, 0 }, - { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, - { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, - { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, - { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, - { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, - { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, - { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } -}; - -/* This table is used when converting repeating opcodes into possessified -versions as a result of an explicit possessive quantifier such as ++. A zero -value means there is no possessified version - in those cases the item in -question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT -because all relevant opcodes are less than that. */ - -static const uint8_t opcode_possessify[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */ - - 0, /* NOTI */ - OP_POSSTAR, 0, /* STAR, MINSTAR */ - OP_POSPLUS, 0, /* PLUS, MINPLUS */ - OP_POSQUERY, 0, /* QUERY, MINQUERY */ - OP_POSUPTO, 0, /* UPTO, MINUPTO */ - 0, /* EXACT */ - 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */ - - OP_POSSTARI, 0, /* STARI, MINSTARI */ - OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */ - OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */ - OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */ - 0, /* EXACTI */ - 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */ - - OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */ - OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */ - OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */ - OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */ - 0, /* NOTEXACT */ - 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */ - - OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */ - OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */ - OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */ - OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */ - 0, /* NOTEXACTI */ - 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */ - - OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */ - OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */ - OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */ - OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */ - 0, /* TYPEEXACT */ - 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */ - - OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */ - OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */ - OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */ - OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */ - 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */ - - 0, 0, 0, /* CLASS, NCLASS, XCLASS */ - 0, 0, /* REF, REFI */ - 0, 0, /* DNREF, DNREFI */ - 0, 0 /* RECURSE, CALLOUT */ -}; - - - -/************************************************* -* Free compiled code * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_code_free(pcre2_code *code) -{ -PCRE2_SIZE* ref_count; - -if (code != NULL) - { - if (code->executable_jit != NULL) - PRIV(jit_free)(code->executable_jit, &code->memctl); - - if ((code->flags & PCRE2_DEREF_TABLES) != 0) - { - /* Decoded tables belong to the codes after deserialization, and they must - be freed when there are no more reference to them. The *ref_count should - always be > 0. */ - - ref_count = (PCRE2_SIZE *)(code->tables + tables_length); - if (*ref_count > 0) - { - (*ref_count)--; - if (*ref_count == 0) - code->memctl.free((void *)code->tables, code->memctl.memory_data); - } - } - - code->memctl.free(code, code->memctl.memory_data); - } -} - - - -/************************************************* -* Insert an automatic callout point * -*************************************************/ - -/* This function is called when the PCRE2_AUTO_CALLOUT option is set, to insert -callout points before each pattern item. - -Arguments: - code current code pointer - ptr current pattern pointer - cb general compile-time data - -Returns: new code pointer -*/ - -static PCRE2_UCHAR * -auto_callout(PCRE2_UCHAR *code, PCRE2_SPTR ptr, compile_block *cb) -{ -code[0] = OP_CALLOUT; -PUT(code, 1, ptr - cb->start_pattern); /* Pattern offset */ -PUT(code, 1 + LINK_SIZE, 0); /* Default length */ -code[1 + 2*LINK_SIZE] = 255; -return code + PRIV(OP_lengths)[OP_CALLOUT]; -} - - - -/************************************************* -* Complete a callout item * -*************************************************/ - -/* A callout item contains the length of the next item in the pattern, which -we can't fill in till after we have reached the relevant point. This is used -for both automatic and manual callouts. - -Arguments: - previous_callout points to previous callout item - ptr current pattern pointer - cb general compile-time data - -Returns: nothing -*/ - -static void -complete_callout(PCRE2_UCHAR *previous_callout, PCRE2_SPTR ptr, - compile_block *cb) -{ -size_t length = ptr - cb->start_pattern - GET(previous_callout, 1); -PUT(previous_callout, 1 + LINK_SIZE, length); -} - - - -/************************************************* -* Find the fixed length of a branch * -*************************************************/ - -/* Scan a branch and compute the fixed length of subject that will match it, if -the length is fixed. This is needed for dealing with lookbehind assertions. In -UTF mode, the result is in code units rather than bytes. The branch is -temporarily terminated with OP_END when this function is called. - -This function is called when a lookbehind assertion is encountered, so that if -it fails, the error message can point to the correct place in the pattern. -However, we cannot do this when the assertion contains subroutine calls, -because they can be forward references. We solve this by remembering this case -and doing the check at the end; a flag specifies which mode we are running in. - -Lookbehind lengths are held in 16-bit fields and the maximum value is defined -as LOOKBEHIND_MAX. - -Arguments: - code points to the start of the pattern (the bracket) - utf TRUE in UTF mode - atend TRUE if called when the pattern is complete - cb the "compile data" structure - recurses chain of recurse_check to catch mutual recursion - countptr pointer to counter, to catch over-complexity - -Returns: if non-negative, the fixed length, - or -1 if an OP_RECURSE item was encountered and atend is FALSE - or -2 if there is no fixed length, - or -3 if \C was encountered (in UTF-8 mode only) - or -4 length is too long - or -5 if an unknown opcode was encountered (internal error) -*/ - -#define FFL_LATER (-1) -#define FFL_NOTFIXED (-2) -#define FFL_BACKSLASHC (-3) -#define FFL_TOOLONG (-4) -#define FFL_TOOCOMPLICATED (-5) -#define FFL_UNKNOWNOP (-6) - -static int -find_fixedlength(PCRE2_UCHAR *code, BOOL utf, BOOL atend, compile_block *cb, - recurse_check *recurses, int *countptr) -{ -int length = -1; -uint32_t group = 0; -uint32_t groupinfo = 0; -recurse_check this_recurse; -register int branchlength = 0; -register PCRE2_UCHAR *cc = code + 1 + LINK_SIZE; - -/* If this is a capturing group, we may have the answer cached, but we can only -use this information if there are no (?| groups in the pattern, because -otherwise group numbers are not unique. */ - -if (*code == OP_CBRA || *code == OP_CBRAPOS || *code == OP_SCBRA || - *code == OP_SCBRAPOS) - { - group = GET2(cc, 0); - cc += IMM2_SIZE; - groupinfo = cb->groupinfo[group]; - if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0) - { - if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return FFL_NOTFIXED; - if ((groupinfo & GI_SET_FIXED_LENGTH) != 0) - return groupinfo & GI_FIXED_LENGTH_MASK; - } - } - -/* A large and/or complex regex can take too long to process. This can happen -more often when (?| groups are present in the pattern. */ - -if ((*countptr)++ > 2000) return FFL_TOOCOMPLICATED; - -/* Scan along the opcodes for this branch. If we get to the end of the -branch, check the length against that of the other branches. */ - -for (;;) - { - int d; - PCRE2_UCHAR *ce, *cs; - register PCRE2_UCHAR op = *cc; - - if (branchlength > LOOKBEHIND_MAX) return FFL_TOOLONG; - - switch (op) - { - /* We only need to continue for OP_CBRA (normal capturing bracket) and - OP_BRA (normal non-capturing bracket) because the other variants of these - opcodes are all concerned with unlimited repeated groups, which of course - are not of fixed length. */ - - case OP_CBRA: - case OP_BRA: - case OP_ONCE: - case OP_ONCE_NC: - case OP_COND: - d = find_fixedlength(cc, utf, atend, cb, recurses, countptr); - if (d < 0) return d; - branchlength += d; - do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += 1 + LINK_SIZE; - break; - - /* Reached end of a branch; if it's a ket it is the end of a nested call. - If it's ALT it is an alternation in a nested call. An ACCEPT is effectively - an ALT. If it is END it's the end of the outer call. All can be handled by - the same code. Note that we must not include the OP_KETRxxx opcodes here, - because they all imply an unlimited repeat. */ - - case OP_ALT: - case OP_KET: - case OP_END: - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - if (length < 0) length = branchlength; - else if (length != branchlength) goto ISNOTFIXED; - if (*cc != OP_ALT) - { - if (group > 0) - { - groupinfo |= (GI_SET_FIXED_LENGTH | length); - cb->groupinfo[group] = groupinfo; - } - return length; - } - cc += 1 + LINK_SIZE; - branchlength = 0; - break; - - /* A true recursion implies not fixed length, but a subroutine call may - be OK. If the subroutine is a forward reference, we can't deal with - it until the end of the pattern, so return FFL_LATER. */ - - case OP_RECURSE: - if (!atend) return FFL_LATER; - cs = ce = (PCRE2_UCHAR *)cb->start_code + GET(cc, 1); /* Start subpattern */ - do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ - if (cc > cs && cc < ce) goto ISNOTFIXED; /* Recursion */ - else /* Check for mutual recursion */ - { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; - if (r != NULL) goto ISNOTFIXED; /* Mutual recursion */ - } - this_recurse.prev = recurses; - this_recurse.group = cs; - d = find_fixedlength(cs, utf, atend, cb, &this_recurse, countptr); - if (d < 0) return d; - branchlength += d; - cc += 1 + LINK_SIZE; - break; - - /* Skip over assertive subpatterns. Note that we must increment cc by - 1 + LINK_SIZE at the end, not by OP_length[*cc] because in a recursive - situation this assertion may be the one that is ultimately being checked - for having a fixed length, in which case its terminating OP_KET will have - been temporarily replaced by OP_END. */ - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += 1 + LINK_SIZE; - break; - - /* Skip over things that don't match chars */ - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - cc += cc[1] + PRIV(OP_lengths)[*cc]; - break; - - case OP_CALLOUT: - case OP_CIRC: - case OP_CIRCM: - case OP_CLOSE: - case OP_COMMIT: - case OP_CREF: - case OP_FALSE: - case OP_TRUE: - case OP_DNCREF: - case OP_DNRREF: - case OP_DOLL: - case OP_DOLLM: - case OP_EOD: - case OP_EODN: - case OP_FAIL: - case OP_NOT_WORD_BOUNDARY: - case OP_PRUNE: - case OP_REVERSE: - case OP_RREF: - case OP_SET_SOM: - case OP_SKIP: - case OP_SOD: - case OP_SOM: - case OP_THEN: - case OP_WORD_BOUNDARY: - cc += PRIV(OP_lengths)[*cc]; - break; - - case OP_CALLOUT_STR: - cc += GET(cc, 1 + 2*LINK_SIZE); - break; - - /* Handle literal characters */ - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - branchlength++; - cc += 2; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - /* Handle exact repetitions. The count is already in characters, but we - need to skip over a multibyte character in UTF8 mode. */ - - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - branchlength += (int)GET2(cc,1); - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - case OP_TYPEEXACT: - branchlength += GET2(cc,1); - if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) - cc += 2; - cc += 1 + IMM2_SIZE + 1; - break; - - /* Handle single-char matchers */ - - case OP_PROP: - case OP_NOTPROP: - cc += 2; - /* Fall through */ - - case OP_HSPACE: - case OP_VSPACE: - case OP_NOT_HSPACE: - case OP_NOT_VSPACE: - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - branchlength++; - cc++; - break; - - /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; - otherwise \C is coded as OP_ALLANY. */ - - case OP_ANYBYTE: - return FFL_BACKSLASHC; - - /* Check a class for variable quantification */ - - case OP_CLASS: - case OP_NCLASS: -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - /* The original code caused an unsigned overflow in 64 bit systems, - so now we use a conditional statement. */ - if (op == OP_XCLASS) - cc += GET(cc, 1); - else - cc += PRIV(OP_lengths)[OP_CLASS]; -#else - cc += PRIV(OP_lengths)[OP_CLASS]; -#endif - - switch (*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - goto ISNOTFIXED; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) goto ISNOTFIXED; - branchlength += (int)GET2(cc,1); - cc += 1 + 2 * IMM2_SIZE; - break; - - default: - branchlength++; - } - break; - - /* Anything else is variable length */ - - case OP_ANYNL: - case OP_BRAMINZERO: - case OP_BRAPOS: - case OP_BRAPOSZERO: - case OP_BRAZERO: - case OP_CBRAPOS: - case OP_EXTUNI: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - case OP_MINPLUS: - case OP_MINPLUSI: - case OP_MINQUERY: - case OP_MINQUERYI: - case OP_MINSTAR: - case OP_MINSTARI: - case OP_MINUPTO: - case OP_MINUPTOI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_PLUS: - case OP_PLUSI: - case OP_POSPLUS: - case OP_POSPLUSI: - case OP_POSQUERY: - case OP_POSQUERYI: - case OP_POSSTAR: - case OP_POSSTARI: - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_QUERY: - case OP_QUERYI: - case OP_REF: - case OP_REFI: - case OP_DNREF: - case OP_DNREFI: - case OP_SBRA: - case OP_SBRAPOS: - case OP_SCBRA: - case OP_SCBRAPOS: - case OP_SCOND: - case OP_SKIPZERO: - case OP_STAR: - case OP_STARI: - case OP_TYPEMINPLUS: - case OP_TYPEMINQUERY: - case OP_TYPEMINSTAR: - case OP_TYPEMINUPTO: - case OP_TYPEPLUS: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSUPTO: - case OP_TYPEQUERY: - case OP_TYPESTAR: - case OP_TYPEUPTO: - case OP_UPTO: - case OP_UPTOI: - goto ISNOTFIXED; - - /* Catch unrecognized opcodes so that when new ones are added they - are not forgotten, as has happened in the past. */ - - default: - return FFL_UNKNOWNOP; - } - } -/* Control never gets here except by goto. */ - -ISNOTFIXED: -if (group > 0) - { - groupinfo |= GI_NOT_FIXED_LENGTH; - cb->groupinfo[group] = groupinfo; - } -return FFL_NOTFIXED; -} - - - -/************************************************* -* Find first significant op code * -*************************************************/ - -/* This is called by several functions that scan a compiled expression looking -for a fixed first character, or an anchoring op code etc. It skips over things -that do not influence this. For some calls, it makes sense to skip negative -forward and all backward assertions, and also the \b assertion; for others it -does not. - -Arguments: - code pointer to the start of the group - skipassert TRUE if certain assertions are to be skipped - -Returns: pointer to the first significant opcode -*/ - -static const PCRE2_UCHAR* -first_significant_code(PCRE2_SPTR code, BOOL skipassert) -{ -for (;;) - { - switch ((int)*code) - { - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - if (!skipassert) return code; - do code += GET(code, 1); while (*code == OP_ALT); - code += PRIV(OP_lengths)[*code]; - break; - - case OP_WORD_BOUNDARY: - case OP_NOT_WORD_BOUNDARY: - if (!skipassert) return code; - /* Fall through */ - - case OP_CALLOUT: - case OP_CREF: - case OP_DNCREF: - case OP_RREF: - case OP_DNRREF: - case OP_FALSE: - case OP_TRUE: - code += PRIV(OP_lengths)[*code]; - break; - - case OP_CALLOUT_STR: - code += GET(code, 1 + 2*LINK_SIZE); - break; - - default: - return code; - } - } -/* Control never reaches here */ -} - - - -/************************************************* -* Scan compiled branch for non-emptiness * -*************************************************/ - -/* This function scans through a branch of a compiled pattern to see whether it -can match the empty string. It is called at the end of compiling to check the -entire pattern, and from compile_branch() when checking for an unlimited repeat -of a group that can match nothing. In the latter case it is called only when -doing the real compile, not during the pre-compile that measures the size of -the compiled pattern. - -Note that first_significant_code() skips over backward and negative forward -assertions when its final argument is TRUE. If we hit an unclosed bracket, we -return "empty" - this means we've struck an inner bracket whose current branch -will already have been scanned. - -Arguments: - code points to start of search - endcode points to where to stop - utf TRUE if in UTF mode - cb compile data - atend TRUE if being called to check an entire pattern - recurses chain of recurse_check to catch mutual recursion - countptr pointer to count to catch over-complicated pattern - -Returns: 0 if what is matched cannot be empty - 1 if what is matched could be empty - -1 if the pattern is too complicated -*/ - -#define CBE_NOTEMPTY 0 -#define CBE_EMPTY 1 -#define CBE_TOOCOMPLICATED (-1) - - -static int -could_be_empty_branch(PCRE2_SPTR code, PCRE2_SPTR endcode, BOOL utf, - compile_block *cb, BOOL atend, recurse_check *recurses, int *countptr) -{ -uint32_t group = 0; -uint32_t groupinfo = 0; -register PCRE2_UCHAR c; -recurse_check this_recurse; - -/* If what we are checking has already been set as "could be empty", we know -the answer. */ - -if (*code >= OP_SBRA && *code <= OP_SCOND) return CBE_EMPTY; - -/* If this is a capturing group, we may have the answer cached, but we can only -use this information if there are no (?| groups in the pattern, because -otherwise group numbers are not unique. */ - -if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0 && - (*code == OP_CBRA || *code == OP_CBRAPOS)) - { - group = GET2(code, 1 + LINK_SIZE); - groupinfo = cb->groupinfo[group]; - if ((groupinfo & GI_SET_COULD_BE_EMPTY) != 0) - return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY; - } - -/* A large and/or complex regex can take too long to process. We have to assume -it can match an empty string. This can happen more often when (?| groups are -present in the pattern and the caching is disabled. Setting the cap at 1100 -allows the test for more than 1023 capturing patterns to work. */ - -if ((*countptr)++ > 1100) return CBE_TOOCOMPLICATED; - -/* Scan the opcodes for this branch. */ - -for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); - code < endcode; - code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) - { - PCRE2_SPTR ccode; - - c = *code; - - /* Skip over forward assertions; the other assertions are skipped by - first_significant_code() with a TRUE final argument. */ - - if (c == OP_ASSERT) - { - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - continue; - } - - /* For a recursion/subroutine call we can scan the recursion when this - function is called at the end, to check a complete pattern. Before then, - recursions just have the group number as their argument and in any case may - be forward references. In that situation, we return CBE_EMPTY, just in case. - It means that unlimited repeats of groups that contain recursions are always - treated as "could be empty" - which just adds a bit more processing time - because of the runtime check. */ - - if (c == OP_RECURSE) - { - PCRE2_SPTR scode, endgroup; - BOOL empty_branch; - - if (!atend) goto ISTRUE; - scode = cb->start_code + GET(code, 1); - endgroup = scode; - - /* We need to detect whether this is a recursive call, as otherwise there - will be an infinite loop. If it is a recursion, just skip over it. Simple - recursions are easily detected. For mutual recursions we keep a chain on - the stack. */ - - do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT); - if (code >= scode && code <= endgroup) continue; /* Simple recursion */ - else - { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) - if (r->group == scode) break; - if (r != NULL) continue; /* Mutual recursion */ - } - - /* Scan the referenced group, remembering it on the stack chain to detect - mutual recursions. */ - - empty_branch = FALSE; - this_recurse.prev = recurses; - this_recurse.group = scode; - - do - { - int rc = could_be_empty_branch(scode, endcode, utf, cb, atend, - &this_recurse, countptr); - if (rc < 0) return rc; - if (rc > 0) - { - empty_branch = TRUE; - break; - } - scode += GET(scode, 1); - } - while (*scode == OP_ALT); - - if (!empty_branch) goto ISFALSE; /* All branches are non-empty */ - continue; - } - - /* Groups with zero repeats can of course be empty; skip them. */ - - if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO || - c == OP_BRAPOSZERO) - { - code += PRIV(OP_lengths)[c]; - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - continue; - } - - /* A nested group that is already marked as "could be empty" can just be - skipped. */ - - if (c == OP_SBRA || c == OP_SBRAPOS || - c == OP_SCBRA || c == OP_SCBRAPOS) - { - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - continue; - } - - /* For other groups, scan the branches. */ - - if (c == OP_BRA || c == OP_BRAPOS || - c == OP_CBRA || c == OP_CBRAPOS || - c == OP_ONCE || c == OP_ONCE_NC || - c == OP_COND || c == OP_SCOND) - { - BOOL empty_branch; - if (GET(code, 1) == 0) goto ISTRUE; /* Hit unclosed bracket */ - - /* If a conditional group has only one branch, there is a second, implied, - empty branch, so just skip over the conditional, because it could be empty. - Otherwise, scan the individual branches of the group. */ - - if (c == OP_COND && code[GET(code, 1)] != OP_ALT) - code += GET(code, 1); - else - { - empty_branch = FALSE; - do - { - if (!empty_branch) - { - int rc = could_be_empty_branch(code, endcode, utf, cb, atend, - recurses, countptr); - if (rc < 0) return rc; - if (rc > 0) empty_branch = TRUE; - } - code += GET(code, 1); - } - while (*code == OP_ALT); - if (!empty_branch) goto ISFALSE; /* All branches are non-empty */ - } - - c = *code; - continue; - } - - /* Handle the other opcodes */ - - switch (c) - { - /* Check for quantifiers after a class. XCLASS is used for classes that - cannot be represented just by a bit map. This includes negated single - high-valued characters. The length in PRIV(OP_lengths)[] is zero; the - actual length is stored in the compiled code, so we must update "code" - here. */ - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - ccode = code += GET(code, 1); - goto CHECK_CLASS_REPEAT; -#endif - - case OP_CLASS: - case OP_NCLASS: - ccode = code + PRIV(OP_lengths)[OP_CLASS]; - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - CHECK_CLASS_REPEAT: -#endif - - switch (*ccode) - { - case OP_CRSTAR: /* These could be empty; continue */ - case OP_CRMINSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSQUERY: - break; - - default: /* Non-repeat => class must match */ - case OP_CRPLUS: /* These repeats aren't empty */ - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - goto ISFALSE; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - if (GET2(ccode, 1) > 0) goto ISFALSE; /* Minimum > 0 */ - break; - } - break; - - /* Opcodes that must match a character */ - - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: - - case OP_PROP: - case OP_NOTPROP: - case OP_ANYNL: - - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_EXTUNI: - - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - - case OP_PLUS: - case OP_PLUSI: - case OP_MINPLUS: - case OP_MINPLUSI: - - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - - case OP_POSPLUS: - case OP_POSPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - case OP_TYPEEXACT: - goto ISFALSE; - - /* These are going to continue, as they may be empty, but we have to - fudge the length for the \p and \P cases. */ - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPOSSTAR: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSQUERY: - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; - break; - - /* Same for these */ - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; - break; - - /* End of branch */ - - case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - case OP_ALT: - goto ISTRUE; - - /* In UTF-8 or UTF-16 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, - POSQUERY, UPTO, MINUPTO, and POSUPTO and their caseless and negative - versions may be followed by a multibyte character. */ - -#ifdef MAYBE_UTF_MULTI - case OP_STAR: - case OP_STARI: - case OP_NOTSTAR: - case OP_NOTSTARI: - - case OP_MINSTAR: - case OP_MINSTARI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - - case OP_POSSTAR: - case OP_POSSTARI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - - case OP_QUERY: - case OP_QUERYI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - - case OP_MINQUERY: - case OP_MINQUERYI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - - case OP_POSQUERY: - case OP_POSQUERYI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); - break; - - case OP_UPTO: - case OP_UPTOI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - - case OP_MINUPTO: - case OP_MINUPTOI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); - break; -#endif /* MAYBE_UTF_MULTI */ - - /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument - string. */ - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - code += code[1]; - break; - - /* None of the remaining opcodes are required to match a character. */ - - default: - break; - } - } - -ISTRUE: -groupinfo |= GI_COULD_BE_EMPTY; - -ISFALSE: -if (group > 0) cb->groupinfo[group] = groupinfo | GI_SET_COULD_BE_EMPTY; - -return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY; -} - - - -/************************************************* -* Check for counted repeat * -*************************************************/ - -/* This function is called when a '{' is encountered in a place where it might -start a quantifier. It looks ahead to see if it really is a quantifier, that -is, one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits. - -Argument: pointer to the first char after '{' -Returns: TRUE or FALSE -*/ - -static BOOL -is_counted_repeat(PCRE2_SPTR p) -{ -if (!IS_DIGIT(*p)) return FALSE; -p++; -while (IS_DIGIT(*p)) p++; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if (*p++ != CHAR_COMMA) return FALSE; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if (!IS_DIGIT(*p)) return FALSE; -p++; -while (IS_DIGIT(*p)) p++; - -return (*p == CHAR_RIGHT_CURLY_BRACKET); -} - - - -/************************************************* -* Handle escapes * -*************************************************/ - -/* This function is called when a \ has been encountered. It either returns a -positive value for a simple escape such as \d, or 0 for a data character, which -is placed in chptr. A backreference to group n is returned as negative n. On -entry, ptr is pointing at the \. On exit, it points the final code unit of the -escape sequence. - -This function is also called from pcre2_substitute() to handle escape sequences -in replacement strings. In this case, the cb argument is NULL, and only -sequences that define a data character are recognised. The isclass argument is -not relevant, but the options argument is the final value of the compiled -pattern's options. - -There is one "trick" case: when a sequence such as [[:>:]] or \s in UCP mode is -processed, it is replaced by a nested alternative sequence. If this contains a -backslash (which is usually does), ptrend does not point to its end - it still -points to the end of the whole pattern. However, we can detect this case -because cb->nestptr[0] will be non-NULL. The nested sequences are all zero- -terminated and there are only ever two levels of nesting. - -Arguments: - ptrptr points to the input position pointer - ptrend points to the end of the input - chptr points to a returned data character - errorcodeptr points to the errorcode variable (containing zero) - options the current options bits - isclass TRUE if inside a character class - cb compile data block - -Returns: zero => a data character - positive => a special escape sequence - negative => a back reference - on error, errorcodeptr is set non-zero -*/ - -int -PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb) -{ -BOOL utf = (options & PCRE2_UTF) != 0; -PCRE2_SPTR ptr = *ptrptr + 1; -register uint32_t c, cc; -int escape = 0; -int i; - -/* Find the end of a nested insert. */ - -if (cb != NULL && cb->nestptr[0] != NULL) - ptrend = ptr + PRIV(strlen)(ptr); - -/* If backslash is at the end of the string, it's an error. */ - -if (ptr >= ptrend) - { - *errorcodeptr = ERR1; - return 0; - } - -GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ -ptr--; /* Set pointer back to the last code unit */ - -/* Non-alphanumerics are literals, so we just leave the value in c. An initial -value test saves a memory lookup for code points outside the alphanumeric -range. Otherwise, do a table lookup. A non-zero result is something that can be -returned immediately. Otherwise further processing is required. */ - -if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {} /* Definitely literal */ - -else if ((i = escapes[c - ESCAPES_FIRST]) != 0) - { - if (i > 0) c = (uint32_t)i; else /* Positive is a data character */ - { - escape = -i; /* Else return a special escape */ - if (escape == ESC_P || escape == ESC_p || escape == ESC_X) - cb->external_flags |= PCRE2_HASBKPORX; /* Note \P, \p, or \X */ - } - } - -/* Escapes that need further processing, including those that are unknown. -When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u -when BSUX is set). */ - -else - { - PCRE2_SPTR oldptr; - BOOL braced, negated, overflow; - unsigned int s; - - /* Filter calls from pcre2_substitute(). */ - - if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x && - (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0)) - { - *errorcodeptr = ERR3; - return 0; - } - - switch (c) - { - /* A number of Perl escapes are not handled by PCRE. We give an explicit - error. */ - - case CHAR_l: - case CHAR_L: - *errorcodeptr = ERR37; - break; - - /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated - specially, \u must be followed by four hex digits. Otherwise it is a - lowercase u letter. */ - - case CHAR_u: - if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else - { - uint32_t xc; - if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ - if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ - cc = (cc << 4) | xc; - if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */ - cc = (cc << 4) | xc; - if ((xc = XDIGIT(ptr[4])) == 0xff) break; /* Not a hex digit */ - c = (cc << 4) | xc; - ptr += 4; - if (utf) - { - if (c > 0x10ffffU) *errorcodeptr = ERR77; - else if (c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; - } - else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77; - } - break; - - case CHAR_U: - /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an - upper case letter. */ - if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; - break; - - /* In a character class, \g is just a literal "g". Outside a character - class, \g must be followed by one of a number of specific things: - - (1) A number, either plain or braced. If positive, it is an absolute - backreference. If negative, it is a relative backreference. This is a Perl - 5.10 feature. - - (2) Perl 5.10 also supports \g{name} as a reference to a named group. This - is part of Perl's movement towards a unified syntax for back references. As - this is synonymous with \k{name}, we fudge it up by pretending it really - was \k. - - (3) For Oniguruma compatibility we also support \g followed by a name or a - number either in angle brackets or in single quotes. However, these are - (possibly recursive) subroutine calls, _not_ backreferences. Just return - the ESC_g code (cf \k). */ - - case CHAR_g: - if (isclass) break; - if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) - { - escape = ESC_g; - break; - } - - /* Handle the Perl-compatible cases */ - - if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) - { - PCRE2_SPTR p; - for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++) - if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; - if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET) - { - escape = ESC_k; - break; - } - braced = TRUE; - ptr++; - } - else braced = FALSE; - - if (ptr[1] == CHAR_MINUS) - { - negated = TRUE; - ptr++; - } - else negated = FALSE; - - /* The integer range is limited by the machine's int representation. */ - s = 0; - overflow = FALSE; - while (IS_DIGIT(ptr[1])) - { - if (s > INT_MAX / 10 - 1) /* Integer overflow */ - { - overflow = TRUE; - break; - } - s = s * 10 + (int)(*(++ptr) - CHAR_0); - } - if (overflow) /* Integer overflow */ - { - while (IS_DIGIT(ptr[1])) ptr++; - *errorcodeptr = ERR61; - break; - } - - if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET) - { - *errorcodeptr = ERR57; - break; - } - - if (s == 0) - { - *errorcodeptr = ERR58; - break; - } - - if (negated) - { - if (s > cb->bracount) - { - *errorcodeptr = ERR15; - break; - } - s = cb->bracount - (s - 1); - } - - escape = -(int)s; - break; - - /* The handling of escape sequences consisting of a string of digits - starting with one that is not zero is not straightforward. Perl has changed - over the years. Nowadays \g{} for backreferences and \o{} for octal are - recommended to avoid the ambiguities in the old syntax. - - Outside a character class, the digits are read as a decimal number. If the - number is less than 10, or if there are that many previous extracting left - brackets, it is a back reference. Otherwise, up to three octal digits are - read to form an escaped character code. Thus \123 is likely to be octal 123 - (cf \0123, which is octal 012 followed by the literal 3). - - Inside a character class, \ followed by a digit is always either a literal - 8 or 9 or an octal number. */ - - case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: - case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: - - if (!isclass) - { - oldptr = ptr; - /* The integer range is limited by the machine's int representation. */ - s = c - CHAR_0; - overflow = FALSE; - while (IS_DIGIT(ptr[1])) - { - if (s > INT_MAX / 10 - 1) /* Integer overflow */ - { - overflow = TRUE; - break; - } - s = s * 10 + (int)(*(++ptr) - CHAR_0); - } - if (overflow) /* Integer overflow */ - { - while (IS_DIGIT(ptr[1])) ptr++; - *errorcodeptr = ERR61; - break; - } - - /* \1 to \9 are always back references. \8x and \9x are too; \1x to \7x - are octal escapes if there are not that many previous captures. */ - - if (s < 10 || *oldptr >= CHAR_8 || s <= cb->bracount) - { - escape = -(int)s; /* Indicates a back reference */ - break; - } - ptr = oldptr; /* Put the pointer back and fall through */ - } - - /* Handle a digit following \ when the number is not a back reference, or - we are within a character class. If the first digit is 8 or 9, Perl used to - generate a binary zero byte and then treat the digit as a following - literal. At least by Perl 5.18 this changed so as not to insert the binary - zero. */ - - if ((c = *ptr) >= CHAR_8) break; - - /* Fall through with a digit less than 8 */ - - /* \0 always starts an octal number, but we may drop through to here with a - larger first octal digit. The original code used just to take the least - significant 8 bits of octal numbers (I think this is what early Perls used - to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, - but no more than 3 octal digits. */ - - case CHAR_0: - c -= CHAR_0; - while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) - c = c * 8 + *(++ptr) - CHAR_0; -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (!utf && c > 0xff) *errorcodeptr = ERR51; -#endif - break; - - /* \o is a relatively new Perl feature, supporting a more general way of - specifying character codes in octal. The only supported form is \o{ddd}. */ - - case CHAR_o: - if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR55; else - if (ptr[2] == CHAR_RIGHT_CURLY_BRACKET) *errorcodeptr = ERR78; else - { - ptr += 2; - c = 0; - overflow = FALSE; - while (*ptr >= CHAR_0 && *ptr <= CHAR_7) - { - cc = *ptr++; - if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x20000000l) { overflow = TRUE; break; } -#endif - c = (c << 3) + (cc - CHAR_0); -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } -#elif PCRE2_CODE_UNIT_WIDTH == 16 - if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } -#elif PCRE2_CODE_UNIT_WIDTH == 32 - if (utf && c > 0x10ffffU) { overflow = TRUE; break; } -#endif - } - if (overflow) - { - while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; - *errorcodeptr = ERR34; - } - else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) - { - if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; - } - else *errorcodeptr = ERR64; - } - break; - - /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by - two hexadecimal digits. Otherwise it is a lowercase x letter. */ - - case CHAR_x: - if ((options & PCRE2_ALT_BSUX) != 0) - { - uint32_t xc; - if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ - if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ - c = (cc << 4) | xc; - ptr += 2; - } /* End PCRE2_ALT_BSUX handling */ - - /* Handle \x in Perl's style. \x{ddd} is a character number which can be - greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex - digits. If not, { used to be treated as a data character. However, Perl - seems to read hex digits up to the first non-such, and ignore the rest, so - that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE - now gives an error. */ - - else - { - if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) - { - ptr += 2; - if (*ptr == CHAR_RIGHT_CURLY_BRACKET) - { - *errorcodeptr = ERR78; - break; - } - c = 0; - overflow = FALSE; - - while ((cc = XDIGIT(*ptr)) != 0xff) - { - ptr++; - if (c == 0 && cc == 0) continue; /* Leading zeroes */ -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x10000000l) { overflow = TRUE; break; } -#endif - c = (c << 4) | cc; - if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR)) - { - overflow = TRUE; - break; - } - } - - if (overflow) - { - while (XDIGIT(*ptr) != 0xff) ptr++; - *errorcodeptr = ERR34; - } - else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) - { - if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; - } - - /* If the sequence of hex digits does not end with '}', give an error. - We used just to recognize this construct and fall through to the normal - \x handling, but nowadays Perl gives an error, which seems much more - sensible, so we do too. */ - - else *errorcodeptr = ERR67; - } /* End of \x{} processing */ - - /* Read a single-byte hex-defined char (up to two hex digits after \x) */ - - else - { - c = 0; - if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ - ptr++; - c = cc; - if ((cc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ - ptr++; - c = (c << 4) | cc; - } /* End of \xdd handling */ - } /* End of Perl-style \x handling */ - break; - - /* The handling of \c is different in ASCII and EBCDIC environments. In an - ASCII (or Unicode) environment, an error is given if the character - following \c is not a printable ASCII character. Otherwise, the following - character is upper-cased if it is a letter, and after that the 0x40 bit is - flipped. The result is the value of the escape. - - In an EBCDIC environment the handling of \c is compatible with the - specification in the perlebcdic document. The following character must be - a letter or one of small number of special characters. These provide a - means of defining the character values 0-31. - - For testing the EBCDIC handling of \c in an ASCII environment, recognize - the EBCDIC value of 'c' explicitly. */ - -#if defined EBCDIC && 'a' != 0x81 - case 0x83: -#else - case CHAR_c: -#endif - - c = *(++ptr); - if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c); - if (c == CHAR_NULL && ptr >= ptrend) - { - *errorcodeptr = ERR2; - break; - } - - /* Handle \c in an ASCII/Unicode environment. */ - -#ifndef EBCDIC /* ASCII/UTF-8 coding */ - if (c < 32 || c > 126) /* Excludes all non-printable ASCII */ - { - *errorcodeptr = ERR68; - break; - } - c ^= 0x40; - - /* Handle \c in an EBCDIC environment. The special case \c? is converted to - 255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC - encoding. (This is the way Perl indicates that it handles \c?.) The other - valid sequences correspond to a list of specific characters. */ - -#else - if (c == CHAR_QUESTION_MARK) - c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff; - else - { - for (i = 0; i < 32; i++) - { - if (c == ebcdic_escape_c[i]) break; - } - if (i < 32) c = i; else *errorcodeptr = ERR68; - } -#endif /* EBCDIC */ - - break; - - /* Any other alphanumeric following \ is an error. Perl gives an error only - if in warning mode, but PCRE doesn't have a warning mode. */ - - default: - *errorcodeptr = ERR3; - break; - } - } - -/* Perl supports \N{name} for character names, as well as plain \N for "not -newline". PCRE does not support \N{name}. However, it does support -quantification such as \N{2,3}. */ - -if (escape == ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && - !is_counted_repeat(ptr+2)) - *errorcodeptr = ERR37; - -/* If PCRE2_UCP is set, we change the values for \d etc. */ - -if ((options & PCRE2_UCP) != 0 && escape >= ESC_D && escape <= ESC_w) - escape += (ESC_DU - ESC_D); - -/* Set the pointer to the final character before returning. */ - -*ptrptr = ptr; -*chptr = c; -return escape; -} - - - -#ifdef SUPPORT_UNICODE -/************************************************* -* Handle \P and \p * -*************************************************/ - -/* This function is called after \P or \p has been encountered, provided that -PCRE2 is compiled with support for UTF and Unicode properties. On entry, the -contents of ptrptr are pointing at the P or p. On exit, it is left pointing at -the final code unit of the escape sequence. - -Arguments: - ptrptr the pattern position pointer - negptr a boolean that is set TRUE for negation else FALSE - ptypeptr an unsigned int that is set to the type value - pdataptr an unsigned int that is set to the detailed property value - errorcodeptr the error code variable - cb the compile data - -Returns: TRUE if the type value was found, or FALSE for an invalid type -*/ - -static BOOL -get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, unsigned int *ptypeptr, - unsigned int *pdataptr, int *errorcodeptr, compile_block *cb) -{ -register PCRE2_UCHAR c; -int i, bot, top; -PCRE2_SPTR ptr = *ptrptr; -PCRE2_UCHAR name[32]; - -*negptr = FALSE; -c = *(++ptr); - -/* \P or \p can be followed by a name in {}, optionally preceded by ^ for -negation. */ - -if (c == CHAR_LEFT_CURLY_BRACKET) - { - if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT) - { - *negptr = TRUE; - ptr++; - } - for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++) - { - c = *(++ptr); - if (c == CHAR_NULL) goto ERROR_RETURN; - if (c == CHAR_RIGHT_CURLY_BRACKET) break; - name[i] = c; - } - if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; - name[i] = 0; - } - -/* Otherwise there is just one following character, which must be an ASCII -letter. */ - -else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0) - { - name[0] = c; - name[1] = 0; - } -else goto ERROR_RETURN; - -*ptrptr = ptr; - -/* Search for a recognized property name using binary chop. */ - -bot = 0; -top = PRIV(utt_size); - -while (bot < top) - { - int r; - i = (bot + top) >> 1; - r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); - if (r == 0) - { - *ptypeptr = PRIV(utt)[i].type; - *pdataptr = PRIV(utt)[i].value; - return TRUE; - } - if (r > 0) bot = i + 1; else top = i; - } -*errorcodeptr = ERR47; /* Unrecognized name */ -return FALSE; - -ERROR_RETURN: /* Malformed \P or \p */ -*errorcodeptr = ERR46; -*ptrptr = ptr; -return FALSE; -} -#endif - - - -/************************************************* -* Read repeat counts * -*************************************************/ - -/* Read an item of the form {n,m} and return the values. This is called only -after is_counted_repeat() has confirmed that a repeat-count quantifier exists, -so the syntax is guaranteed to be correct, but we need to check the values. - -Arguments: - p pointer to first char after '{' - minp pointer to int for min - maxp pointer to int for max - returned as -1 if no max - errorcodeptr points to error code variable - -Returns: pointer to '}' on success; - current ptr on error, with errorcodeptr set non-zero -*/ - -static PCRE2_SPTR -read_repeat_counts(PCRE2_SPTR p, int *minp, int *maxp, int *errorcodeptr) -{ -int min = 0; -int max = -1; - -while (IS_DIGIT(*p)) - { - min = min * 10 + (int)(*p++ - CHAR_0); - if (min > 65535) - { - *errorcodeptr = ERR5; - return p; - } - } - -if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else - { - if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) - { - max = 0; - while(IS_DIGIT(*p)) - { - max = max * 10 + (int)(*p++ - CHAR_0); - if (max > 65535) - { - *errorcodeptr = ERR5; - return p; - } - } - if (max < min) - { - *errorcodeptr = ERR4; - return p; - } - } - } - -*minp = min; -*maxp = max; -return p; -} - - - -/************************************************* -* Scan compiled regex for recursion reference * -*************************************************/ - -/* This function scans through a compiled pattern until it finds an instance of -OP_RECURSE. - -Arguments: - code points to start of expression - utf TRUE in UTF mode - -Returns: pointer to the opcode for OP_RECURSE, or NULL if not found -*/ - -static PCRE2_SPTR -find_recurse(PCRE2_SPTR code, BOOL utf) -{ -for (;;) - { - register PCRE2_UCHAR c = *code; - if (c == OP_END) return NULL; - if (c == OP_RECURSE) return code; - - /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. CALLOUT_STR is used for - callouts with string arguments. In both cases the length in the table is - zero; the actual length is stored in the compiled code. */ - - if (c == OP_XCLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); - - /* Otherwise, we can get the item's length from the table, except that for - repeated character types, we have to test for \p and \P, which have an extra - two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we - must add in its length. */ - - else - { - switch(c) - { - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; - break; - - case OP_TYPEPOSUPTO: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - code += code[1]; - break; - } - - /* Add in the fixed length from the table */ - - code += PRIV(OP_lengths)[c]; - - /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may - be followed by a multi-unit character. The length in the table is a - minimum, so we have to arrange to skip the extra units. */ - -#ifdef MAYBE_UTF_MULTI - if (utf) switch(c) - { - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - case OP_UPTO: - case OP_UPTOI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_MINUPTO: - case OP_MINUPTOI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - case OP_STAR: - case OP_STARI: - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_MINSTAR: - case OP_MINSTARI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_POSSTAR: - case OP_POSSTARI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - case OP_PLUS: - case OP_PLUSI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_MINPLUS: - case OP_MINPLUSI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_POSPLUS: - case OP_POSPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - case OP_QUERY: - case OP_QUERYI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_MINQUERY: - case OP_MINQUERYI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - case OP_POSQUERY: - case OP_POSQUERYI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); - break; - } -#else - (void)(utf); /* Keep compiler happy by referencing function argument */ -#endif /* MAYBE_UTF_MULTI */ - } - } -} - - - -/************************************************* -* Check for POSIX class syntax * -*************************************************/ - -/* This function is called when the sequence "[:" or "[." or "[=" is -encountered in a character class. It checks whether this is followed by a -sequence of characters terminated by a matching ":]" or ".]" or "=]". If we -reach an unescaped ']' without the special preceding character, return FALSE. - -Originally, this function only recognized a sequence of letters between the -terminators, but it seems that Perl recognizes any sequence of characters, -though of course unknown POSIX names are subsequently rejected. Perl gives an -"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE -didn't consider this to be a POSIX class. Likewise for [:1234:]. - -The problem in trying to be exactly like Perl is in the handling of escapes. We -have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX -class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code -below handles the special cases \\ and \], but does not try to do any other -escape processing. This makes it different from Perl for cases such as -[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does -not recognize "l\ower". This is a lesser evil than not diagnosing bad classes -when Perl does, I think. - -A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. -It seems that the appearance of a nested POSIX class supersedes an apparent -external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or -a digit. This is handled by returning FALSE if the start of a new group with -the same terminator is encountered, since the next closing sequence must close -the nested group, not the outer one. - -In Perl, unescaped square brackets may also appear as part of class names. For -example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for -[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not -seem right at all. PCRE does not allow closing square brackets in POSIX class -names. - -Arguments: - ptr pointer to the initial [ - endptr where to return a pointer to the terminating ':', '.', or '=' - -Returns: TRUE or FALSE -*/ - -static BOOL -check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR *endptr) -{ -PCRE2_UCHAR terminator; /* Don't combine these lines; the Solaris cc */ -terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ - -for (++ptr; *ptr != CHAR_NULL; ptr++) - { - if (*ptr == CHAR_BACKSLASH && - (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH)) - ptr++; - else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) || - *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; - else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) - { - *endptr = ptr; - return TRUE; - } - } - -return FALSE; -} - - - -/************************************************* -* Check POSIX class name * -*************************************************/ - -/* This function is called to check the name given in a POSIX-style class entry -such as [:alnum:]. - -Arguments: - ptr points to the first letter - len the length of the name - -Returns: a value representing the name, or -1 if unknown -*/ - -static int -check_posix_name(PCRE2_SPTR ptr, int len) -{ -const char *pn = posix_names; -register int yield = 0; -while (posix_name_lengths[yield] != 0) - { - if (len == posix_name_lengths[yield] && - PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield; - pn += posix_name_lengths[yield] + 1; - yield++; - } -return -1; -} - - - -#ifdef SUPPORT_UNICODE -/************************************************* -* Get othercase range * -*************************************************/ - -/* This function is passed the start and end of a class range in UCT mode. It -searches up the characters, looking for ranges of characters in the "other" -case. Each call returns the next one, updating the start address. A character -with multiple other cases is returned on its own with a special return value. - -Arguments: - cptr points to starting character value; updated - d end value - ocptr where to put start of othercase range - odptr where to put end of othercase range - -Yield: -1 when no more - 0 when a range is returned - >0 the CASESET offset for char with multiple other cases - in this case, ocptr contains the original -*/ - -static int -get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, - uint32_t *odptr) -{ -uint32_t c, othercase, next; -unsigned int co; - -/* Find the first character that has an other case. If it has multiple other -cases, return its case offset value. */ - -for (c = *cptr; c <= d; c++) - { - if ((co = UCD_CASESET(c)) != 0) - { - *ocptr = c++; /* Character that has the set */ - *cptr = c; /* Rest of input range */ - return (int)co; - } - if ((othercase = UCD_OTHERCASE(c)) != c) break; - } - -if (c > d) return -1; /* Reached end of range */ - -/* Found a character that has a single other case. Search for the end of the -range, which is either the end of the input range, or a character that has zero -or more than one other cases. */ - -*ocptr = othercase; -next = othercase + 1; - -for (++c; c <= d; c++) - { - if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break; - next++; - } - -*odptr = next - 1; /* End of othercase range */ -*cptr = c; /* Rest of input range */ -return 0; -} -#endif /* SUPPORT_UNICODE */ - - - -/************************************************* -* Add a character or range to a class * -*************************************************/ - -/* This function packages up the logic of adding a character or range of -characters to a class. The character values in the arguments will be within the -valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is -mutually recursive with the function immediately below. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cb compile data - start start of range character - end end of range character - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, uint32_t start, uint32_t end) -{ -uint32_t c; -uint32_t classbits_end = (end <= 0xff ? end : 0xff); -int n8 = 0; - -/* If caseless matching is required, scan the range and process alternate -cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa. Sometimes we can just extend the original -range. */ - -if ((options & PCRE2_CASELESS) != 0) - { -#ifdef SUPPORT_UNICODE - if ((options & PCRE2_UTF) != 0) - { - int rc; - uint32_t oc, od; - - options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ - c = start; - - while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) - { - /* Handle a single character that has more than one other case. */ - - if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cb, - PRIV(ucd_caseless_sets) + rc, oc); - - /* Do nothing if the other case range is within the original range. */ - - else if (oc >= start && od <= end) continue; - - /* Extend the original range if there is overlap, noting that if oc < c, we - can't have od > end because a subrange is always shorter than the basic - range. Otherwise, use a recursive call to add the additional range. */ - - else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ - else if (od > end && oc <= end + 1) - { - end = od; /* Extend upwards */ - if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); - } - else n8 += add_to_class(classbits, uchardptr, options, cb, oc, od); - } - } - else -#endif /* SUPPORT_UNICODE */ - - /* Not UTF mode */ - - for (c = start; c <= classbits_end; c++) - { - SETBIT(classbits, cb->fcc[c]); - n8++; - } - } - -/* Now handle the original range. Adjust the final value according to the bit -length - this means that the same lists of (e.g.) horizontal spaces can be used -in all cases. */ - -if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR) - end = MAX_NON_UTF_CHAR; - -/* Use the bitmap for characters < 256. Otherwise use extra data.*/ - -for (c = start; c <= classbits_end; c++) - { - /* Regardless of start, c will always be <= 255. */ - SETBIT(classbits, c); - n8++; - } - -#ifdef SUPPORT_WIDE_CHARS -if (start <= 0xff) start = 0xff + 1; - -if (end >= start) - { - PCRE2_UCHAR *uchardata = *uchardptr; - -#ifdef SUPPORT_UNICODE - if ((options & PCRE2_UTF) != 0) - { - if (start < end) - { - *uchardata++ = XCL_RANGE; - uchardata += PRIV(ord2utf)(start, uchardata); - uchardata += PRIV(ord2utf)(end, uchardata); - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - uchardata += PRIV(ord2utf)(start, uchardata); - } - } - else -#endif /* SUPPORT_UNICODE */ - - /* Without UTF support, character values are constrained by the bit length, - and can only be > 256 for 16-bit and 32-bit libraries. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 - {} -#else - if (start < end) - { - *uchardata++ = XCL_RANGE; - *uchardata++ = start; - *uchardata++ = end; - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - *uchardata++ = start; - } -#endif - *uchardptr = uchardata; /* Updata extra data pointer */ - } -#else - (void)uchardptr; /* Avoid compiler warning */ -#endif /* SUPPORT_WIDE_CHARS */ - -return n8; /* Number of 8-bit characters */ -} - - - -/************************************************* -* Add a list of characters to a class * -*************************************************/ - -/* This function is used for adding a list of case-equivalent characters to a -class, and also for adding a list of horizontal or vertical whitespace. If the -list is in order (which it should be), ranges of characters are detected and -handled appropriately. This function is mutually recursive with the function -above. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - except character to omit; this is used when adding lists of - case-equivalent characters to avoid including the one we - already know about - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, const uint32_t *p, unsigned int except) -{ -int n8 = 0; -while (p[0] < NOTACHAR) - { - int n = 0; - if (p[0] != except) - { - while(p[n+1] == p[0] + n + 1) n++; - n8 += add_to_class(classbits, uchardptr, options, cb, p[0], p[n]); - } - p += n + 1; - } -return n8; -} - - - -/************************************************* -* Add characters not in a list to a class * -*************************************************/ - -/* This function is used for adding the complement of a list of horizontal or -vertical whitespace to a class. The list must be in order. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, const uint32_t *p) -{ -BOOL utf = (options & PCRE2_UTF) != 0; -int n8 = 0; -if (p[0] > 0) - n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1); -while (p[0] < NOTACHAR) - { - while (p[1] == p[0] + 1) p++; - n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1, - (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); - p++; - } -return n8; -} - - - -/************************************************* -* Process (*VERB) name for escapes * -*************************************************/ - -/* This function is called when the PCRE2_ALT_VERBNAMES option is set, to -process the characters in a verb's name argument. It is called twice, once with -codeptr == NULL, to find out the length of the processed name, and again to put -the name into memory. - -Arguments: - ptrptr pointer to the input pointer - codeptr pointer to the compiled code pointer - errorcodeptr pointer to the error code - options the options bits - utf TRUE if processing UTF - cb compile data block - -Returns: length of the processed name, or < 0 on error -*/ - -static int -process_verb_name(PCRE2_SPTR *ptrptr, PCRE2_UCHAR **codeptr, int *errorcodeptr, - uint32_t options, BOOL utf, compile_block *cb) -{ -int32_t arglen = 0; -BOOL inescq = FALSE; -PCRE2_SPTR ptr = *ptrptr; -PCRE2_UCHAR *code = (codeptr == NULL)? NULL : *codeptr; - -for (; ptr < cb->end_pattern; ptr++) - { - uint32_t x = *ptr; - - /* Skip over literals */ - - if (inescq) - { - if (x == CHAR_BACKSLASH && ptr[1] == CHAR_E) - { - inescq = FALSE; - ptr++;; - continue; - } - } - - else /* Not a literal character */ - { - if (x == CHAR_RIGHT_PARENTHESIS) break; - - /* Skip over comments and whitespace in extended mode. */ - - if ((options & PCRE2_EXTENDED) != 0) - { - PCRE2_SPTR wscptr = ptr; - while (MAX_255(x) && (cb->ctypes[x] & ctype_space) != 0) x = *(++ptr); - if (x == CHAR_NUMBER_SIGN) - { - ptr++; - while (*ptr != CHAR_NULL || ptr < cb->end_pattern) - { - if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ - { /* IS_NEWLINE sets cb->nllen. */ - ptr += cb->nllen; - break; - } - ptr++; -#ifdef SUPPORT_UNICODE - if (utf) FORWARDCHAR(ptr); -#endif - } - } - - /* If we have skipped any characters, restart the loop. */ - - if (ptr > wscptr) - { - ptr--; - continue; - } - } - - /* Process escapes */ - - if (x == '\\') - { - int rc; - *errorcodeptr = 0; - rc = PRIV(check_escape)(&ptr, cb->end_pattern, &x, errorcodeptr, options, - FALSE, cb); - *ptrptr = ptr; /* For possible error */ - if (*errorcodeptr != 0) return -1; - if (rc != 0) - { - if (rc == ESC_Q) - { - inescq = TRUE; - continue; - } - if (rc == ESC_E) continue; - *errorcodeptr = ERR40; - return -1; - } - } - } - - /* We have the next character in the name. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - if (code == NULL) /* Just want the length */ - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - int i; - for (i = 0; i < PRIV(utf8_table1_size); i++) - if ((int)x <= PRIV(utf8_table1)[i]) break; - arglen += i; -#elif PCRE2_CODE_UNIT_WIDTH == 16 - if (x > 0xffff) arglen++; -#endif - } - else - { - PCRE2_UCHAR cbuff[8]; - x = PRIV(ord2utf)(x, cbuff); - memcpy(code, cbuff, CU2BYTES(x)); - code += x; - } - } - else -#endif /* SUPPORT_UNICODE */ - - /* Not UTF */ - { - if (code != NULL) *code++ = x; - } - - arglen++; - - if ((unsigned int)arglen > MAX_MARK) - { - *errorcodeptr = ERR76; - *ptrptr = ptr; - return -1; - } - } - -/* Update the pointers before returning. */ - -*ptrptr = ptr; -if (codeptr != NULL) *codeptr = code; -return arglen; -} - - - -/************************************************* -* Macro for the next two functions * -*************************************************/ - -/* Both scan_for_captures() and compile_branch() use this macro to generate a -fragment of code that reads the characters of a name and sets its length -(checking for not being too long). Count the characters dynamically, to avoid -the possibility of integer overflow. The same macro is used for reading *VERB -names. */ - -#define READ_NAME(ctype, errno, errset) \ - namelen = 0; \ - while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0) \ - { \ - ptr++; \ - namelen++; \ - if (namelen > MAX_NAME_SIZE) \ - { \ - errset = errno; \ - goto FAILED; \ - } \ - } - - - -/************************************************* -* Scan regex to identify named groups * -*************************************************/ - -/* This function is called first of all, to scan for named capturing groups so -that information about them is fully available to both the compiling scans. -It skips over everything except parenthesized items. - -Arguments: - ptrptr points to pointer to the start of the pattern - options compiling dynamic options - cb pointer to the compile data block - -Returns: zero on success or a non-zero error code, with pointer updated -*/ - -typedef struct nest_save { - uint16_t nest_depth; - uint16_t reset_group; - uint16_t max_group; - uint16_t flags; -} nest_save; - -#define NSF_RESET 0x0001u -#define NSF_EXTENDED 0x0002u -#define NSF_DUPNAMES 0x0004u - -static uint32_t scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options, - compile_block *cb) -{ -uint32_t c; -uint32_t delimiter; -uint32_t nest_depth = 0; -uint32_t set, unset, *optset; -int errorcode = 0; -int escape; -int namelen; -int i; -BOOL inescq = FALSE; -BOOL isdupname; -BOOL skiptoket = FALSE; -BOOL utf = (options & PCRE2_UTF) != 0; -BOOL negate_class; -PCRE2_SPTR name; -PCRE2_SPTR start; -PCRE2_SPTR ptr = *ptrptr; -named_group *ng; -nest_save *top_nest = NULL; -nest_save *end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size); - -/* The size of the nest_save structure might not be a factor of the size of the -workspace. Therefore we must round down end_nests so as to correctly avoid -creating a nest_save that spans the end of the workspace. */ - -end_nests = (nest_save *)((char *)end_nests - - ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save))); - -/* Now scan the pattern */ - -for (; ptr < cb->end_pattern; ptr++) - { - c = *ptr; - - /* Parenthesized groups set skiptoket when all following characters up to the - next closing parenthesis must be ignored. The parenthesis itself must be - processed (to end the nested parenthesized item). */ - - if (skiptoket) - { - if (c != CHAR_RIGHT_PARENTHESIS) continue; - skiptoket = FALSE; - } - - /* Skip over literals */ - - if (inescq) - { - if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) - { - inescq = FALSE; - ptr++; - } - continue; - } - - /* Skip over comments and whitespace in extended mode. Need a loop to handle - whitespace after a comment. */ - - if ((options & PCRE2_EXTENDED) != 0) - { - for (;;) - { - while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); - if (c != CHAR_NUMBER_SIGN) break; - ptr++; - while (*ptr != CHAR_NULL) - { - if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ - { /* IS_NEWLINE sets cb->nllen. */ - ptr += cb->nllen; - break; - } - ptr++; -#ifdef SUPPORT_UNICODE - if (utf) FORWARDCHAR(ptr); -#endif - } - c = *ptr; /* Either NULL or the char after a newline */ - } - } - - /* Process the next pattern item. */ - - switch(c) - { - default: /* Most characters are just skipped */ - break; - - /* Skip escapes except for \Q */ - - case CHAR_BACKSLASH: - errorcode = 0; - escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode, options, - FALSE, cb); - if (errorcode != 0) goto FAILED; - if (escape == ESC_Q) inescq = TRUE; - break; - - /* Skip a character class. The syntax is complicated so we have to - replicate some of what happens when a class is processed for real. */ - - case CHAR_LEFT_SQUARE_BRACKET: - if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0 || - PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) - { - ptr += 6; - break; - } - - /* If the first character is '^', set the negation flag (not actually used - here, except to recognize only one ^) and skip it. If the first few - characters (either before or after ^) are \Q\E or \E we skip them too. This - makes for compatibility with Perl. */ - - negate_class = FALSE; - for (;;) - { - c = *(++ptr); /* First character in class */ - if (c == CHAR_BACKSLASH) - { - if (ptr[1] == CHAR_E) - ptr++; - else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) - ptr += 3; - else - break; - } - else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) - negate_class = TRUE; - else break; - } - - if (c == CHAR_RIGHT_SQUARE_BRACKET && - (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) - break; - - /* Loop for the contents of the class */ - - for (;;) - { - PCRE2_SPTR tempptr; - - if (c == CHAR_NULL && ptr >= cb->end_pattern) - { - errorcode = ERR6; /* Missing terminating ']' */ - goto FAILED; - } - -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(c)) - { /* Braces are required because the */ - GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ - } -#endif - - /* Inside \Q...\E everything is literal except \E */ - - if (inescq) - { - if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ - { - inescq = FALSE; /* Reset literal state */ - ptr++; /* Skip the 'E' */ - } - goto CONTINUE_CLASS; - } - - /* Skip POSIX class names. */ - if (c == CHAR_LEFT_SQUARE_BRACKET && - (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || - ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) - { - ptr = tempptr + 1; - } - else if (c == CHAR_BACKSLASH) - { - errorcode = 0; - escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode, - options, TRUE, cb); - if (errorcode != 0) goto FAILED; - if (escape == ESC_Q) inescq = TRUE; - } - - CONTINUE_CLASS: - c = *(++ptr); - if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; - } /* End of class-processing loop */ - break; - - /* This is the real work of this function - handling parentheses. */ - - case CHAR_LEFT_PARENTHESIS: - nest_depth++; - - if (ptr[1] != CHAR_QUESTION_MARK) - { - if (ptr[1] != CHAR_ASTERISK) - { - if ((options & PCRE2_NO_AUTO_CAPTURE) == 0) cb->bracount++; - } - - /* (*something) - just skip to closing ket unless PCRE2_ALT_VERBNAMES is - set, in which case we have to process escapes in the string after the - name. */ - - else - { - ptr += 2; - while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0) ptr++; - if (*ptr == CHAR_COLON) - { - ptr++; - if ((options & PCRE2_ALT_VERBNAMES) != 0) - { - if (process_verb_name(&ptr, NULL, &errorcode, options, utf, cb) < 0) - goto FAILED; - } - else - { - while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) - ptr++; - } - } - nest_depth--; - } - } - - /* Handle (?...) groups */ - - else switch(ptr[2]) - { - default: - ptr += 2; - if (ptr[0] == CHAR_R || /* (?R) */ - ptr[0] == CHAR_NUMBER_SIGN || /* (?#) */ - IS_DIGIT(ptr[0]) || /* (?n) */ - (ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1]))) /* (?-n) */ - { - skiptoket = TRUE; - break; - } - - /* Handle (?| and (?imsxJU: which are the only other valid forms. Both - need a new block on the nest stack. */ - - if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace); - else if (++top_nest >= end_nests) - { - errorcode = ERR84; - goto FAILED; - } - top_nest->nest_depth = nest_depth; - top_nest->flags = 0; - if ((options & PCRE2_EXTENDED) != 0) top_nest->flags |= NSF_EXTENDED; - if ((options & PCRE2_DUPNAMES) != 0) top_nest->flags |= NSF_DUPNAMES; - - if (*ptr == CHAR_VERTICAL_LINE) - { - top_nest->reset_group = cb->bracount; - top_nest->max_group = cb->bracount; - top_nest->flags |= NSF_RESET; - cb->external_flags |= PCRE2_DUPCAPUSED; - break; - } - - /* Scan options */ - - top_nest->reset_group = 0; - top_nest->max_group = 0; - - set = unset = 0; - optset = &set; - - /* Need only track (?x: and (?J: at this stage */ - - while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) - { - switch (*ptr++) - { - case CHAR_MINUS: optset = &unset; break; - - case CHAR_x: *optset |= PCRE2_EXTENDED; break; - - case CHAR_J: - *optset |= PCRE2_DUPNAMES; - cb->external_flags |= PCRE2_JCHANGED; - break; - - case CHAR_i: - case CHAR_m: - case CHAR_s: - case CHAR_U: - break; - - default: errorcode = ERR11; - ptr--; /* Correct the offset */ - goto FAILED; - } - } - - options = (options | set) & (~unset); - - /* If the options ended with ')' this is not the start of a nested - group with option changes, so the options change at this level. If the - previous level set up a nest block, discard the one we have just created. - Otherwise adjust it for the previous level. */ - - if (*ptr == CHAR_RIGHT_PARENTHESIS) - { - nest_depth--; - if (top_nest > (nest_save *)(cb->start_workspace) && - (top_nest-1)->nest_depth == nest_depth) top_nest --; - else top_nest->nest_depth = nest_depth; - } - break; - - /* Skip over a numerical or string argument for a callout. */ - - case CHAR_C: - ptr += 2; - if (ptr[1] == CHAR_RIGHT_PARENTHESIS) break; - if (IS_DIGIT(ptr[1])) - { - while (IS_DIGIT(ptr[1])) ptr++; - } - - /* Handle a string argument */ - - else - { - ptr++; - delimiter = 0; - for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) - { - if (*ptr == PRIV(callout_start_delims)[i]) - { - delimiter = PRIV(callout_end_delims)[i]; - break; - } - } - - if (delimiter == 0) - { - errorcode = ERR82; - goto FAILED; - } - - start = ptr; - do - { - if (++ptr >= cb->end_pattern) - { - errorcode = ERR81; - ptr = start; /* To give a more useful message */ - goto FAILED; - } - if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; - } - while (ptr[0] != delimiter); - } - - /* Check terminating ) */ - - if (ptr[1] != CHAR_RIGHT_PARENTHESIS) - { - errorcode = ERR39; - ptr++; - goto FAILED; - } - break; - - /* Conditional group */ - - case CHAR_LEFT_PARENTHESIS: - if (ptr[3] != CHAR_QUESTION_MARK) /* Not assertion or callout */ - { - nest_depth++; - ptr += 2; - break; - } - - /* Must be an assertion or a callout */ - - switch(ptr[4]) - { - case CHAR_LESS_THAN_SIGN: - if (ptr[5] != CHAR_EXCLAMATION_MARK && ptr[5] != CHAR_EQUALS_SIGN) - goto MISSING_ASSERTION; - /* Fall through */ - - case CHAR_C: - case CHAR_EXCLAMATION_MARK: - case CHAR_EQUALS_SIGN: - ptr++; - break; - - default: - MISSING_ASSERTION: - ptr += 3; /* To improve error message */ - errorcode = ERR28; - goto FAILED; - } - break; - - case CHAR_COLON: - case CHAR_GREATER_THAN_SIGN: - case CHAR_EQUALS_SIGN: - case CHAR_EXCLAMATION_MARK: - case CHAR_AMPERSAND: - case CHAR_PLUS: - ptr += 2; - break; - - case CHAR_P: - if (ptr[3] != CHAR_LESS_THAN_SIGN) - { - ptr += 3; - break; - } - ptr++; - c = CHAR_GREATER_THAN_SIGN; /* Terminator */ - goto DEFINE_NAME; - - case CHAR_LESS_THAN_SIGN: - if (ptr[3] == CHAR_EQUALS_SIGN || ptr[3] == CHAR_EXCLAMATION_MARK) - { - ptr += 3; - break; - } - c = CHAR_GREATER_THAN_SIGN; /* Terminator */ - goto DEFINE_NAME; - - case CHAR_APOSTROPHE: - c = CHAR_APOSTROPHE; /* Terminator */ - - DEFINE_NAME: - name = ptr = ptr + 3; - - if (*ptr == c) /* Empty name */ - { - errorcode = ERR62; - goto FAILED; - } - - if (IS_DIGIT(*ptr)) - { - errorcode = ERR44; /* Group name must start with non-digit */ - goto FAILED; - } - - if (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) == 0) - { - errorcode = ERR24; - goto FAILED; - } - - /* Advance ptr, set namelen and check its length. */ - READ_NAME(ctype_word, ERR48, errorcode); - - if (*ptr != c) - { - errorcode = ERR42; - goto FAILED; - } - - if (cb->names_found >= MAX_NAME_COUNT) - { - errorcode = ERR49; - goto FAILED; - } - - if (namelen + IMM2_SIZE + 1 > cb->name_entry_size) - cb->name_entry_size = namelen + IMM2_SIZE + 1; - - /* We have a valid name for this capturing group. */ - - cb->bracount++; - - /* Scan the list to check for duplicates. For duplicate names, if the - number is the same, break the loop, which causes the name to be - discarded; otherwise, if DUPNAMES is not set, give an error. - If it is set, allow the name with a different number, but continue - scanning in case this is a duplicate with the same number. For - non-duplicate names, give an error if the number is duplicated. */ - - isdupname = FALSE; - ng = cb->named_groups; - for (i = 0; i < cb->names_found; i++, ng++) - { - if (namelen == ng->length && - PRIV(strncmp)(name, ng->name, namelen) == 0) - { - if (ng->number == cb->bracount) break; - if ((options & PCRE2_DUPNAMES) == 0) - { - errorcode = ERR43; - goto FAILED; - } - isdupname = ng->isdup = TRUE; /* Mark as a duplicate */ - cb->dupnames = TRUE; /* Duplicate names exist */ - } - else if (ng->number == cb->bracount) - { - errorcode = ERR65; - goto FAILED; - } - } - - if (i < cb->names_found) break; /* Ignore duplicate with same number */ - - /* Increase the list size if necessary */ - - if (cb->names_found >= cb->named_group_list_size) - { - int newsize = cb->named_group_list_size * 2; - named_group *newspace = - cb->cx->memctl.malloc(newsize * sizeof(named_group), - cb->cx->memctl.memory_data); - if (newspace == NULL) - { - errorcode = ERR21; - goto FAILED; - } - - memcpy(newspace, cb->named_groups, - cb->named_group_list_size * sizeof(named_group)); - if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE) - cb->cx->memctl.free((void *)cb->named_groups, - cb->cx->memctl.memory_data); - cb->named_groups = newspace; - cb->named_group_list_size = newsize; - } - - /* Add this name to the list */ - - cb->named_groups[cb->names_found].name = name; - cb->named_groups[cb->names_found].length = namelen; - cb->named_groups[cb->names_found].number = cb->bracount; - cb->named_groups[cb->names_found].isdup = isdupname; - cb->names_found++; - break; - } /* End of (? switch */ - break; /* End of ( handling */ - - /* At an alternation, reset the capture count if we are in a (?| group. */ - - case CHAR_VERTICAL_LINE: - if (top_nest != NULL && top_nest->nest_depth == nest_depth && - (top_nest->flags & NSF_RESET) != 0) - { - if (cb->bracount > top_nest->max_group) - top_nest->max_group = cb->bracount; - cb->bracount = top_nest->reset_group; - } - break; - - /* At a right parenthesis, reset the capture count to the maximum if we - are in a (?| group and/or reset the extended option. */ - - case CHAR_RIGHT_PARENTHESIS: - if (top_nest != NULL && top_nest->nest_depth == nest_depth) - { - if ((top_nest->flags & NSF_RESET) != 0 && - top_nest->max_group > cb->bracount) - cb->bracount = top_nest->max_group; - if ((top_nest->flags & NSF_EXTENDED) != 0) options |= PCRE2_EXTENDED; - else options &= ~PCRE2_EXTENDED; - if ((top_nest->flags & NSF_DUPNAMES) != 0) options |= PCRE2_DUPNAMES; - else options &= ~PCRE2_DUPNAMES; - if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; - else top_nest--; - } - if (nest_depth > 0) nest_depth--; /* Can be 0 for unmatched ) */ - break; - } - } - -cb->final_bracount = cb->bracount; -return 0; - -FAILED: -*ptrptr = ptr; -return errorcode; -} - - - -/************************************************* -* Compile one branch * -*************************************************/ - -/* Scan the pattern, compiling it into the a vector. If the options are -changed during the branch, the pointer is used to change the external options -bits. This function is used during the pre-compile phase when we are trying -to find out the amount of memory needed, as well as during the real compile -phase. The value of lengthptr distinguishes the two phases. - -Arguments: - optionsptr pointer to the option bits - codeptr points to the pointer to the current code point - ptrptr points to the current pattern pointer - errorcodeptr points to error code variable - firstcuptr place to put the first required code unit - firstcuflagsptr place to put the first code unit flags, or a negative number - reqcuptr place to put the last required code unit - reqcuflagsptr place to put the last required code unit flags, or a negative number - bcptr points to current branch chain - cond_depth conditional nesting depth - cb contains pointers to tables etc. - lengthptr NULL during the real compile phase - points to length accumulator during pre-compile phase - -Returns: TRUE on success - FALSE, with *errorcodeptr set non-zero on error -*/ - -static BOOL -compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, - PCRE2_SPTR *ptrptr, int *errorcodeptr, - uint32_t *firstcuptr, int32_t *firstcuflagsptr, - uint32_t *reqcuptr, int32_t *reqcuflagsptr, - branch_chain *bcptr, int cond_depth, - compile_block *cb, size_t *lengthptr) -{ -int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ -int bravalue = 0; -uint32_t greedy_default, greedy_non_default; -uint32_t repeat_type, op_type; -uint32_t options = *optionsptr; /* May change dynamically */ -uint32_t firstcu, reqcu; -int32_t firstcuflags, reqcuflags; -uint32_t zeroreqcu, zerofirstcu; -int32_t zeroreqcuflags, zerofirstcuflags; -int32_t req_caseopt, reqvary, tempreqvary; -int after_manual_callout = 0; -int escape; -size_t length_prevgroup = 0; -register uint32_t c; -register PCRE2_UCHAR *code = *codeptr; -PCRE2_UCHAR *last_code = code; -PCRE2_UCHAR *orig_code = code; -PCRE2_UCHAR *tempcode; -BOOL inescq = FALSE; -BOOL groupsetfirstcu = FALSE; -PCRE2_SPTR ptr = *ptrptr; -PCRE2_SPTR tempptr; -PCRE2_UCHAR *previous = NULL; -PCRE2_UCHAR *previous_callout = NULL; -uint8_t classbits[32]; - -/* We can fish out the UTF setting once and for all into a BOOL, but we must -not do this for other options (e.g. PCRE2_EXTENDED) because they may change -dynamically as we process the pattern. */ - -#ifdef SUPPORT_UNICODE -BOOL utf = (options & PCRE2_UTF) != 0; -#if PCRE2_CODE_UNIT_WIDTH != 32 -PCRE2_UCHAR utf_units[6]; /* For setting up multi-cu chars */ -#endif - -#else /* No UTF support */ -BOOL utf = FALSE; -#endif - -/* Helper variables for OP_XCLASS opcode (for characters > 255). We define -class_uchardata always so that it can be passed to add_to_class() always, -though it will not be used in non-UTF 8-bit cases. This avoids having to supply -alternative calls for the different cases. */ - -PCRE2_UCHAR *class_uchardata; -#ifdef SUPPORT_WIDE_CHARS -BOOL xclass; -PCRE2_UCHAR *class_uchardata_base; -#endif - -/* Set up the default and non-default settings for greediness */ - -greedy_default = ((options & PCRE2_UNGREEDY) != 0); -greedy_non_default = greedy_default ^ 1; - -/* Initialize no first unit, no required unit. REQ_UNSET means "no char -matching encountered yet". It gets changed to REQ_NONE if we hit something that -matches a non-fixed first unit; reqcu just remains unset if we never find one. - -When we hit a repeat whose minimum is zero, we may have to adjust these values -to take the zero repeat into account. This is implemented by setting them to -zerofirstcu and zeroreqcu when such a repeat is encountered. The individual -item types that can be repeated set these backoff variables appropriately. */ - -firstcu = reqcu = zerofirstcu = zeroreqcu = 0; -firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET; - -/* The variable req_caseopt contains either the REQ_CASELESS value or zero, -according to the current setting of the caseless flag. The REQ_CASELESS value -leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables -to record the case status of the value. This is used only for ASCII characters. -*/ - -req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS:0; - -/* Switch on next character until the end of the branch */ - -for (;; ptr++) - { - BOOL negate_class; - BOOL should_flip_negation; - BOOL match_all_or_no_wide_chars; - BOOL possessive_quantifier; - BOOL is_quantifier; - BOOL is_recurse; - BOOL is_dupname; - BOOL reset_bracount; - int class_has_8bitchar; - int class_one_char; -#ifdef SUPPORT_WIDE_CHARS - BOOL xclass_has_prop; -#endif - int recno; /* Must be signed */ - int refsign; /* Must be signed */ - int terminator; /* Must be signed */ - unsigned int mclength; - unsigned int tempbracount; - uint32_t ec; - uint32_t newoptions; - uint32_t skipunits; - uint32_t subreqcu, subfirstcu; - int32_t subreqcuflags, subfirstcuflags; /* Must be signed */ - PCRE2_UCHAR mcbuffer[8]; - - /* Get next character in the pattern */ - - c = *ptr; - - /* If we are at the end of a nested substitution, revert to the outer level - string. Nesting only happens one or two levels deep, and the inserted string - is always zero terminated. */ - - if (c == CHAR_NULL && cb->nestptr[0] != NULL) - { - ptr = cb->nestptr[0]; - cb->nestptr[0] = cb->nestptr[1]; - cb->nestptr[1] = NULL; - c = *ptr; - } - - /* If we are in the pre-compile phase, accumulate the length used for the - previous cycle of this loop. */ - - if (lengthptr != NULL) - { - if (code > cb->start_workspace + cb->workspace_size - - WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ - { - *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)? - ERR52 : ERR86; - goto FAILED; - } - - /* There is at least one situation where code goes backwards: this is the - case of a zero quantifier after a class (e.g. [ab]{0}). At compile time, - the class is simply eliminated. However, it is created first, so we have to - allow memory for it. Therefore, don't ever reduce the length at this point. - */ - - if (code < last_code) code = last_code; - - /* Paranoid check for integer overflow */ - - if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code)) - { - *errorcodeptr = ERR20; - goto FAILED; - } - *lengthptr += code - last_code; - - /* If "previous" is set and it is not at the start of the work space, move - it back to there, in order to avoid filling up the work space. Otherwise, - if "previous" is NULL, reset the current code pointer to the start. */ - - if (previous != NULL) - { - if (previous > orig_code) - { - memmove(orig_code, previous, CU2BYTES(code - previous)); - code -= previous - orig_code; - previous = orig_code; - } - } - else code = orig_code; - - /* Remember where this code item starts so we can pick up the length - next time round. */ - - last_code = code; - } - - /* Before doing anything else we must handle all the special items that do - nothing, and which may come between an item and its quantifier. Otherwise, - when auto-callouts are enabled, a callout gets incorrectly inserted before - the quantifier is recognized. After recognizing a "do nothing" item, restart - the loop in case another one follows. */ - - /* If c is not NULL we are not at the end of the pattern. If it is NULL, we - may still be in the pattern with a NULL data item. In these cases, if we are - in \Q...\E, check for the \E that ends the literal string; if not, we have a - literal character. If not in \Q...\E, an isolated \E is ignored. */ - - if (c != CHAR_NULL || ptr < cb->end_pattern) - { - if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) - { - inescq = FALSE; - ptr++; - continue; - } - else if (inescq) /* Literal character */ - { - if (previous_callout != NULL) - { - if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ - complete_callout(previous_callout, ptr, cb); - previous_callout = NULL; - } - if ((options & PCRE2_AUTO_CALLOUT) != 0) - { - previous_callout = code; - code = auto_callout(code, ptr, cb); - } - goto NORMAL_CHAR; - } - - /* Check for the start of a \Q...\E sequence. We must do this here rather - than later in case it is immediately followed by \E, which turns it into a - "do nothing" sequence. */ - - if (c == CHAR_BACKSLASH && ptr[1] == CHAR_Q) - { - inescq = TRUE; - ptr++; - continue; - } - } - - /* In extended mode, skip white space and #-comments that end at newline. */ - - if ((options & PCRE2_EXTENDED) != 0) - { - PCRE2_SPTR wscptr = ptr; - while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); - if (c == CHAR_NUMBER_SIGN) - { - ptr++; - while (ptr < cb->end_pattern) - { - if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ - { /* IS_NEWLINE sets cb->nllen. */ - ptr += cb->nllen; - break; - } - ptr++; -#ifdef SUPPORT_UNICODE - if (utf) FORWARDCHAR(ptr); -#endif - } - } - - /* If we skipped any characters, restart the loop. Otherwise, we didn't see - a comment. */ - - if (ptr > wscptr) - { - ptr--; - continue; - } - } - - /* Skip over (?# comments. */ - - if (c == CHAR_LEFT_PARENTHESIS && ptr[1] == CHAR_QUESTION_MARK && - ptr[2] == CHAR_NUMBER_SIGN) - { - ptr += 3; - while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr != CHAR_RIGHT_PARENTHESIS) - { - *errorcodeptr = ERR18; - goto FAILED; - } - continue; - } - - /* End of processing "do nothing" items. See if the next thing is a - quantifier. */ - - is_quantifier = - c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK || - (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1)); - - /* Fill in length of a previous callout and create an auto callout if - required, except when the next thing is a quantifier or when processing a - property substitution string for \w etc in UCP mode. */ - - if (!is_quantifier && cb->nestptr[0] == NULL) - { - if (previous_callout != NULL && after_manual_callout-- <= 0) - { - if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ - complete_callout(previous_callout, ptr, cb); - previous_callout = NULL; - } - - if ((options & PCRE2_AUTO_CALLOUT) != 0) - { - previous_callout = code; - code = auto_callout(code, ptr, cb); - } - } - - /* Process the next pattern item. */ - - switch(c) - { - /* ===================================================================*/ - /* The branch terminates at string end or | or ) */ - - case CHAR_NULL: - if (ptr < cb->end_pattern) goto NORMAL_CHAR; /* Zero data character */ - /* Fall through */ - - case CHAR_VERTICAL_LINE: - case CHAR_RIGHT_PARENTHESIS: - *firstcuptr = firstcu; - *firstcuflagsptr = firstcuflags; - *reqcuptr = reqcu; - *reqcuflagsptr = reqcuflags; - *codeptr = code; - *ptrptr = ptr; - if (lengthptr != NULL) - { - if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code)) - { - *errorcodeptr = ERR20; - goto FAILED; - } - *lengthptr += code - last_code; /* To include callout length */ - } - return TRUE; - - - /* ===================================================================*/ - /* Handle single-character metacharacters. In multiline mode, ^ disables - the setting of any following char as a first character. */ - - case CHAR_CIRCUMFLEX_ACCENT: - previous = NULL; - if ((options & PCRE2_MULTILINE) != 0) - { - if (firstcuflags == REQ_UNSET) - zerofirstcuflags = firstcuflags = REQ_NONE; - *code++ = OP_CIRCM; - } - else *code++ = OP_CIRC; - break; - - case CHAR_DOLLAR_SIGN: - previous = NULL; - *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL; - break; - - /* There can never be a first char if '.' is first, whatever happens about - repeats. The value of reqcu doesn't change either. */ - - case CHAR_DOT: - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - previous = code; - *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY; - break; - - - /* ===================================================================*/ - /* Character classes. If the included characters are all < 256, we build a - 32-byte bitmap of the permitted characters, except in the special case - where there is only one such character. For negated classes, we build the - map as usual, then invert it at the end. However, we use a different opcode - so that data characters > 255 can be handled correctly. - - If the class contains characters outside the 0-255 range, a different - opcode is compiled. It may optionally have a bit map for characters < 256, - but those above are are explicitly listed afterwards. A flag byte tells - whether the bitmap is present, and whether this is a negated class or not. - - An isolated ']' character is not treated specially, so is just another data - character. In earlier versions of PCRE that used the original API there was - a "JavaScript compatibility mode" in which it gave an error. However, - JavaScript itself has changed in this respect so there is no longer any - need for this special handling. - - In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is - used for "start of word" and "end of word". As these are otherwise illegal - sequences, we don't break anything by recognizing them. They are replaced - by \b(?=\w) and \b(?<=\w) respectively. This can only happen at the top - nesting level, as no other inserted sequences will contains these oddities. - Sequences like [a[:<:]] are erroneous and are handled by the normal code - below. */ - - case CHAR_LEFT_SQUARE_BRACKET: - if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0) - { - cb->nestptr[0] = ptr + 7; - ptr = sub_start_of_word; /* Do not combine these statements; clang's */ - ptr--; /* sanitizer moans about a negative index. */ - continue; - } - - if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) - { - cb->nestptr[0] = ptr + 7; - ptr = sub_end_of_word; /* Do not combine these statements; clang's */ - ptr--; /* sanitizer moans about a negative index. */ - continue; - } - - /* Handle a real character class. */ - - previous = code; - - /* PCRE supports POSIX class stuff inside a class. Perl gives an error if - they are encountered at the top level, so we'll do that too. */ - - if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || - ptr[1] == CHAR_EQUALS_SIGN) && - check_posix_syntax(ptr, &tempptr)) - { - *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR12 : ERR13; - goto FAILED; - } - - /* If the first character is '^', set the negation flag and skip it. Also, - if the first few characters (either before or after ^) are \Q\E or \E we - skip them too. This makes for compatibility with Perl. */ - - negate_class = FALSE; - for (;;) - { - c = *(++ptr); - if (c == CHAR_BACKSLASH) - { - if (ptr[1] == CHAR_E) - ptr++; - else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) - ptr += 3; - else - break; - } - else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) - negate_class = TRUE; - else break; - } - - /* Empty classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set. Otherwise, - an initial ']' is taken as a data character -- the code below handles - that. When empty classes are allowed, [] must always fail, so generate - OP_FAIL, whereas [^] must match any character, so generate OP_ALLANY. */ - - if (c == CHAR_RIGHT_SQUARE_BRACKET && - (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) - { - *code++ = negate_class? OP_ALLANY : OP_FAIL; - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - break; - } - - /* If a non-extended class contains a negative special such as \S, we need - to flip the negation flag at the end, so that support for characters > 255 - works correctly (they are all included in the class). An extended class may - need to insert specific matching or non-matching code for wide characters. - */ - - should_flip_negation = match_all_or_no_wide_chars = FALSE; - - /* Extended class (xclass) will be used when characters > 255 - might match. */ - -#ifdef SUPPORT_WIDE_CHARS - xclass = FALSE; - class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ - class_uchardata_base = class_uchardata; /* Save the start */ -#endif - - /* For optimization purposes, we track some properties of the class: - class_has_8bitchar will be non-zero if the class contains at least one 256 - character with a code point less than 256; class_one_char will be 1 if the - class contains just one character; xclass_has_prop will be TRUE if Unicode - property checks are present in the class. */ - - class_has_8bitchar = 0; - class_one_char = 0; -#ifdef SUPPORT_WIDE_CHARS - xclass_has_prop = FALSE; -#endif - - /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map - in a temporary bit of memory, in case the class contains fewer than two - 8-bit characters because in that case the compiled code doesn't use the bit - map. */ - - memset(classbits, 0, 32 * sizeof(uint8_t)); - - /* Process characters until ] is reached. As the test is at the end of the - loop, an initial ] is taken as a data character. At the start of the loop, - c contains the first code unit of the character. If it is zero, check for - the end of the pattern, to allow binary zero as data. */ - - for(;;) - { - PCRE2_SPTR oldptr; -#ifdef EBCDIC - BOOL range_is_literal = TRUE; -#endif - - if (c == CHAR_NULL && ptr >= cb->end_pattern) - { - *errorcodeptr = ERR6; /* Missing terminating ']' */ - goto FAILED; - } - -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(c)) - { /* Braces are required because the */ - GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ - } -#endif - - /* Inside \Q...\E everything is literal except \E */ - - if (inescq) - { - if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ - { - inescq = FALSE; /* Reset literal state */ - ptr++; /* Skip the 'E' */ - goto CONTINUE_CLASS; /* Carry on with next char */ - } - goto CHECK_RANGE; /* Could be range if \E follows */ - } - - /* Handle POSIX class names. Perl allows a negation extension of the - form [:^name:]. A square bracket that doesn't match the syntax is - treated as a literal. We also recognize the POSIX constructions - [.ch.] and [=ch=] ("collating elements") and fault them, as Perl - 5.6 and 5.8 do. */ - - if (c == CHAR_LEFT_SQUARE_BRACKET && - (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || - ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) - { - BOOL local_negate = FALSE; - int posix_class, taboffset, tabopt; - register const uint8_t *cbits = cb->cbits; - uint8_t pbits[32]; - - if (ptr[1] != CHAR_COLON) - { - *errorcodeptr = ERR13; - goto FAILED; - } - - ptr += 2; - if (*ptr == CHAR_CIRCUMFLEX_ACCENT) - { - local_negate = TRUE; - should_flip_negation = TRUE; /* Note negative special */ - ptr++; - } - - posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); - if (posix_class < 0) - { - *errorcodeptr = ERR30; - goto FAILED; - } - - /* If matching is caseless, upper and lower are converted to - alpha. This relies on the fact that the class table starts with - alpha, lower, upper as the first 3 entries. */ - - if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) - posix_class = 0; - - /* When PCRE2_UCP is set, some of the POSIX classes are converted to - different escape sequences that use Unicode properties \p or \P. Others - that are not available via \p or \P generate XCL_PROP/XCL_NOTPROP - directly. UCP support is not available unless UTF support is.*/ - -#ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0) - { - unsigned int ptype = 0; - int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0); - - /* The posix_substitutes table specifies which POSIX classes can be - converted to \p or \P items. This can only happen at top nestling - level, as there will never be a POSIX class in a string that is - substituted for something else. */ - - if (posix_substitutes[pc] != NULL) - { - cb->nestptr[0] = tempptr + 1; - ptr = posix_substitutes[pc] - 1; - goto CONTINUE_CLASS; - } - - /* There are three other classes that generate special property calls - that are recognized only in an XCLASS. */ - - else switch(posix_class) - { - case PC_GRAPH: - ptype = PT_PXGRAPH; - /* Fall through */ - case PC_PRINT: - if (ptype == 0) ptype = PT_PXPRINT; - /* Fall through */ - case PC_PUNCT: - if (ptype == 0) ptype = PT_PXPUNCT; - *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = ptype; - *class_uchardata++ = 0; - xclass_has_prop = TRUE; - ptr = tempptr + 1; - goto CONTINUE_CLASS; - - /* For the other POSIX classes (ascii, xdigit) we are going to fall - through to the non-UCP case and build a bit map for characters with - code points less than 256. However, if we are in a negated POSIX - class, characters with code points greater than 255 must either all - match or all not match, depending on whether the whole class is not - or is negated. For example, for [[:^ascii:]... they must all match, - whereas for [^[:^xdigit:]... they must not. - - In the special case where there are no xclass items, this is - automatically handled by the use of OP_CLASS or OP_NCLASS, but an - explicit range is needed for OP_XCLASS. Setting a flag here causes - the range to be generated later when it is known that OP_XCLASS is - required. */ - - default: - match_all_or_no_wide_chars |= local_negate; - break; - } - } -#endif /* SUPPORT_UNICODE */ - - /* In the non-UCP case, or when UCP makes no difference, we build the - bit map for the POSIX class in a chunk of local store because we may be - adding and subtracting from it, and we don't want to subtract bits that - may be in the main map already. At the end we or the result into the - bit map that is being built. */ - - posix_class *= 3; - - /* Copy in the first table (always present) */ - - memcpy(pbits, cbits + posix_class_maps[posix_class], - 32 * sizeof(uint8_t)); - - /* If there is a second table, add or remove it as required. */ - - taboffset = posix_class_maps[posix_class + 1]; - tabopt = posix_class_maps[posix_class + 2]; - - if (taboffset >= 0) - { - if (tabopt >= 0) - for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; - else - for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; - } - - /* Now see if we need to remove any special characters. An option - value of 1 removes vertical space and 2 removes underscore. */ - - if (tabopt < 0) tabopt = -tabopt; - if (tabopt == 1) pbits[1] &= ~0x3c; - else if (tabopt == 2) pbits[11] &= 0x7f; - - /* Add the POSIX table or its complement into the main table that is - being built and we are done. */ - - if (local_negate) - for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c]; - else - for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; - - ptr = tempptr + 1; - /* Every class contains at least one < 256 character. */ - class_has_8bitchar = 1; - /* Every class contains at least two characters. */ - class_one_char = 2; - goto CONTINUE_CLASS; /* End of POSIX syntax handling */ - } - - /* Backslash may introduce a single character, or it may introduce one - of the specials, which just set a flag. The sequence \b is a special - case. Inside a class (and only there) it is treated as backspace. We - assume that other escapes have more than one character in them, so - speculatively set both class_has_8bitchar and class_one_char bigger - than one. Unrecognized escapes fall through and are faulted. */ - - if (c == CHAR_BACKSLASH) - { - escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr, - options, TRUE, cb); - if (*errorcodeptr != 0) goto FAILED; - if (escape == 0) /* Escaped single char */ - { - c = ec; -#ifdef EBCDIC - range_is_literal = FALSE; -#endif - } - else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ - else if (escape == ESC_N) /* \N is not supported in a class */ - { - *errorcodeptr = ERR71; - goto FAILED; - } - else if (escape == ESC_Q) /* Handle start of quoted string */ - { - if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) - { - ptr += 2; /* avoid empty string */ - } - else inescq = TRUE; - goto CONTINUE_CLASS; - } - else if (escape == ESC_E) goto CONTINUE_CLASS; /* Ignore orphan \E */ - - else /* Handle \d-type escapes */ - { - register const uint8_t *cbits = cb->cbits; - /* Every class contains at least two < 256 characters. */ - class_has_8bitchar++; - /* Every class contains at least two characters. */ - class_one_char += 2; - - switch (escape) - { -#ifdef SUPPORT_UNICODE - case ESC_du: /* These are the values given for \d etc */ - case ESC_DU: /* when PCRE2_UCP is set. We replace the */ - case ESC_wu: /* escape sequence with an appropriate \p */ - case ESC_WU: /* or \P to test Unicode properties instead */ - case ESC_su: /* of the default ASCII testing. This might be */ - case ESC_SU: /* a 2nd-level nesting for [[:<:]] or [[:>:]]. */ - cb->nestptr[1] = cb->nestptr[0]; - cb->nestptr[0] = ptr; - ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ - class_has_8bitchar--; /* Undo! */ - break; -#endif - case ESC_d: - for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; - break; - - case ESC_D: - should_flip_negation = TRUE; - for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; - break; - - case ESC_w: - for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; - break; - - case ESC_W: - should_flip_negation = TRUE; - for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; - break; - - /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl - 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was - previously set by something earlier in the character class. - Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so - we could just adjust the appropriate bit. From PCRE 8.34 we no - longer treat \s and \S specially. */ - - case ESC_s: - for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; - break; - - case ESC_S: - should_flip_negation = TRUE; - for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; - break; - - /* The rest apply in both UCP and non-UCP cases. */ - - case ESC_h: - (void)add_list_to_class(classbits, &class_uchardata, options, cb, - PRIV(hspace_list), NOTACHAR); - break; - - case ESC_H: - (void)add_not_list_to_class(classbits, &class_uchardata, options, - cb, PRIV(hspace_list)); - break; - - case ESC_v: - (void)add_list_to_class(classbits, &class_uchardata, options, cb, - PRIV(vspace_list), NOTACHAR); - break; - - case ESC_V: - (void)add_not_list_to_class(classbits, &class_uchardata, options, - cb, PRIV(vspace_list)); - break; - - case ESC_p: - case ESC_P: -#ifdef SUPPORT_UNICODE - { - BOOL negated; - unsigned int ptype = 0, pdata = 0; - if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb)) - goto FAILED; - *class_uchardata++ = ((escape == ESC_p) != negated)? - XCL_PROP : XCL_NOTPROP; - *class_uchardata++ = ptype; - *class_uchardata++ = pdata; - xclass_has_prop = TRUE; - class_has_8bitchar--; /* Undo! */ - } - break; -#else - *errorcodeptr = ERR45; - goto FAILED; -#endif - /* Unrecognized escapes are faulted. */ - - default: - *errorcodeptr = ERR7; - goto FAILED; - } - - /* Handled \d-type escape */ - - goto CONTINUE_CLASS; - } - - /* Control gets here if the escape just defined a single character. - This is in c and may be greater than 256. */ - - escape = 0; - } /* End of backslash handling */ - - /* A character may be followed by '-' to form a range. However, Perl does - not permit ']' to be the end of the range. A '-' character at the end is - treated as a literal. Perl ignores orphaned \E sequences entirely. The - code for handling \Q and \E is messy. */ - - CHECK_RANGE: - while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) - { - inescq = FALSE; - ptr += 2; - } - oldptr = ptr; - - /* Remember if \r or \n were explicitly used */ - - if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - - /* Check for range */ - - if (!inescq && ptr[1] == CHAR_MINUS) - { - uint32_t d; - ptr += 2; - while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2; - - /* If we hit \Q (not followed by \E) at this point, go into escaped - mode. */ - - while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q) - { - ptr += 2; - if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) - { ptr += 2; continue; } - inescq = TRUE; - break; - } - - /* Minus (hyphen) at the end of a class is treated as a literal, so put - back the pointer and jump to handle the character that preceded it. */ - - if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) - { - ptr = oldptr; - goto CLASS_SINGLE_CHARACTER; - } - - /* Otherwise, we have a potential range; pick up the next character */ - -#ifdef SUPPORT_UNICODE - if (utf) - { /* Braces are required because the */ - GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ - } - else -#endif - d = *ptr; /* Not UTF mode */ - - /* The second part of a range can be a single-character escape - sequence, but not any of the other escapes. Perl treats a hyphen as a - literal in such circumstances. However, in Perl's warning mode, a - warning is given, so PCRE now faults it as it is almost certainly a - mistake on the user's part. */ - - if (!inescq) - { - if (d == CHAR_BACKSLASH) - { - int descape; - descape = PRIV(check_escape)(&ptr, cb->end_pattern, &d, - errorcodeptr, options, TRUE, cb); - if (*errorcodeptr != 0) goto FAILED; -#ifdef EBCDIC - range_is_literal = FALSE; -#endif - /* 0 means a character was put into d; \b is backspace; any other - special causes an error. */ - - if (descape != 0) - { - if (descape == ESC_b) d = CHAR_BS; else - { - *errorcodeptr = ERR50; - goto FAILED; - } - } - } - - /* A hyphen followed by a POSIX class is treated in the same way. */ - - else if (d == CHAR_LEFT_SQUARE_BRACKET && - (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || - ptr[1] == CHAR_EQUALS_SIGN) && - check_posix_syntax(ptr, &tempptr)) - { - *errorcodeptr = ERR50; - goto FAILED; - } - } - - /* Check that the two values are in the correct order. Optimize - one-character ranges. */ - - if (d < c) - { - *errorcodeptr = ERR8; - goto FAILED; - } - if (d == c) goto CLASS_SINGLE_CHARACTER; /* A few lines below */ - - /* We have found a character range, so single character optimizations - cannot be done anymore. Any value greater than 1 indicates that there - is more than one character. */ - - class_one_char = 2; - - /* Remember an explicit \r or \n, and add the range to the class. */ - - if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - - /* In an EBCDIC environment, Perl treats alphabetic ranges specially - because there are holes in the encoding, and simply using the range A-Z - (for example) would include the characters in the holes. This applies - only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ - -#ifdef EBCDIC - if (range_is_literal && - (cb->ctypes[c] & ctype_letter) != 0 && - (cb->ctypes[d] & ctype_letter) != 0 && - (c <= CHAR_z) == (d <= CHAR_z)) - { - uint32_t uc = (c <= CHAR_z)? 0 : 64; - uint32_t C = c - uc; - uint32_t D = d - uc; - - if (C <= CHAR_i) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_i)? D : CHAR_i) + uc); - C = CHAR_j; - } - - if (C <= D && C <= CHAR_r) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_r)? D : CHAR_r) + uc); - C = CHAR_s; - } - - if (C <= D) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - D + uc); - } - } - else -#endif - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, c, d); - goto CONTINUE_CLASS; /* Go get the next char in the class */ - } - - /* Handle a single character - we can get here for a normal non-escape - char, or after \ that introduces a single character or for an apparent - range that isn't. Only the value 1 matters for class_one_char, so don't - increase it if it is already 2 or more ... just in case there's a class - with a zillion characters in it. */ - - CLASS_SINGLE_CHARACTER: - if (class_one_char < 2) class_one_char++; - - /* If class_one_char is 1 and xclass_has_prop is false, we have the first - single character in the class, and there have been no prior ranges, or - XCLASS items generated by escapes. If this is the final character in the - class, we can optimize by turning the item into a 1-character OP_CHAR[I] - if it's positive, or OP_NOT[I] if it's negative. In the positive case, it - can cause firstcu to be set. Otherwise, there can be no first char if - this item is first, whatever repeat count may follow. In the case of - reqcu, save the previous value for reinstating. */ - - if (!inescq && -#ifdef SUPPORT_UNICODE - !xclass_has_prop && -#endif - class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) - { - ptr++; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - - if (negate_class) - { -#ifdef SUPPORT_UNICODE - int d; -#endif - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - - /* For caseless UTF mode, check whether this character has more than - one other case. If so, generate a special OP_NOTPROP item instead of - OP_NOTI. */ - -#ifdef SUPPORT_UNICODE - if (utf && (options & PCRE2_CASELESS) != 0 && - (d = UCD_CASESET(c)) != 0) - { - *code++ = OP_NOTPROP; - *code++ = PT_CLIST; - *code++ = d; - } - else -#endif - /* Char has only one other case, or UCP not available */ - - { - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; - code += PUTCHAR(c, code); - } - - /* We are finished with this character class */ - - goto END_CLASS; - } - - /* For a single, positive character, get the value into mcbuffer, and - then we can handle this with the normal one-character code. */ - mclength = PUTCHAR(c, mcbuffer); - goto ONE_CHAR; - } /* End of 1-char optimization */ - - /* There is more than one character in the class, or an XCLASS item - has been generated. Add this character to the class. */ - - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, c, c); - - /* Continue to the next character in the class. Closing square bracket - not within \Q..\E ends the class. A NULL character terminates a - nested substitution string, but may be a data character in the main - pattern (tested at the start of this loop). */ - - CONTINUE_CLASS: - c = *(++ptr); - if (c == CHAR_NULL && cb->nestptr[0] != NULL) - { - ptr = cb->nestptr[0]; - cb->nestptr[0] = cb->nestptr[1]; - cb->nestptr[1] = NULL; - c = *(++ptr); - } - -#ifdef SUPPORT_WIDE_CHARS - /* If any wide characters have been encountered, set xclass = TRUE. Then, - in the pre-compile phase, accumulate the length of the wide characters - and reset the pointer. This is so that very large classes that contain a - zillion wide characters do not overwrite the work space (which is on the - stack). */ - - if (class_uchardata > class_uchardata_base) - { - xclass = TRUE; - if (lengthptr != NULL) - { - *lengthptr += class_uchardata - class_uchardata_base; - class_uchardata = class_uchardata_base; - } - } -#endif - /* An unescaped ] ends the class */ - - if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; - } /* End of main class-processing loop */ - - /* If this is the first thing in the branch, there can be no first char - setting, whatever the repeat count. Any reqcu setting must remain - unchanged after any kind of repeat. */ - - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - - /* If there are characters with values > 255, or Unicode property settings - (\p or \P), we have to compile an extended class, with its own opcode, - unless there were no property settings and there was a negated special such - as \S in the class, and PCRE2_UCP is not set, because in that case all - characters > 255 are in or not in the class, so any that were explicitly - given as well can be ignored. - - In the UCP case, if certain negated POSIX classes ([:^ascii:] or - [^:xdigit:]) were present in a class, we either have to match or not match - all wide characters (depending on whether the whole class is or is not - negated). This requirement is indicated by match_all_or_no_wide_chars being - true. We do this by including an explicit range, which works in both cases. - - If, when generating an xclass, there are no characters < 256, we can omit - the bitmap in the actual compiled code. */ - -#ifdef SUPPORT_WIDE_CHARS -#ifdef SUPPORT_UNICODE - if (xclass && (xclass_has_prop || !should_flip_negation || - (options & PCRE2_UCP) != 0)) -#elif PCRE2_CODE_UNIT_WIDTH != 8 - if (xclass && (xclass_has_prop || !should_flip_negation)) -#endif - { - if (match_all_or_no_wide_chars) - { - *class_uchardata++ = XCL_RANGE; - class_uchardata += PRIV(ord2utf)(0x100, class_uchardata); - class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata); - } - *class_uchardata++ = XCL_END; /* Marks the end of extra data */ - *code++ = OP_XCLASS; - code += LINK_SIZE; - *code = negate_class? XCL_NOT:0; - if (xclass_has_prop) *code |= XCL_HASPROP; - - /* If the map is required, move up the extra data to make room for it; - otherwise just move the code pointer to the end of the extra data. */ - - if (class_has_8bitchar > 0) - { - *code++ |= XCL_MAP; - memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, - CU2BYTES(class_uchardata - code)); - if (negate_class && !xclass_has_prop) - for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; - memcpy(code, classbits, 32); - code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); - } - else code = class_uchardata; - - /* Now fill in the complete length of the item */ - - PUT(previous, 1, (int)(code - previous)); - break; /* End of class handling */ - } -#endif - - /* If there are no characters > 255, or they are all to be included or - excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the - whole class was negated and whether there were negative specials such as \S - (non-UCP) in the class. Then copy the 32-byte map into the code vector, - negating it if necessary. */ - - *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; - if (lengthptr == NULL) /* Save time in the pre-compile phase */ - { - if (negate_class) - for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; - memcpy(code, classbits, 32); - } - code += 32 / sizeof(PCRE2_UCHAR); - - END_CLASS: - break; - - - /* ===================================================================*/ - /* Various kinds of repeat; '{' is not necessarily a quantifier, but this - has been tested above. */ - - case CHAR_LEFT_CURLY_BRACKET: - if (!is_quantifier) goto NORMAL_CHAR; - ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr); - if (*errorcodeptr != 0) goto FAILED; - goto REPEAT; - - case CHAR_ASTERISK: - repeat_min = 0; - repeat_max = -1; - goto REPEAT; - - case CHAR_PLUS: - repeat_min = 1; - repeat_max = -1; - goto REPEAT; - - case CHAR_QUESTION_MARK: - repeat_min = 0; - repeat_max = 1; - - REPEAT: - if (previous == NULL) - { - *errorcodeptr = ERR9; - goto FAILED; - } - - if (repeat_min == 0) - { - firstcu = zerofirstcu; /* Adjust for zero repeat */ - firstcuflags = zerofirstcuflags; - reqcu = zeroreqcu; /* Ditto */ - reqcuflags = zeroreqcuflags; - } - - /* Remember whether this is a variable length repeat */ - - reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; - - op_type = 0; /* Default single-char op codes */ - possessive_quantifier = FALSE; /* Default not possessive quantifier */ - - /* Save start of previous item, in case we have to move it up in order to - insert something before it. */ - - tempcode = previous; - - /* Before checking for a possessive quantifier, we must skip over - whitespace and comments in extended mode because Perl allows white space at - this point. */ - - if ((options & PCRE2_EXTENDED) != 0) - { - ptr++; - for (;;) - { - while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_space) != 0) ptr++; - if (*ptr != CHAR_NUMBER_SIGN) break; - ptr++; - while (ptr < cb->end_pattern) - { - if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ - { /* IS_NEWLINE sets cb->nllen. */ - ptr += cb->nllen; - break; - } - ptr++; -#ifdef SUPPORT_UNICODE - if (utf) FORWARDCHAR(ptr); -#endif - } /* Loop for comment characters */ - } /* Loop for multiple comments */ - ptr--; /* Last code unit of previous character. */ - } - - /* If the next character is '+', we have a possessive quantifier. This - implies greediness, whatever the setting of the PCRE2_UNGREEDY option. - If the next character is '?' this is a minimizing repeat, by default, - but if PCRE2_UNGREEDY is set, it works the other way round. We change the - repeat type to the non-default. */ - - if (ptr[1] == CHAR_PLUS) - { - repeat_type = 0; /* Force greedy */ - possessive_quantifier = TRUE; - ptr++; - } - else if (ptr[1] == CHAR_QUESTION_MARK) - { - repeat_type = greedy_non_default; - ptr++; - } - else repeat_type = greedy_default; - - /* If the repeat is {1} we can ignore it. */ - - if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; - - /* If previous was a recursion call, wrap it in atomic brackets so that - previous becomes the atomic group. All recursions were so wrapped in the - past, but it no longer happens for non-repeated recursions. In fact, the - repeated ones could be re-implemented independently so as not to need this, - but for the moment we rely on the code for repeating groups. */ - - if (*previous == OP_RECURSE) - { - memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE)); - *previous = OP_ONCE; - PUT(previous, 1, 2 + 2*LINK_SIZE); - previous[2 + 2*LINK_SIZE] = OP_KET; - PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); - code += 2 + 2 * LINK_SIZE; - length_prevgroup = 3 + 3*LINK_SIZE; - } - - /* Now handle repetition for the different types of item. */ - - /* If previous was a character or negated character match, abolish the item - and generate a repeat item instead. If a char item has a minimum of more - than one, ensure that it is set in reqcu - it might not be if a sequence - such as x{3} is the first thing in a branch because the x will have gone - into firstcu instead. */ - - if (*previous == OP_CHAR || *previous == OP_CHARI - || *previous == OP_NOT || *previous == OP_NOTI) - { - switch (*previous) - { - default: /* Make compiler happy. */ - case OP_CHAR: op_type = OP_STAR - OP_STAR; break; - case OP_CHARI: op_type = OP_STARI - OP_STAR; break; - case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break; - case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break; - } - - /* Deal with UTF characters that take up more than one code unit. It's - easier to write this out separately than try to macrify it. Use c to - hold the length of the character in code units, plus UTF_LENGTH to flag - that it's a length rather than a small character. */ - -#ifdef MAYBE_UTF_MULTI - if (utf && NOT_FIRSTCU(code[-1])) - { - PCRE2_UCHAR *lastchar = code - 1; - BACKCHAR(lastchar); - c = (int)(code - lastchar); /* Length of UTF character */ - memcpy(utf_units, lastchar, CU2BYTES(c)); /* Save the char */ - c |= UTF_LENGTH; /* Flag c as a length */ - } - else -#endif /* MAYBE_UTF_MULTI */ - - /* Handle the case of a single charater - either with no UTF support, or - with UTF disabled, or for a single-code-unit UTF character. */ - { - c = code[-1]; - if (*previous <= OP_CHARI && repeat_min > 1) - { - reqcu = c; - reqcuflags = req_caseopt | cb->req_varyopt; - } - } - - goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ - } - - /* If previous was a character type match (\d or similar), abolish it and - create a suitable repeat item. The code is shared with single-character - repeats by setting op_type to add a suitable offset into repeat_type. Note - the the Unicode property types will be present only when SUPPORT_UNICODE is - defined, but we don't wrap the little bits of code here because it just - makes it horribly messy. */ - - else if (*previous < OP_EODN) - { - PCRE2_UCHAR *oldcode; - int prop_type, prop_value; - op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ - c = *previous; /* Save previous opcode */ - if (c == OP_PROP || c == OP_NOTPROP) - { - prop_type = previous[1]; - prop_value = previous[2]; - } - else - { - /* Come here from just above with a character in c */ - OUTPUT_SINGLE_REPEAT: - prop_type = prop_value = -1; - } - - /* At this point we either have prop_type == prop_value == -1 and either - a code point or a character type that is not OP_[NOT]PROP in c, or we - have OP_[NOT]PROP in c and prop_type/prop_value not negative. */ - - oldcode = code; /* Save where we were */ - code = previous; /* Usually overwrite previous item */ - - /* If the maximum is zero then the minimum must also be zero; Perl allows - this case, so we do too - by simply omitting the item altogether. */ - - if (repeat_max == 0) goto END_REPEAT; - - /* Combine the op_type with the repeat_type */ - - repeat_type += op_type; - - /* A minimum of zero is handled either as the special case * or ?, or as - an UPTO, with the maximum given. */ - - if (repeat_min == 0) - { - if (repeat_max == -1) *code++ = OP_STAR + repeat_type; - else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; - else - { - *code++ = OP_UPTO + repeat_type; - PUT2INC(code, 0, repeat_max); - } - } - - /* A repeat minimum of 1 is optimized into some special cases. If the - maximum is unlimited, we use OP_PLUS. Otherwise, the original item is - left in place and, if the maximum is greater than 1, we use OP_UPTO with - one less than the maximum. */ - - else if (repeat_min == 1) - { - if (repeat_max == -1) - *code++ = OP_PLUS + repeat_type; - else - { - code = oldcode; /* Leave previous item in place */ - if (repeat_max == 1) goto END_REPEAT; - *code++ = OP_UPTO + repeat_type; - PUT2INC(code, 0, repeat_max - 1); - } - } - - /* The case {n,n} is just an EXACT, while the general case {n,m} is - handled as an EXACT followed by an UPTO or STAR or QUERY. */ - - else - { - *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ - PUT2INC(code, 0, repeat_min); - - /* Unless repeat_max equals repeat_min, fill in the data for EXACT, and - then generate the second opcode. In UTF mode, multi-code-unit - characters have their length in c, with the UTF_LENGTH bit as a flag, - and the code units in utf_units. For a repeated Unicode property match, - there are two extra values that define the required property, and c - never has the UTF_LENGTH bit set. */ - - if (repeat_max != repeat_min) - { -#ifdef MAYBE_UTF_MULTI - if (utf && (c & UTF_LENGTH) != 0) - { - memcpy(code, utf_units, CU2BYTES(c & 7)); - code += c & 7; - } - else -#endif /* MAYBE_UTF_MULTI */ - { - *code++ = c; - if (prop_type >= 0) - { - *code++ = prop_type; - *code++ = prop_value; - } - } - - /* Now set up the following opcode */ - - if (repeat_max < 0) *code++ = OP_STAR + repeat_type; else - { - repeat_max -= repeat_min; - if (repeat_max == 1) - { - *code++ = OP_QUERY + repeat_type; - } - else - { - *code++ = OP_UPTO + repeat_type; - PUT2INC(code, 0, repeat_max); - } - } - } - } - - /* Fill in the character or character type for the final opcode. */ - -#ifdef MAYBE_UTF_MULTI - if (utf && (c & UTF_LENGTH) != 0) - { - memcpy(code, utf_units, CU2BYTES(c & 7)); - code += c & 7; - } - else -#endif /* MAYBEW_UTF_MULTI */ - { - *code++ = c; - if (prop_type >= 0) - { - *code++ = prop_type; - *code++ = prop_value; - } - } - } - - /* If previous was a character class or a back reference, we put the repeat - stuff after it, but just skip the item if the repeat was {0,0}. */ - - else if (*previous == OP_CLASS || *previous == OP_NCLASS || -#ifdef SUPPORT_WIDE_CHARS - *previous == OP_XCLASS || -#endif - *previous == OP_REF || *previous == OP_REFI || - *previous == OP_DNREF || *previous == OP_DNREFI) - { - if (repeat_max == 0) - { - code = previous; - goto END_REPEAT; - } - - if (repeat_min == 0 && repeat_max == -1) - *code++ = OP_CRSTAR + repeat_type; - else if (repeat_min == 1 && repeat_max == -1) - *code++ = OP_CRPLUS + repeat_type; - else if (repeat_min == 0 && repeat_max == 1) - *code++ = OP_CRQUERY + repeat_type; - else - { - *code++ = OP_CRRANGE + repeat_type; - PUT2INC(code, 0, repeat_min); - if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ - PUT2INC(code, 0, repeat_max); - } - } - - /* If previous was a bracket group, we may have to replicate it in certain - cases. Note that at this point we can encounter only the "basic" bracket - opcodes such as BRA and CBRA, as this is the place where they get converted - into the more special varieties such as BRAPOS and SBRA. A test for >= - OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, - ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND. - Originally, PCRE did not allow repetition of assertions, but now it does, - for Perl compatibility. */ - - else if (*previous >= OP_ASSERT && *previous <= OP_COND) - { - register int i; - int len = (int)(code - previous); - PCRE2_UCHAR *bralink = NULL; - PCRE2_UCHAR *brazeroptr = NULL; - - /* Repeating a DEFINE group (or any group where the condition is always - FALSE and there is only one branch) is pointless, but Perl allows the - syntax, so we just ignore the repeat. */ - - if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE && - previous[GET(previous, 1)] != OP_ALT) - goto END_REPEAT; - - /* There is no sense in actually repeating assertions. The only potential - use of repetition is in cases when the assertion is optional. Therefore, - if the minimum is greater than zero, just ignore the repeat. If the - maximum is not zero or one, set it to 1. */ - - if (*previous < OP_ONCE) /* Assertion */ - { - if (repeat_min > 0) goto END_REPEAT; - if (repeat_max < 0 || repeat_max > 1) repeat_max = 1; - } - - /* The case of a zero minimum is special because of the need to stick - OP_BRAZERO in front of it, and because the group appears once in the - data, whereas in other cases it appears the minimum number of times. For - this reason, it is simplest to treat this case separately, as otherwise - the code gets far too messy. There are several special subcases when the - minimum is zero. */ - - if (repeat_min == 0) - { - /* If the maximum is also zero, we used to just omit the group from the - output altogether, like this: - - ** if (repeat_max == 0) - ** { - ** code = previous; - ** goto END_REPEAT; - ** } - - However, that fails when a group or a subgroup within it is referenced - as a subroutine from elsewhere in the pattern, so now we stick in - OP_SKIPZERO in front of it so that it is skipped on execution. As we - don't have a list of which groups are referenced, we cannot do this - selectively. - - If the maximum is 1 or unlimited, we just have to stick in the BRAZERO - and do no more at this point. */ - - if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ - { - memmove(previous + 1, previous, CU2BYTES(len)); - code++; - if (repeat_max == 0) - { - *previous++ = OP_SKIPZERO; - goto END_REPEAT; - } - brazeroptr = previous; /* Save for possessive optimizing */ - *previous++ = OP_BRAZERO + repeat_type; - } - - /* If the maximum is greater than 1 and limited, we have to replicate - in a nested fashion, sticking OP_BRAZERO before each set of brackets. - The first one has to be handled carefully because it's the original - copy, which has to be moved up. The remainder can be handled by code - that is common with the non-zero minimum case below. We have to - adjust the value or repeat_max, since one less copy is required. */ - - else - { - int offset; - memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len)); - code += 2 + LINK_SIZE; - *previous++ = OP_BRAZERO + repeat_type; - *previous++ = OP_BRA; - - /* We chain together the bracket offset fields that have to be - filled in later when the ends of the brackets are reached. */ - - offset = (bralink == NULL)? 0 : (int)(previous - bralink); - bralink = previous; - PUTINC(previous, 0, offset); - } - - repeat_max--; - } - - /* If the minimum is greater than zero, replicate the group as many - times as necessary, and adjust the maximum to the number of subsequent - copies that we need. */ - - else - { - if (repeat_min > 1) - { - /* In the pre-compile phase, we don't actually do the replication. We - just adjust the length as if we had. Do some paranoid checks for - potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit - integer type when available, otherwise double. */ - - if (lengthptr != NULL) - { - size_t delta = (repeat_min - 1)*length_prevgroup; - if ((INT64_OR_DOUBLE)(repeat_min - 1)* - (INT64_OR_DOUBLE)length_prevgroup > - (INT64_OR_DOUBLE)INT_MAX || - OFLOW_MAX - *lengthptr < delta) - { - *errorcodeptr = ERR20; - goto FAILED; - } - *lengthptr += delta; - } - - /* This is compiling for real. If there is a set first byte for - the group, and we have not yet set a "required byte", set it. */ - - else - { - if (groupsetfirstcu && reqcuflags < 0) - { - reqcu = firstcu; - reqcuflags = firstcuflags; - } - for (i = 1; i < repeat_min; i++) - { - memcpy(code, previous, CU2BYTES(len)); - code += len; - } - } - } - - if (repeat_max > 0) repeat_max -= repeat_min; - } - - /* This code is common to both the zero and non-zero minimum cases. If - the maximum is limited, it replicates the group in a nested fashion, - remembering the bracket starts on a stack. In the case of a zero minimum, - the first one was set up above. In all cases the repeat_max now specifies - the number of additional copies needed. Again, we must remember to - replicate entries on the forward reference list. */ - - if (repeat_max >= 0) - { - /* In the pre-compile phase, we don't actually do the replication. We - just adjust the length as if we had. For each repetition we must add 1 - to the length for BRAZERO and for all but the last repetition we must - add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some - paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is - a 64-bit integer type when available, otherwise double. */ - - if (lengthptr != NULL && repeat_max > 0) - { - size_t delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - - 2 - 2*LINK_SIZE; /* Last one doesn't nest */ - if ((INT64_OR_DOUBLE)repeat_max * - (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - > (INT64_OR_DOUBLE)INT_MAX || - OFLOW_MAX - *lengthptr < delta) - { - *errorcodeptr = ERR20; - goto FAILED; - } - *lengthptr += delta; - } - - /* This is compiling for real */ - - else for (i = repeat_max - 1; i >= 0; i--) - { - *code++ = OP_BRAZERO + repeat_type; - - /* All but the final copy start a new nesting, maintaining the - chain of brackets outstanding. */ - - if (i != 0) - { - int offset; - *code++ = OP_BRA; - offset = (bralink == NULL)? 0 : (int)(code - bralink); - bralink = code; - PUTINC(code, 0, offset); - } - - memcpy(code, previous, CU2BYTES(len)); - code += len; - } - - /* Now chain through the pending brackets, and fill in their length - fields (which are holding the chain links pro tem). */ - - while (bralink != NULL) - { - int oldlinkoffset; - int offset = (int)(code - bralink + 1); - PCRE2_UCHAR *bra = code - offset; - oldlinkoffset = GET(bra, 1); - bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; - *code++ = OP_KET; - PUTINC(code, 0, offset); - PUT(bra, 1, offset); - } - } - - /* If the maximum is unlimited, set a repeater in the final copy. For - ONCE brackets, that's all we need to do. However, possessively repeated - ONCE brackets can be converted into non-capturing brackets, as the - behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to - deal with possessive ONCEs specially. - - Otherwise, when we are doing the actual compile phase, check to see - whether this group is one that could match an empty string. If so, - convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so - that runtime checking can be done. [This check is also applied to ONCE - groups at runtime, but in a different way.] - - Then, if the quantifier was possessive and the bracket is not a - conditional, we convert the BRA code to the POS form, and the KET code to - KETRPOS. (It turns out to be convenient at runtime to detect this kind of - subpattern at both the start and at the end.) The use of special opcodes - makes it possible to reduce greatly the stack usage in pcre2_match(). If - the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. - - Then, if the minimum number of matches is 1 or 0, cancel the possessive - flag so that the default action below, of wrapping everything inside - atomic brackets, does not happen. When the minimum is greater than 1, - there will be earlier copies of the group, and so we still have to wrap - the whole thing. */ - - else - { - PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE; - PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1); - - /* Convert possessive ONCE brackets to non-capturing */ - - if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) && - possessive_quantifier) *bracode = OP_BRA; - - /* For non-possessive ONCE brackets, all we need to do is to - set the KET. */ - - if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC) - *ketcode = OP_KETRMAX + repeat_type; - - /* Handle non-ONCE brackets and possessive ONCEs (which have been - converted to non-capturing above). */ - - else - { - /* In the compile phase, check whether the group could match an empty - string. */ - - if (lengthptr == NULL) - { - PCRE2_UCHAR *scode = bracode; - do - { - int count = 0; - int rc = could_be_empty_branch(scode, ketcode, utf, cb, FALSE, - NULL, &count); - if (rc < 0) - { - *errorcodeptr = ERR86; - goto FAILED; - } - if (rc > 0) - { - *bracode += OP_SBRA - OP_BRA; - break; - } - scode += GET(scode, 1); - } - while (*scode == OP_ALT); - - /* A conditional group with only one branch has an implicit empty - alternative branch. */ - - if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT) - *bracode = OP_SCOND; - } - - /* Handle possessive quantifiers. */ - - if (possessive_quantifier) - { - /* For COND brackets, we wrap the whole thing in a possessively - repeated non-capturing bracket, because we have not invented POS - versions of the COND opcodes. */ - - if (*bracode == OP_COND || *bracode == OP_SCOND) - { - int nlen = (int)(code - bracode); - memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen)); - code += 1 + LINK_SIZE; - nlen += 1 + LINK_SIZE; - *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS; - *code++ = OP_KETRPOS; - PUTINC(code, 0, nlen); - PUT(bracode, 1, nlen); - } - - /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ - - else - { - *bracode += 1; /* Switch to xxxPOS opcodes */ - *ketcode = OP_KETRPOS; - } - - /* If the minimum is zero, mark it as possessive, then unset the - possessive flag when the minimum is 0 or 1. */ - - if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; - if (repeat_min < 2) possessive_quantifier = FALSE; - } - - /* Non-possessive quantifier */ - - else *ketcode = OP_KETRMAX + repeat_type; - } - } - } - - /* If previous is OP_FAIL, it was generated by an empty class [] - (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be - generated, that is by (*FAIL) or (?!), set previous to NULL, which gives a - "nothing to repeat" error above. We can just ignore the repeat in empty - class case. */ - - else if (*previous == OP_FAIL) goto END_REPEAT; - - /* Else there's some kind of shambles */ - - else - { - *errorcodeptr = ERR10; - goto FAILED; - } - - /* If the character following a repeat is '+', possessive_quantifier is - TRUE. For some opcodes, there are special alternative opcodes for this - case. For anything else, we wrap the entire repeated item inside OP_ONCE - brackets. Logically, the '+' notation is just syntactic sugar, taken from - Sun's Java package, but the special opcodes can optimize it. - - Some (but not all) possessively repeated subpatterns have already been - completely handled in the code just above. For them, possessive_quantifier - is always FALSE at this stage. Note that the repeated item starts at - tempcode, not at previous, which might be the first part of a string whose - (former) last char we repeated. */ - - if (possessive_quantifier) - { - int len; - - /* Possessifying an EXACT quantifier has no effect, so we can ignore it. - However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6}, - {5,}, or {5,10}). We skip over an EXACT item; if the length of what - remains is greater than zero, there's a further opcode that can be - handled. If not, do nothing, leaving the EXACT alone. */ - - switch(*tempcode) - { - case OP_TYPEEXACT: - tempcode += PRIV(OP_lengths)[*tempcode] + - ((tempcode[1 + IMM2_SIZE] == OP_PROP - || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); - break; - - /* CHAR opcodes are used for exacts whose count is 1. */ - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - tempcode += PRIV(OP_lengths)[*tempcode]; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(tempcode[-1])) - tempcode += GET_EXTRALEN(tempcode[-1]); -#endif - break; - - /* For the class opcodes, the repeat operator appears at the end; - adjust tempcode to point to it. */ - - case OP_CLASS: - case OP_NCLASS: - tempcode += 1 + 32/sizeof(PCRE2_UCHAR); - break; - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - tempcode += GET(tempcode, 1); - break; -#endif - } - - /* If tempcode is equal to code (which points to the end of the repeated - item), it means we have skipped an EXACT item but there is no following - QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In - all other cases, tempcode will be pointing to the repeat opcode, and will - be less than code, so the value of len will be greater than 0. */ - - len = (int)(code - tempcode); - if (len > 0) - { - unsigned int repcode = *tempcode; - - /* There is a table for possessifying opcodes, all of which are less - than OP_CALLOUT. A zero entry means there is no possessified version. - */ - - if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0) - *tempcode = opcode_possessify[repcode]; - - /* For opcode without a special possessified version, wrap the item in - ONCE brackets. */ - - else - { - memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len)); - code += 1 + LINK_SIZE; - len += 1 + LINK_SIZE; - tempcode[0] = OP_ONCE; - *code++ = OP_KET; - PUTINC(code, 0, len); - PUT(tempcode, 1, len); - } - } - } - - /* In all case we no longer have a previous item. We also set the - "follows varying string" flag for subsequently encountered reqcus if - it isn't already set and we have just passed a varying length item. */ - - END_REPEAT: - previous = NULL; - cb->req_varyopt |= reqvary; - break; - - - /* ===================================================================*/ - /* Start of nested parenthesized sub-expression, or lookahead or lookbehind - or option setting or condition or all the other extended parenthesis forms. - We must save the current high-water-mark for the forward reference list so - that we know where they start for this group. However, because the list may - be extended when there are very many forward references (usually the result - of a replicated inner group), we must use an offset rather than an absolute - address. Note that (?# comments are dealt with at the top of the loop; - they do not get this far. */ - - case CHAR_LEFT_PARENTHESIS: - ptr++; - - /* Deal with various "verbs" that can be introduced by '*'. */ - - if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' - || (MAX_255(ptr[1]) && ((cb->ctypes[ptr[1]] & ctype_letter) != 0)))) - { - int i, namelen; - int arglen = 0; - const char *vn = verbnames; - PCRE2_SPTR name = ptr + 1; - PCRE2_SPTR arg = NULL; - previous = NULL; - ptr++; - - /* Increment ptr, set namelen, check length */ - - READ_NAME(ctype_letter, ERR60, *errorcodeptr); - - /* It appears that Perl allows any characters whatsoever, other than - a closing parenthesis, to appear in arguments, so we no longer insist on - letters, digits, and underscores. Perl does not, however, do any - interpretation within arguments, and has no means of including a closing - parenthesis. PCRE supports escape processing but only when it is - requested by an option. Note that check_escape() will not return values - greater than the code unit maximum when not in UTF mode. */ - - if (*ptr == CHAR_COLON) - { - arg = ++ptr; - - if ((options & PCRE2_ALT_VERBNAMES) == 0) - { - arglen = 0; - while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) - { - ptr++; /* Check length as we go */ - arglen++; /* along, to avoid the */ - if ((unsigned int)arglen > MAX_MARK) /* possibility of overflow. */ - { - *errorcodeptr = ERR76; - goto FAILED; - } - } - } - else - { - /* The length check is in process_verb_names() */ - arglen = process_verb_name(&ptr, NULL, errorcodeptr, options, - utf, cb); - if (arglen < 0) goto FAILED; - } - } - - if (*ptr != CHAR_RIGHT_PARENTHESIS) - { - *errorcodeptr = ERR60; - goto FAILED; - } - - /* Scan the table of verb names */ - - for (i = 0; i < verbcount; i++) - { - if (namelen == verbs[i].len && - PRIV(strncmp_c8)(name, vn, namelen) == 0) - { - int setverb; - - /* Check for open captures before ACCEPT and convert it to - ASSERT_ACCEPT if in an assertion. */ - - if (verbs[i].op == OP_ACCEPT) - { - open_capitem *oc; - if (arglen != 0) - { - *errorcodeptr = ERR59; - goto FAILED; - } - cb->had_accept = TRUE; - /* In the first pass, just accumulate the length required; - otherwise hitting (*ACCEPT) inside many nested parentheses can - cause workspace overflow. */ - for (oc = cb->open_caps; oc != NULL; oc = oc->next) - { - if (lengthptr != NULL) - { - *lengthptr += CU2BYTES(1) + IMM2_SIZE; - } - else - { - *code++ = OP_CLOSE; - PUT2INC(code, 0, oc->number); - } - } - - setverb = *code++ = - (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; - - /* Do not set firstcu after *ACCEPT */ - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - } - - /* Handle other cases with/without an argument */ - - else if (arglen == 0) /* There is no argument */ - { - if (verbs[i].op < 0) /* Argument is mandatory */ - { - *errorcodeptr = ERR66; - goto FAILED; - } - setverb = *code++ = verbs[i].op; - } - - else /* An argument is present */ - { - if (verbs[i].op_arg < 0) /* Argument is forbidden */ - { - *errorcodeptr = ERR59; - goto FAILED; - } - setverb = *code++ = verbs[i].op_arg; - - /* Arguments can be very long, especially in 16- and 32-bit modes, - and can overflow the workspace in the first pass. Instead of - putting the argument into memory, we just update the length counter - and set up an empty argument. */ - - if (lengthptr != NULL) - { - *lengthptr += arglen; - *code++ = 0; - } - else - { - *code++ = arglen; - if ((options & PCRE2_ALT_VERBNAMES) != 0) - { - PCRE2_UCHAR *memcode = code; /* code is "register" */ - (void)process_verb_name(&arg, &memcode, errorcodeptr, options, - utf, cb); - code = memcode; - } - else /* No argument processing */ - { - memcpy(code, arg, CU2BYTES(arglen)); - code += arglen; - } - } - - *code++ = 0; - } - - switch (setverb) - { - case OP_THEN: - case OP_THEN_ARG: - cb->external_flags |= PCRE2_HASTHEN; - break; - - case OP_PRUNE: - case OP_PRUNE_ARG: - case OP_SKIP: - case OP_SKIP_ARG: - cb->had_pruneorskip = TRUE; - break; - } - - break; /* Found verb, exit loop */ - } - - vn += verbs[i].len + 1; - } - - if (i < verbcount) continue; /* Successfully handled a verb */ - *errorcodeptr = ERR60; /* Verb not recognized */ - goto FAILED; - } - - /* Initialization for "real" parentheses */ - - newoptions = options; - skipunits = 0; - bravalue = OP_CBRA; - reset_bracount = FALSE; - - /* Deal with the extended parentheses; all are introduced by '?', and the - appearance of any of them means that this is not a capturing group. */ - - if (*ptr == CHAR_QUESTION_MARK) - { - int i, count; - int namelen; /* Must be signed */ - uint32_t index; - uint32_t set, unset, *optset; - named_group *ng; - PCRE2_SPTR name; - PCRE2_UCHAR *slot; - - switch (*(++ptr)) - { - /* ------------------------------------------------------------ */ - case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ - reset_bracount = TRUE; - /* Fall through */ - - /* ------------------------------------------------------------ */ - case CHAR_COLON: /* Non-capturing bracket */ - bravalue = OP_BRA; - ptr++; - break; - - /* ------------------------------------------------------------ */ - case CHAR_LEFT_PARENTHESIS: - bravalue = OP_COND; /* Conditional group */ - tempptr = ptr; - - /* A condition can be an assertion, a number (referring to a numbered - group's having been set), a name (referring to a named group), or 'R', - referring to recursion. R and R&name are also permitted for - recursion tests. - - There are ways of testing a named group: (?(name)) is used by Python; - Perl 5.10 onwards uses (?() or (?('name')). - - There is one unfortunate ambiguity, caused by history. 'R' can be the - recursive thing or the name 'R' (and similarly for 'R' followed by - digits). We look for a name first; if not found, we try the other case. - - For compatibility with auto-callouts, we allow a callout to be - specified before a condition that is an assertion. First, check for the - syntax of a callout; if found, adjust the temporary pointer that is - used to check for an assertion condition. That's all that is needed! */ - - if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C) - { - if (IS_DIGIT(ptr[3]) || ptr[3] == CHAR_RIGHT_PARENTHESIS) - { - for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break; - if (ptr[i] == CHAR_RIGHT_PARENTHESIS) - tempptr += i + 1; - } - else - { - uint32_t delimiter = 0; - for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) - { - if (ptr[3] == PRIV(callout_start_delims)[i]) - { - delimiter = PRIV(callout_end_delims)[i]; - break; - } - } - if (delimiter != 0) - { - for (i = 4; ptr + i < cb->end_pattern; i++) - { - if (ptr[i] == delimiter) - { - if (ptr[i+1] == delimiter) i++; - else - { - if (ptr[i+1] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 2; - break; - } - } - } - } - } - - /* tempptr should now be pointing to the opening parenthesis of the - assertion condition. */ - - if (*tempptr != CHAR_LEFT_PARENTHESIS) - { - *errorcodeptr = ERR28; - goto FAILED; - } - } - - /* For conditions that are assertions, check the syntax, and then exit - the switch. This will take control down to where bracketed groups - are processed. The assertion will be handled as part of the group, - but we need to identify this case because the conditional assertion may - not be quantifier. */ - - if (tempptr[1] == CHAR_QUESTION_MARK && - (tempptr[2] == CHAR_EQUALS_SIGN || - tempptr[2] == CHAR_EXCLAMATION_MARK || - (tempptr[2] == CHAR_LESS_THAN_SIGN && - (tempptr[3] == CHAR_EQUALS_SIGN || - tempptr[3] == CHAR_EXCLAMATION_MARK)))) - { - cb->iscondassert = TRUE; - break; - } - - /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all - need to skip at least 1+IMM2_SIZE bytes at the start of the group. */ - - code[1+LINK_SIZE] = OP_CREF; - skipunits = 1+IMM2_SIZE; - refsign = -1; /* => not a number */ - namelen = -1; /* => not a name; must set to avoid warning */ - name = NULL; /* Always set to avoid warning */ - recno = 0; /* Always set to avoid warning */ - - /* Point at character after (?( */ - - ptr++; - - /* Check for (?(VERSION[>]=n.m), which is a facility whereby indirect - users of PCRE2 via an application can discover which release of PCRE2 - is being used. */ - - if (PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 && - ptr[7] != CHAR_RIGHT_PARENTHESIS) - { - BOOL ge = FALSE; - int major = 0; - int minor = 0; - - ptr += 7; - if (*ptr == CHAR_GREATER_THAN_SIGN) - { - ge = TRUE; - ptr++; - } - - /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT - references its argument twice. */ - - if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr))) - { - *errorcodeptr = ERR79; - goto FAILED; - } - - while (IS_DIGIT(*ptr)) major = major * 10 + *ptr++ - '0'; - if (*ptr == CHAR_DOT) - { - ptr++; - while (IS_DIGIT(*ptr)) minor = minor * 10 + *ptr++ - '0'; - if (minor < 10) minor *= 10; - } - - if (*ptr != CHAR_RIGHT_PARENTHESIS || minor > 99) - { - *errorcodeptr = ERR79; - goto FAILED; - } - - if (ge) - code[1+LINK_SIZE] = ((PCRE2_MAJOR > major) || - (PCRE2_MAJOR == major && PCRE2_MINOR >= minor))? - OP_TRUE : OP_FALSE; - else - code[1+LINK_SIZE] = (PCRE2_MAJOR == major && PCRE2_MINOR == minor)? - OP_TRUE : OP_FALSE; - - ptr++; - skipunits = 1; - break; /* End of condition processing */ - } - - /* Check for a test for recursion in a named group. */ - - if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND) - { - terminator = -1; - ptr += 2; - code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */ - } - - /* Check for a test for a named group's having been set, using the Perl - syntax (?() or (?('name'), and also allow for the original PCRE - syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */ - - else if (*ptr == CHAR_LESS_THAN_SIGN) - { - terminator = CHAR_GREATER_THAN_SIGN; - ptr++; - } - else if (*ptr == CHAR_APOSTROPHE) - { - terminator = CHAR_APOSTROPHE; - ptr++; - } - else - { - terminator = CHAR_NULL; - if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++; - else if (IS_DIGIT(*ptr)) refsign = 0; - } - - /* Handle a number */ - - if (refsign >= 0) - { - while (IS_DIGIT(*ptr)) - { - if (recno > INT_MAX / 10 - 1) /* Integer overflow */ - { - while (IS_DIGIT(*ptr)) ptr++; - *errorcodeptr = ERR61; - goto FAILED; - } - recno = recno * 10 + (int)(*ptr - CHAR_0); - ptr++; - } - } - - /* Otherwise we expect to read a name; anything else is an error. When - the referenced name is one of a number of duplicates, a different - opcode is used and it needs more memory. Unfortunately we cannot tell - whether this is the case in the first pass, so we have to allow for - more memory always. In the second pass, the additional to skipunits - happens later. */ - - else - { - if (IS_DIGIT(*ptr)) - { - *errorcodeptr = ERR44; /* Group name must start with non-digit */ - goto FAILED; - } - if (!MAX_255(*ptr) || (cb->ctypes[*ptr] & ctype_word) == 0) - { - *errorcodeptr = ERR28; /* Assertion expected */ - goto FAILED; - } - name = ptr; - /* Increment ptr, set namelen, check length */ - READ_NAME(ctype_word, ERR48, *errorcodeptr); - if (lengthptr != NULL) skipunits += IMM2_SIZE; - } - - /* Check the terminator */ - - if ((terminator > 0 && *ptr++ != (PCRE2_UCHAR)terminator) || - *ptr++ != CHAR_RIGHT_PARENTHESIS) - { - ptr--; /* Error offset */ - *errorcodeptr = ERR26; /* Malformed number or name */ - goto FAILED; - } - - /* Do no further checking in the pre-compile phase. */ - - if (lengthptr != NULL) break; - - /* In the real compile we do the work of looking for the actual - reference. If refsign is not negative, it means we have a number in - recno. */ - - if (refsign >= 0) - { - if (recno <= 0) - { - *errorcodeptr = ERR35; - goto FAILED; - } - if (refsign != 0) recno = (refsign == CHAR_MINUS)? - (cb->bracount + 1) - recno : recno + cb->bracount; - if (recno <= 0 || (uint32_t)recno > cb->final_bracount) - { - *errorcodeptr = ERR15; - goto FAILED; - } - PUT2(code, 2+LINK_SIZE, recno); - if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; - break; - } - - /* Otherwise look for the name. */ - - slot = cb->name_table; - for (i = 0; i < cb->names_found; i++) - { - if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0) break; - slot += cb->name_entry_size; - } - - /* Found the named subpattern. If the name is duplicated, add one to - the opcode to change CREF/RREF into DNCREF/DNRREF and insert - appropriate data values. Otherwise, just insert the unique subpattern - number. */ - - if (i < cb->names_found) - { - int offset = i; /* Offset of first name found */ - - count = 0; - for (;;) - { - recno = GET2(slot, 0); /* Number for last found */ - if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; - count++; - if (++i >= cb->names_found) break; - slot += cb->name_entry_size; - if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) != 0 || - (slot+IMM2_SIZE)[namelen] != 0) break; - } - - if (count > 1) - { - PUT2(code, 2+LINK_SIZE, offset); - PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count); - skipunits += IMM2_SIZE; - code[1+LINK_SIZE]++; - } - else /* Not a duplicated name */ - { - PUT2(code, 2+LINK_SIZE, recno); - } - } - - /* If terminator == CHAR_NULL it means that the name followed directly - after the opening parenthesis [e.g. (?(abc)...] and in this case there - are some further alternatives to try. For the cases where terminator != - CHAR_NULL [things like (?(... or (?('name')... or (?(R&name)... ] - we have now checked all the possibilities, so give an error. */ - - else if (terminator != CHAR_NULL) - { - *errorcodeptr = ERR15; - goto FAILED; - } - - /* Check for (?(R) for recursion. Allow digits after R to specify a - specific group number. */ - - else if (*name == CHAR_R) - { - recno = 0; - for (i = 1; i < namelen; i++) - { - if (!IS_DIGIT(name[i])) - { - *errorcodeptr = ERR15; /* Non-existent subpattern */ - goto FAILED; - } - if (recno > INT_MAX / 10 - 1) /* Integer overflow */ - { - *errorcodeptr = ERR61; - goto FAILED; - } - recno = recno * 10 + name[i] - CHAR_0; - } - if (recno == 0) recno = RREF_ANY; - code[1+LINK_SIZE] = OP_RREF; /* Change test type */ - PUT2(code, 2+LINK_SIZE, recno); - } - - /* Similarly, check for the (?(DEFINE) "condition", which is always - false. During compilation we set OP_DEFINE to distinguish this from - other OP_FALSE conditions so that it can be checked for having only one - branch, but after that the opcode is changed to OP_FALSE. */ - - else if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0) - { - code[1+LINK_SIZE] = OP_DEFINE; - skipunits = 1; - } - - /* Reference to an unidentified subpattern. */ - - else - { - *errorcodeptr = ERR15; - goto FAILED; - } - break; - - - /* ------------------------------------------------------------ */ - case CHAR_EQUALS_SIGN: /* Positive lookahead */ - bravalue = OP_ASSERT; - cb->assert_depth += 1; - ptr++; - break; - - /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird - thing to do, but Perl allows all assertions to be quantified, and when - they contain capturing parentheses there may be a potential use for - this feature. Not that that applies to a quantified (?!) but we allow - it for uniformity. */ - - /* ------------------------------------------------------------ */ - case CHAR_EXCLAMATION_MARK: /* Negative lookahead */ - ptr++; - if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK && - ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK && - (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2))) - { - *code++ = OP_FAIL; - previous = NULL; - continue; - } - bravalue = OP_ASSERT_NOT; - cb->assert_depth += 1; - break; - - - /* ------------------------------------------------------------ */ - case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */ - switch (ptr[1]) - { - case CHAR_EQUALS_SIGN: /* Positive lookbehind */ - bravalue = OP_ASSERTBACK; - cb->assert_depth += 1; - ptr += 2; - break; - - case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */ - bravalue = OP_ASSERTBACK_NOT; - cb->assert_depth += 1; - ptr += 2; - break; - - /* Must be a name definition - as the syntax was checked in the - pre-pass, we can assume here that it is valid. Skip over the name - and go to handle the numbered group. */ - - default: - while (*(++ptr) != CHAR_GREATER_THAN_SIGN); - ptr++; - goto NUMBERED_GROUP; - } - break; - - - /* ------------------------------------------------------------ */ - case CHAR_GREATER_THAN_SIGN: /* One-time brackets */ - bravalue = OP_ONCE; - ptr++; - break; - - - /* ------------------------------------------------------------ */ - case CHAR_C: /* Callout */ - previous_callout = code; /* Save for later completion */ - after_manual_callout = 1; /* Skip one item before completing */ - ptr++; /* Character after (?C */ - - /* A callout may have a string argument, delimited by one of a fixed - number of characters, or an undelimited numerical argument, or no - argument, which is the same as (?C0). Different opcodes are used for - the two cases. */ - - if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr)) - { - uint32_t delimiter = 0; - - for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) - { - if (*ptr == PRIV(callout_start_delims)[i]) - { - delimiter = PRIV(callout_end_delims)[i]; - break; - } - } - - if (delimiter == 0) - { - *errorcodeptr = ERR82; - goto FAILED; - } - - /* During the pre-compile phase, we parse the string and update the - length. There is no need to generate any code. (In fact, the string - has already been parsed in the pre-pass that looks for named - parentheses, but it does no harm to leave this code in.) */ - - if (lengthptr != NULL) /* Only check the string */ - { - PCRE2_SPTR start = ptr; - do - { - if (++ptr >= cb->end_pattern) - { - *errorcodeptr = ERR81; - ptr = start; /* To give a more useful message */ - goto FAILED; - } - if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; - } - while (ptr[0] != delimiter); - - /* Start points to the opening delimiter, ptr points to the - closing delimiter. We must allow for including the delimiter and - for the terminating zero. Any doubled delimiters within the string - make this an overestimate, but it is not worth bothering about. */ - - (*lengthptr) += (ptr - start) + 2 + (1 + 4*LINK_SIZE); - } - - /* In the real compile we can copy the string, knowing that it is - syntactically OK. The starting delimiter is included so that the - client can discover it if they want. We also pass the start offset to - help a script language give better error messages. */ - - else - { - PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE); - *callout_string++ = *ptr++; - PUT(code, 1 + 3*LINK_SIZE, (int)(ptr - cb->start_pattern)); /* Start offset */ - for(;;) - { - if (*ptr == delimiter) - { - if (ptr[1] == delimiter) ptr++; else break; - } - *callout_string++ = *ptr++; - } - *callout_string++ = CHAR_NULL; - code[0] = OP_CALLOUT_STR; - PUT(code, 1, (int)(ptr + 2 - cb->start_pattern)); /* Next offset */ - PUT(code, 1 + LINK_SIZE, 0); /* Default length */ - PUT(code, 1 + 2*LINK_SIZE, /* Compute size */ - (int)(callout_string - code)); - code = callout_string; - } - - /* Advance to what should be the closing parenthesis, which is - checked below. */ - - ptr++; - } - - /* Handle a callout with an optional numerical argument, which must be - less than or equal to 255. A missing argument gives 0. */ - - else - { - int n = 0; - code[0] = OP_CALLOUT; /* Numerical callout */ - while (IS_DIGIT(*ptr)) - { - n = n * 10 + *ptr++ - CHAR_0; - if (n > 255) - { - *errorcodeptr = ERR38; - goto FAILED; - } - } - PUT(code, 1, (int)(ptr - cb->start_pattern + 1)); /* Next offset */ - PUT(code, 1 + LINK_SIZE, 0); /* Default length */ - code[1 + 2*LINK_SIZE] = n; /* Callout number */ - code += PRIV(OP_lengths)[OP_CALLOUT]; - } - - /* Both formats must have a closing parenthesis */ - - if (*ptr != CHAR_RIGHT_PARENTHESIS) - { - *errorcodeptr = ERR39; - goto FAILED; - } - - /* Callouts cannot be quantified. */ - - previous = NULL; - continue; - - - /* ------------------------------------------------------------ */ - case CHAR_P: /* Python-style named subpattern handling */ - if (*(++ptr) == CHAR_EQUALS_SIGN || - *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */ - { - is_recurse = *ptr == CHAR_GREATER_THAN_SIGN; - terminator = CHAR_RIGHT_PARENTHESIS; - goto NAMED_REF_OR_RECURSE; - } - else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */ - { - *errorcodeptr = ERR41; - goto FAILED; - } - /* Fall through to handle (?P< as (?< is handled */ - - - /* ------------------------------------------------------------ */ - case CHAR_APOSTROPHE: /* Define a name - note fall through above */ - - /* The syntax was checked and the list of names was set up in the - pre-pass, so there is nothing to be done now except to skip over the - name. */ - - terminator = (*ptr == CHAR_LESS_THAN_SIGN)? - CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; - while (*(++ptr) != (unsigned int)terminator); - ptr++; - goto NUMBERED_GROUP; /* Set up numbered group */ - - - /* ------------------------------------------------------------ */ - case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */ - terminator = CHAR_RIGHT_PARENTHESIS; - is_recurse = TRUE; - /* Fall through */ - - /* We come here from the Python syntax above that handles both - references (?P=name) and recursion (?P>name), as well as falling - through from the Perl recursion syntax (?&name). We also come here from - the Perl \k or \k'name' back reference syntax and the \k{name} - .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */ - - NAMED_REF_OR_RECURSE: - name = ++ptr; - if (IS_DIGIT(*ptr)) - { - *errorcodeptr = ERR44; /* Group name must start with non-digit */ - goto FAILED; - } - /* Increment ptr, set namelen, check length */ - READ_NAME(ctype_word, ERR48, *errorcodeptr); - - /* In the pre-compile phase, do a syntax check. */ - - if (lengthptr != NULL) - { - if (namelen == 0) - { - *errorcodeptr = ERR62; - goto FAILED; - } - if (*ptr != (PCRE2_UCHAR)terminator) - { - *errorcodeptr = ERR42; - goto FAILED; - } - } - - /* Scan the list of names generated in the pre-pass in order to get - a number and whether or not this name is duplicated. */ - - recno = 0; - is_dupname = FALSE; - ng = cb->named_groups; - - for (i = 0; i < cb->names_found; i++, ng++) - { - if (namelen == ng->length && - PRIV(strncmp)(name, ng->name, namelen) == 0) - { - open_capitem *oc; - is_dupname = ng->isdup; - recno = ng->number; - - /* For a recursion, that's all that is needed. We can now go to the - code that handles numerical recursion. */ - - if (is_recurse) goto HANDLE_RECURSION; - - /* For a back reference, update the back reference map and the - maximum back reference. Then for each group we must check to see if - it is recursive, that is, it is inside the group that it - references. A flag is set so that the group can be made atomic. */ - - cb->backref_map |= (recno < 32)? (1u << recno) : 1; - if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; - - for (oc = cb->open_caps; oc != NULL; oc = oc->next) - { - if (oc->number == recno) - { - oc->flag = TRUE; - break; - } - } - } - } - - /* If the name was not found we have a bad reference. */ - - if (recno == 0) - { - *errorcodeptr = ERR15; - goto FAILED; - } - - /* If a back reference name is not duplicated, we can handle it as a - numerical reference. */ - - if (!is_dupname) goto HANDLE_REFERENCE; - - /* If a back reference name is duplicated, we generate a different - opcode to a numerical back reference. In the second pass we must search - for the index and count in the final name table. */ - - count = 0; - index = 0; - - if (lengthptr == NULL) - { - slot = cb->name_table; - for (i = 0; i < cb->names_found; i++) - { - if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0 && - slot[IMM2_SIZE+namelen] == 0) - { - if (count == 0) index = i; - count++; - } - slot += cb->name_entry_size; - } - - if (count == 0) - { - *errorcodeptr = ERR15; - goto FAILED; - } - } - - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - previous = code; - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF; - PUT2INC(code, 0, index); - PUT2INC(code, 0, count); - continue; /* End of back ref handling */ - - - /* ------------------------------------------------------------ */ - case CHAR_R: /* Recursion, same as (?0) */ - recno = 0; - if (*(++ptr) != CHAR_RIGHT_PARENTHESIS) - { - *errorcodeptr = ERR29; - goto FAILED; - } - goto HANDLE_RECURSION; - - - /* ------------------------------------------------------------ */ - case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */ - case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: - case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: - { - terminator = CHAR_RIGHT_PARENTHESIS; - - /* Come here from the \g<...> and \g'...' code (Oniguruma - compatibility). However, the syntax has been checked to ensure that - the ... are a (signed) number, so that neither ERR63 nor ERR29 will - be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY - ever be taken. */ - - HANDLE_NUMERICAL_RECURSION: - - if ((refsign = *ptr) == CHAR_PLUS) - { - ptr++; - if (!IS_DIGIT(*ptr)) - { - *errorcodeptr = ERR63; - goto FAILED; - } - } - else if (refsign == CHAR_MINUS) - { - if (!IS_DIGIT(ptr[1])) - goto OTHER_CHAR_AFTER_QUERY; - ptr++; - } - - recno = 0; - while (IS_DIGIT(*ptr)) - { - if (recno > INT_MAX / 10 - 1) /* Integer overflow */ - { - while (IS_DIGIT(*ptr)) ptr++; - *errorcodeptr = ERR61; - goto FAILED; - } - recno = recno * 10 + *ptr++ - CHAR_0; - } - - if (*ptr != (PCRE2_UCHAR)terminator) - { - *errorcodeptr = ERR29; - goto FAILED; - } - - if (refsign == CHAR_MINUS) - { - if (recno == 0) - { - *errorcodeptr = ERR58; - goto FAILED; - } - recno = (int)(cb->bracount + 1) - recno; - if (recno <= 0) - { - *errorcodeptr = ERR15; - goto FAILED; - } - } - else if (refsign == CHAR_PLUS) - { - if (recno == 0) - { - *errorcodeptr = ERR58; - goto FAILED; - } - recno += cb->bracount; - } - - if ((uint32_t)recno > cb->final_bracount) - { - *errorcodeptr = ERR15; - goto FAILED; - } - - /* Come here from code above that handles a named recursion. - We insert the number of the called group after OP_RECURSE. At the - end of compiling the pattern is scanned and these numbers are - replaced by offsets within the pattern. It is done like this to avoid - problems with forward references and adjusting offsets when groups - are duplicated and moved (as discovered in previous implementations). - Note that a recursion does not have a set first character (relevant - if it is repeated, because it will then be wrapped with ONCE - brackets). */ - - HANDLE_RECURSION: - previous = code; - *code = OP_RECURSE; - PUT(code, 1, recno); - code += 1 + LINK_SIZE; - groupsetfirstcu = FALSE; - cb->had_recurse = TRUE; - } - - /* Can't determine a first byte now */ - - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - continue; - - - /* ------------------------------------------------------------ */ - default: /* Other characters: check option setting */ - OTHER_CHAR_AFTER_QUERY: - set = unset = 0; - optset = &set; - - while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) - { - switch (*ptr++) - { - case CHAR_MINUS: optset = &unset; break; - - case CHAR_J: /* Record that it changed in the external options */ - *optset |= PCRE2_DUPNAMES; - cb->external_flags |= PCRE2_JCHANGED; - break; - - case CHAR_i: *optset |= PCRE2_CASELESS; break; - case CHAR_m: *optset |= PCRE2_MULTILINE; break; - case CHAR_s: *optset |= PCRE2_DOTALL; break; - case CHAR_x: *optset |= PCRE2_EXTENDED; break; - case CHAR_U: *optset |= PCRE2_UNGREEDY; break; - - default: *errorcodeptr = ERR11; - ptr--; /* Correct the offset */ - goto FAILED; - } - } - - /* Set up the changed option bits, but don't change anything yet. */ - - newoptions = (options | set) & (~unset); - - /* If the options ended with ')' this is not the start of a nested - group with option changes, so the options change at this level. They - must also be passed back for use in subsequent branches. Reset the - greedy defaults and the case value for firstcu and reqcu. */ - - if (*ptr == CHAR_RIGHT_PARENTHESIS) - { - *optionsptr = options = newoptions; - greedy_default = ((newoptions & PCRE2_UNGREEDY) != 0); - greedy_non_default = greedy_default ^ 1; - req_caseopt = ((newoptions & PCRE2_CASELESS) != 0)? REQ_CASELESS:0; - previous = NULL; /* This item can't be repeated */ - continue; /* It is complete */ - } - - /* If the options ended with ':' we are heading into a nested group - with possible change of options. Such groups are non-capturing and are - not assertions of any kind. All we need to do is skip over the ':'; - the newoptions value is handled below. */ - - bravalue = OP_BRA; - ptr++; - } /* End of switch for character following (? */ - } /* End of (? handling */ - - /* Opening parenthesis not followed by '*' or '?'. If PCRE2_NO_AUTO_CAPTURE - is set, all unadorned brackets become non-capturing and behave like (?:...) - brackets. */ - - else if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) - { - bravalue = OP_BRA; - } - - /* Else we have a capturing group. */ - - else - { - NUMBERED_GROUP: - cb->bracount += 1; - PUT2(code, 1+LINK_SIZE, cb->bracount); - skipunits = IMM2_SIZE; - } - - /* Process nested bracketed regex. First check for parentheses nested too - deeply. */ - - if ((cb->parens_depth += 1) > (int)(cb->cx->parens_nest_limit)) - { - *errorcodeptr = ERR19; - goto FAILED; - } - - /* All assertions used not to be repeatable, but this was changed for Perl - compatibility. All kinds can now be repeated except for assertions that are - conditions (Perl also forbids these to be repeated). We copy code into a - non-register variable (tempcode) in order to be able to pass its address - because some compilers complain otherwise. At the start of a conditional - group whose condition is an assertion, cb->iscondassert is set. We unset it - here so as to allow assertions later in the group to be quantified. */ - - if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT && - cb->iscondassert) - { - previous = NULL; - cb->iscondassert = FALSE; - } - else - { - previous = code; - } - - *code = bravalue; - tempcode = code; - tempreqvary = cb->req_varyopt; /* Save value before bracket */ - tempbracount = cb->bracount; /* Save value before bracket */ - length_prevgroup = 0; /* Initialize for pre-compile phase */ - - if (!compile_regex( - newoptions, /* The complete new option state */ - &tempcode, /* Where to put code (updated) */ - &ptr, /* Input pointer (updated) */ - errorcodeptr, /* Where to put an error message */ - (bravalue == OP_ASSERTBACK || - bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ - reset_bracount, /* True if (?| group */ - skipunits, /* Skip over bracket number */ - cond_depth + - ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ - &subfirstcu, /* For possible first char */ - &subfirstcuflags, - &subreqcu, /* For possible last char */ - &subreqcuflags, - bcptr, /* Current branch chain */ - cb, /* Compile data block */ - (lengthptr == NULL)? NULL : /* Actual compile phase */ - &length_prevgroup /* Pre-compile phase */ - )) - goto FAILED; - - cb->parens_depth -= 1; - - /* If this was an atomic group and there are no capturing groups within it, - generate OP_ONCE_NC instead of OP_ONCE. */ - - if (bravalue == OP_ONCE && cb->bracount <= tempbracount) - *code = OP_ONCE_NC; - - if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) - cb->assert_depth -= 1; - - /* At the end of compiling, code is still pointing to the start of the - group, while tempcode has been updated to point past the end of the group. - The pattern pointer (ptr) is on the bracket. - - If this is a conditional bracket, check that there are no more than - two branches in the group, or just one if it's a DEFINE group. We do this - in the real compile phase, not in the pre-pass, where the whole group may - not be available. */ - - if (bravalue == OP_COND && lengthptr == NULL) - { - PCRE2_UCHAR *tc = code; - int condcount = 0; - - do { - condcount++; - tc += GET(tc,1); - } - while (*tc != OP_KET); - - /* A DEFINE group is never obeyed inline (the "condition" is always - false). It must have only one branch. Having checked this, change the - opcode to OP_FALSE. */ - - if (code[LINK_SIZE+1] == OP_DEFINE) - { - if (condcount > 1) - { - *errorcodeptr = ERR54; - goto FAILED; - } - code[LINK_SIZE+1] = OP_FALSE; - bravalue = OP_DEFINE; /* Just a flag to suppress char handling below */ - } - - /* A "normal" conditional group. If there is just one branch, we must not - make use of its firstcu or reqcu, because this is equivalent to an - empty second branch. */ - - else - { - if (condcount > 2) - { - *errorcodeptr = ERR27; - goto FAILED; - } - if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE; - } - } - - /* Error if hit end of pattern */ - - if (*ptr != CHAR_RIGHT_PARENTHESIS) - { - *errorcodeptr = ERR14; - goto FAILED; - } - - /* In the pre-compile phase, update the length by the length of the group, - less the brackets at either end. Then reduce the compiled code to just a - set of non-capturing brackets so that it doesn't use much memory if it is - duplicated by a quantifier.*/ - - if (lengthptr != NULL) - { - if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE) - { - *errorcodeptr = ERR20; - goto FAILED; - } - *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; - code++; /* This already contains bravalue */ - PUTINC(code, 0, 1 + LINK_SIZE); - *code++ = OP_KET; - PUTINC(code, 0, 1 + LINK_SIZE); - break; /* No need to waste time with special character handling */ - } - - /* Otherwise update the main code pointer to the end of the group. */ - - code = tempcode; - - /* For a DEFINE group, required and first character settings are not - relevant. */ - - if (bravalue == OP_DEFINE) break; - - /* Handle updating of the required and first characters for other types of - group. Update for normal brackets of all kinds, and conditions with two - branches (see code above). If the bracket is followed by a quantifier with - zero repeat, we have to back off. Hence the definition of zeroreqcu and - zerofirstcu outside the main loop so that they can be accessed for the - back off. */ - - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - groupsetfirstcu = FALSE; - - if (bravalue >= OP_ONCE) - { - /* If we have not yet set a firstcu in this branch, take it from the - subpattern, remembering that it was set here so that a repeat of more - than one can replicate it as reqcu if necessary. If the subpattern has - no firstcu, set "none" for the whole branch. In both cases, a zero - repeat forces firstcu to "none". */ - - if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET) - { - if (subfirstcuflags >= 0) - { - firstcu = subfirstcu; - firstcuflags = subfirstcuflags; - groupsetfirstcu = TRUE; - } - else firstcuflags = REQ_NONE; - zerofirstcuflags = REQ_NONE; - } - - /* If firstcu was previously set, convert the subpattern's firstcu - into reqcu if there wasn't one, using the vary flag that was in - existence beforehand. */ - - else if (subfirstcuflags >= 0 && subreqcuflags < 0) - { - subreqcu = subfirstcu; - subreqcuflags = subfirstcuflags | tempreqvary; - } - - /* If the subpattern set a required byte (or set a first byte that isn't - really the first byte - see above), set it. */ - - if (subreqcuflags >= 0) - { - reqcu = subreqcu; - reqcuflags = subreqcuflags; - } - } - - /* For a forward assertion, we take the reqcu, if set. This can be - helpful if the pattern that follows the assertion doesn't set a different - char. For example, it's useful for /(?=abcde).+/. We can't set firstcu - for an assertion, however because it leads to incorrect effect for patterns - such as /(?=a)a.+/ when the "real" "a" would then become a reqcu instead - of a firstcu. This is overcome by a scan at the end if there's no - firstcu, looking for an asserted first char. */ - - else if (bravalue == OP_ASSERT && subreqcuflags >= 0) - { - reqcu = subreqcu; - reqcuflags = subreqcuflags; - } - break; /* End of processing '(' */ - - - /* ===================================================================*/ - /* Handle metasequences introduced by \. For ones like \d, the ESC_ values - are arranged to be the negation of the corresponding OP_values in the - default case when PCRE2_UCP is not set. For the back references, the values - are negative the reference number. Only back references and those types - that consume a character may be repeated. We can test for values between - ESC_b and ESC_Z for the latter; this may have to change if any new ones are - ever created. - - Note: \Q and \E are handled at the start of the character-processing loop, - not here. */ - - case CHAR_BACKSLASH: - tempptr = ptr; - escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr, - options, FALSE, cb); - if (*errorcodeptr != 0) goto FAILED; - - if (escape == 0) /* The escape coded a single character */ - c = ec; - else - { - /* For metasequences that actually match a character, we disable the - setting of a first character if it hasn't already been set. */ - - if (firstcuflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z) - firstcuflags = REQ_NONE; - - /* Set values to reset to if this is followed by a zero repeat. */ - - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - - /* \g or \g'name' is a subroutine call by name and \g or \g'n' - is a subroutine call by number (Oniguruma syntax). In fact, the value - ESC_g is returned only for these cases. So we don't need to check for < - or ' if the value is ESC_g. For the Perl syntax \g{n} the value is - -n, and for the Perl syntax \g{name} the result is ESC_k (as - that is a synonym for a named back reference). */ - - if (escape == ESC_g) - { - PCRE2_SPTR p; - uint32_t cf; - - terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? - CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; - - /* These two statements stop the compiler for warning about possibly - unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In - fact, because we do the check for a number below, the paths that - would actually be in error are never taken. */ - - skipunits = 0; - reset_bracount = FALSE; - - /* If it's not a signed or unsigned number, treat it as a name. */ - - cf = ptr[1]; - if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf)) - { - is_recurse = TRUE; - goto NAMED_REF_OR_RECURSE; - } - - /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus - or a digit. */ - - p = ptr + 2; - while (IS_DIGIT(*p)) p++; - if (*p != (PCRE2_UCHAR)terminator) - { - *errorcodeptr = ERR57; - goto FAILED; - } - ptr++; - goto HANDLE_NUMERICAL_RECURSION; - } - - /* \k or \k'name' is a back reference by name (Perl syntax). - We also support \k{name} (.NET syntax). */ - - if (escape == ESC_k) - { - if ((ptr[1] != CHAR_LESS_THAN_SIGN && - ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) - { - *errorcodeptr = ERR69; - goto FAILED; - } - is_recurse = FALSE; - terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? - CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)? - CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET; - goto NAMED_REF_OR_RECURSE; - } - - /* Back references are handled specially; must disable firstcu if - not set to cope with cases like (?=(\w+))\1: which would otherwise set - ':' later. */ - - if (escape < 0) - { - open_capitem *oc; - recno = -escape; - - /* Come here from named backref handling when the reference is to a - single group (i.e. not to a duplicated name). */ - - HANDLE_REFERENCE: - if (recno > (int)cb->final_bracount) - { - *errorcodeptr = ERR15; - goto FAILED; - } - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - previous = code; - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF; - PUT2INC(code, 0, recno); - cb->backref_map |= (recno < 32)? (1u << recno) : 1; - if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno; - - /* Check to see if this back reference is recursive, that it, it - is inside the group that it references. A flag is set so that the - group can be made atomic. */ - - for (oc = cb->open_caps; oc != NULL; oc = oc->next) - { - if (oc->number == recno) - { - oc->flag = TRUE; - break; - } - } - } - - /* So are Unicode property matches, if supported. */ - -#ifdef SUPPORT_UNICODE - else if (escape == ESC_P || escape == ESC_p) - { - BOOL negated; - unsigned int ptype = 0, pdata = 0; - if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb)) - goto FAILED; - previous = code; - *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP; - *code++ = ptype; - *code++ = pdata; - } -#else - - /* If Unicode properties are not supported, \X, \P, and \p are not - allowed. */ - - else if (escape == ESC_X || escape == ESC_P || escape == ESC_p) - { - *errorcodeptr = ERR45; - goto FAILED; - } -#endif - - /* The use of \C can be locked out. */ - -#ifdef NEVER_BACKSLASH_C - else if (escape == ESC_C) - { - *errorcodeptr = ERR85; - goto FAILED; - } -#else - else if (escape == ESC_C && (options & PCRE2_NEVER_BACKSLASH_C) != 0) - { - *errorcodeptr = ERR83; - goto FAILED; - } -#endif - - /* For the rest (including \X when Unicode properties are supported), we - can obtain the OP value by negating the escape value in the default - situation when PCRE2_UCP is not set. When it *is* set, we substitute - Unicode property tests. Note that \b and \B do a one-character - lookbehind, and \A also behaves as if it does. */ - - else - { - if (escape == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */ - if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) && - cb->max_lookbehind == 0) - cb->max_lookbehind = 1; -#ifdef SUPPORT_UNICODE - if (escape >= ESC_DU && escape <= ESC_wu) - { - cb->nestptr[1] = cb->nestptr[0]; /* Back up if at 2nd level */ - cb->nestptr[0] = ptr + 1; /* Where to resume */ - ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ - } - else -#endif - /* In non-UTF mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE - so that it works in DFA mode and in lookbehinds. */ - - { - previous = (escape > ESC_b && escape < ESC_Z)? code : NULL; - *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; - } - } - continue; - } - - /* We have a data character whose value is in c. In UTF-8 mode it may have - a value > 127. We set its representation in the length/buffer, and then - handle it as a data character. */ - - mclength = PUTCHAR(c, mcbuffer); - goto ONE_CHAR; - - - /* ===================================================================*/ - /* Handle a literal character. It is guaranteed not to be whitespace or # - when the extended flag is set. If we are in a UTF mode, it may be a - multi-unit literal character. */ - - default: - NORMAL_CHAR: - mclength = 1; - mcbuffer[0] = c; - -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(c)) - ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr)); -#endif - - /* At this point we have the character's bytes in mcbuffer, and the length - in mclength. When not in UTF mode, the length is always 1. */ - - ONE_CHAR: - previous = code; - - /* For caseless UTF mode, check whether this character has more than one - other case. If so, generate a special OP_PROP item instead of OP_CHARI. */ - -#ifdef SUPPORT_UNICODE - if (utf && (options & PCRE2_CASELESS) != 0) - { - GETCHAR(c, mcbuffer); - if ((c = UCD_CASESET(c)) != 0) - { - *code++ = OP_PROP; - *code++ = PT_CLIST; - *code++ = c; - if (firstcuflags == REQ_UNSET) - firstcuflags = zerofirstcuflags = REQ_NONE; - break; - } - } -#endif - - /* Caseful matches, or not one of the multicase characters. */ - - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR; - for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; - - /* Remember if \r or \n were seen */ - - if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL) - cb->external_flags |= PCRE2_HASCRORLF; - - /* Set the first and required bytes appropriately. If no previous first - byte, set it from this character, but revert to none on a zero repeat. - Otherwise, leave the firstcu value alone, and don't change it on a zero - repeat. */ - - if (firstcuflags == REQ_UNSET) - { - zerofirstcuflags = REQ_NONE; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - - /* If the character is more than one byte long, we can set firstcu - only if it is not to be matched caselessly. */ - - if (mclength == 1 || req_caseopt == 0) - { - firstcu = mcbuffer[0] | req_caseopt; - firstcu = mcbuffer[0]; - firstcuflags = req_caseopt; - - if (mclength != 1) - { - reqcu = code[-1]; - reqcuflags = cb->req_varyopt; - } - } - else firstcuflags = reqcuflags = REQ_NONE; - } - - /* firstcu was previously set; we can set reqcu only if the length is - 1 or the matching is caseful. */ - - else - { - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - if (mclength == 1 || req_caseopt == 0) - { - reqcu = code[-1]; - reqcuflags = req_caseopt | cb->req_varyopt; - } - } - - break; /* End of literal character handling */ - } - } /* end of big loop */ - -/* Control never reaches here by falling through, only by a goto for all the -error states. Pass back the position in the pattern so that it can be displayed -to the user for diagnosing the error. */ - -FAILED: -*ptrptr = ptr; -return FALSE; -} - - - -/************************************************* -* Compile regex: a sequence of alternatives * -*************************************************/ - -/* On entry, ptr is pointing past the bracket character, but on return it -points to the closing bracket, or vertical bar, or end of string. The code -variable is pointing at the byte into which the BRA operator has been stored. -This function is used during the pre-compile phase when we are trying to find -out the amount of memory needed, as well as during the real compile phase. The -value of lengthptr distinguishes the two phases. - -Arguments: - options option bits, including any changes for this subpattern - codeptr -> the address of the current code pointer - ptrptr -> the address of the current pattern pointer - errorcodeptr -> pointer to error code variable - lookbehind TRUE if this is a lookbehind assertion - reset_bracount TRUE to reset the count for each branch - skipunits skip this many code units at start (for brackets and OP_COND) - cond_depth depth of nesting for conditional subpatterns - firstcuptr place to put the first required code unit - firstcuflagsptr place to put the first code unit flags, or a negative number - reqcuptr place to put the last required code unit - reqcuflagsptr place to put the last required code unit flags, or a negative number - bcptr pointer to the chain of currently open branches - cb points to the data block with tables pointers etc. - lengthptr NULL during the real compile phase - points to length accumulator during pre-compile phase - -Returns: TRUE on success -*/ - -static BOOL -compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, PCRE2_SPTR *ptrptr, - int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, uint32_t skipunits, - int cond_depth, uint32_t *firstcuptr, int32_t *firstcuflagsptr, - uint32_t *reqcuptr, int32_t *reqcuflagsptr, branch_chain *bcptr, - compile_block *cb, size_t *lengthptr) -{ -PCRE2_SPTR ptr = *ptrptr; -PCRE2_UCHAR *code = *codeptr; -PCRE2_UCHAR *last_branch = code; -PCRE2_UCHAR *start_bracket = code; -PCRE2_UCHAR *reverse_count = NULL; -open_capitem capitem; -int capnumber = 0; -uint32_t firstcu, reqcu; -int32_t firstcuflags, reqcuflags; -uint32_t branchfirstcu, branchreqcu; -int32_t branchfirstcuflags, branchreqcuflags; -size_t length; -unsigned int orig_bracount; -unsigned int max_bracount; -branch_chain bc; - -/* If set, call the external function that checks for stack availability. */ - -if (cb->cx->stack_guard != NULL && - cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data)) - { - *errorcodeptr= ERR33; - return FALSE; - } - -/* Miscellaneous initialization */ - -bc.outer = bcptr; -bc.current_branch = code; - -firstcu = reqcu = 0; -firstcuflags = reqcuflags = REQ_UNSET; - -/* Accumulate the length for use in the pre-compile phase. Start with the -length of the BRA and KET and any extra code units that are required at the -beginning. We accumulate in a local variable to save frequent testing of -lengthptr for NULL. We cannot do this by looking at the value of 'code' at the -start and end of each alternative, because compiled items are discarded during -the pre-compile phase so that the work space is not exceeded. */ - -length = 2 + 2*LINK_SIZE + skipunits; - -/* WARNING: If the above line is changed for any reason, you must also change -the code that abstracts option settings at the start of the pattern and makes -them global. It tests the value of length for (2 + 2*LINK_SIZE) in the -pre-compile phase to find out whether or not anything has yet been compiled. - -If this is a capturing subpattern, add to the chain of open capturing items -so that we can detect them if (*ACCEPT) is encountered. This is also used to -detect groups that contain recursive back references to themselves. Note that -only OP_CBRA need be tested here; changing this opcode to one of its variants, -e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */ - -if (*code == OP_CBRA) - { - capnumber = GET2(code, 1 + LINK_SIZE); - capitem.number = capnumber; - capitem.next = cb->open_caps; - capitem.flag = FALSE; - cb->open_caps = &capitem; - } - -/* Offset is set zero to mark that this bracket is still open */ - -PUT(code, 1, 0); -code += 1 + LINK_SIZE + skipunits; - -/* Loop for each alternative branch */ - -orig_bracount = max_bracount = cb->bracount; - -for (;;) - { - /* For a (?| group, reset the capturing bracket count so that each branch - uses the same numbers. */ - - if (reset_bracount) cb->bracount = orig_bracount; - - /* Set up dummy OP_REVERSE if lookbehind assertion */ - - if (lookbehind) - { - *code++ = OP_REVERSE; - reverse_count = code; - PUTINC(code, 0, 0); - length += 1 + LINK_SIZE; - } - - /* Now compile the branch; in the pre-compile phase its length gets added - into the length. */ - - if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstcu, - &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc, - cond_depth, cb, (lengthptr == NULL)? NULL : &length)) - { - *ptrptr = ptr; - return FALSE; - } - - /* Keep the highest bracket count in case (?| was used and some branch - has fewer than the rest. */ - - if (cb->bracount > max_bracount) max_bracount = cb->bracount; - - /* In the real compile phase, there is some post-processing to be done. */ - - if (lengthptr == NULL) - { - /* If this is the first branch, the firstcu and reqcu values for the - branch become the values for the regex. */ - - if (*last_branch != OP_ALT) - { - firstcu = branchfirstcu; - firstcuflags = branchfirstcuflags; - reqcu = branchreqcu; - reqcuflags = branchreqcuflags; - } - - /* If this is not the first branch, the first char and reqcu have to - match the values from all the previous branches, except that if the - previous value for reqcu didn't have REQ_VARY set, it can still match, - and we set REQ_VARY for the regex. */ - - else - { - /* If we previously had a firstcu, but it doesn't match the new branch, - we have to abandon the firstcu for the regex, but if there was - previously no reqcu, it takes on the value of the old firstcu. */ - - if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu) - { - if (firstcuflags >= 0) - { - if (reqcuflags < 0) - { - reqcu = firstcu; - reqcuflags = firstcuflags; - } - } - firstcuflags = REQ_NONE; - } - - /* If we (now or from before) have no firstcu, a firstcu from the - branch becomes a reqcu if there isn't a branch reqcu. */ - - if (firstcuflags < 0 && branchfirstcuflags >= 0 && - branchreqcuflags < 0) - { - branchreqcu = branchfirstcu; - branchreqcuflags = branchfirstcuflags; - } - - /* Now ensure that the reqcus match */ - - if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) || - reqcu != branchreqcu) - reqcuflags = REQ_NONE; - else - { - reqcu = branchreqcu; - reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */ - } - } - - /* If lookbehind, check that this branch matches a fixed-length string, and - put the length into the OP_REVERSE item. Temporarily mark the end of the - branch with OP_END. If the branch contains OP_RECURSE, the result is - FFL_LATER (a negative value) because there may be forward references that - we can't check here. Set a flag to cause another lookbehind check at the - end. Why not do it all at the end? Because common errors can be picked up - here and the offset of the problem can be shown. */ - - if (lookbehind) - { - int fixed_length; - int count = 0; - *code = OP_END; - fixed_length = find_fixedlength(last_branch, (options & PCRE2_UTF) != 0, - FALSE, cb, NULL, &count); - if (fixed_length == FFL_LATER) - { - cb->check_lookbehind = TRUE; - } - else if (fixed_length < 0) - { - *errorcodeptr = fixed_length_errors[-fixed_length]; - *ptrptr = ptr; - return FALSE; - } - else - { - if (fixed_length > cb->max_lookbehind) - cb->max_lookbehind = fixed_length; - PUT(reverse_count, 0, fixed_length); - } - } - } - - /* Reached end of expression, either ')' or end of pattern. In the real - compile phase, go back through the alternative branches and reverse the chain - of offsets, with the field in the BRA item now becoming an offset to the - first alternative. If there are no alternatives, it points to the end of the - group. The length in the terminating ket is always the length of the whole - bracketed item. Return leaving the pointer at the terminating char. */ - - if (*ptr != CHAR_VERTICAL_LINE) - { - if (lengthptr == NULL) - { - size_t branch_length = code - last_branch; - do - { - size_t prev_length = GET(last_branch, 1); - PUT(last_branch, 1, branch_length); - branch_length = prev_length; - last_branch -= branch_length; - } - while (branch_length > 0); - } - - /* Fill in the ket */ - - *code = OP_KET; - PUT(code, 1, (int)(code - start_bracket)); - code += 1 + LINK_SIZE; - - /* If it was a capturing subpattern, check to see if it contained any - recursive back references. If so, we must wrap it in atomic brackets. In - any event, remove the block from the chain. */ - - if (capnumber > 0) - { - if (cb->open_caps->flag) - { - memmove(start_bracket + 1 + LINK_SIZE, start_bracket, - CU2BYTES(code - start_bracket)); - *start_bracket = OP_ONCE; - code += 1 + LINK_SIZE; - PUT(start_bracket, 1, (int)(code - start_bracket)); - *code = OP_KET; - PUT(code, 1, (int)(code - start_bracket)); - code += 1 + LINK_SIZE; - length += 2 + 2*LINK_SIZE; - } - cb->open_caps = cb->open_caps->next; - } - - /* Retain the highest bracket number, in case resetting was used. */ - - cb->bracount = max_bracount; - - /* Set values to pass back */ - - *codeptr = code; - *ptrptr = ptr; - *firstcuptr = firstcu; - *firstcuflagsptr = firstcuflags; - *reqcuptr = reqcu; - *reqcuflagsptr = reqcuflags; - if (lengthptr != NULL) - { - if (OFLOW_MAX - *lengthptr < length) - { - *errorcodeptr = ERR20; - return FALSE; - } - *lengthptr += length; - } - return TRUE; - } - - /* Another branch follows. In the pre-compile phase, we can move the code - pointer back to where it was for the start of the first branch. (That is, - pretend that each branch is the only one.) - - In the real compile phase, insert an ALT node. Its length field points back - to the previous branch while the bracket remains open. At the end the chain - is reversed. It's done like this so that the start of the bracket has a - zero offset until it is closed, making it possible to detect recursion. */ - - if (lengthptr != NULL) - { - code = *codeptr + 1 + LINK_SIZE + skipunits; - length += 1 + LINK_SIZE; - } - else - { - *code = OP_ALT; - PUT(code, 1, (int)(code - last_branch)); - bc.current_branch = last_branch = code; - code += 1 + LINK_SIZE; - } - - /* Advance past the vertical bar */ - - ptr++; - } -/* Control never reaches here */ -} - - - -/************************************************* -* Check for anchored pattern * -*************************************************/ - -/* Try to find out if this is an anchored regular expression. Consider each -alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket -all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then -it's anchored. However, if this is a multiline pattern, then only OP_SOD will -be found, because ^ generates OP_CIRCM in that mode. - -We can also consider a regex to be anchored if OP_SOM starts all its branches. -This is the code for \G, which means "match at start of match position, taking -into account the match offset". - -A branch is also implicitly anchored if it starts with .* and DOTALL is set, -because that will try the rest of the pattern at all possible matching points, -so there is no point trying again.... er .... - -.... except when the .* appears inside capturing parentheses, and there is a -subsequent back reference to those parentheses. We haven't enough information -to catch that case precisely. - -At first, the best we could do was to detect when .* was in capturing brackets -and the highest back reference was greater than or equal to that level. -However, by keeping a bitmap of the first 31 back references, we can catch some -of the more common cases more precisely. - -... A second exception is when the .* appears inside an atomic group, because -this prevents the number of characters it matches from being adjusted. - -Arguments: - code points to start of the compiled pattern - bracket_map a bitmap of which brackets we are inside while testing; this - handles up to substring 31; after that we just have to take - the less precise approach - cb points to the compile data block - atomcount atomic group level - -Returns: TRUE or FALSE -*/ - -static BOOL -is_anchored(register PCRE2_SPTR code, unsigned int bracket_map, - compile_block *cb, int atomcount) -{ -do { - PCRE2_SPTR scode = first_significant_code( - code + PRIV(OP_lengths)[*code], FALSE); - register int op = *scode; - - /* Non-capturing brackets */ - - if (op == OP_BRA || op == OP_BRAPOS || - op == OP_SBRA || op == OP_SBRAPOS) - { - if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE; - } - - /* Capturing brackets */ - - else if (op == OP_CBRA || op == OP_CBRAPOS || - op == OP_SCBRA || op == OP_SCBRAPOS) - { - int n = GET2(scode, 1+LINK_SIZE); - int new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_anchored(scode, new_map, cb, atomcount)) return FALSE; - } - - /* Positive forward assertions and conditions */ - - else if (op == OP_ASSERT || op == OP_COND) - { - if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE; - } - - /* Atomic groups */ - - else if (op == OP_ONCE || op == OP_ONCE_NC) - { - if (!is_anchored(scode, bracket_map, cb, atomcount + 1)) - return FALSE; - } - - /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and - it isn't in brackets that are or may be referenced or inside an atomic - group. There is also an option that disables auto-anchoring. */ - - else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || - op == OP_TYPEPOSSTAR)) - { - if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || - (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) - return FALSE; - } - - /* Check for explicit anchoring */ - - else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; - - code += GET(code, 1); - } -while (*code == OP_ALT); /* Loop for each alternative */ -return TRUE; -} - - - -/************************************************* -* Check for starting with ^ or .* * -*************************************************/ - -/* This is called to find out if every branch starts with ^ or .* so that -"first char" processing can be done to speed things up in multiline -matching and for non-DOTALL patterns that start with .* (which must start at -the beginning or after \n). As in the case of is_anchored() (see above), we -have to take account of back references to capturing brackets that contain .* -because in that case we can't make the assumption. Also, the appearance of .* -inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not -count, because once again the assumption no longer holds. - -Arguments: - code points to start of the compiled pattern or a group - bracket_map a bitmap of which brackets we are inside while testing; this - handles up to substring 31; after that we just have to take - the less precise approach - cb points to the compile data - atomcount atomic group level - -Returns: TRUE or FALSE -*/ - -static BOOL -is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb, - int atomcount) -{ -do { - PCRE2_SPTR scode = first_significant_code( - code + PRIV(OP_lengths)[*code], FALSE); - register int op = *scode; - - /* If we are at the start of a conditional assertion group, *both* the - conditional assertion *and* what follows the condition must satisfy the test - for start of line. Other kinds of condition fail. Note that there may be an - auto-callout at the start of a condition. */ - - if (op == OP_COND) - { - scode += 1 + LINK_SIZE; - - if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; - else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE); - - switch (*scode) - { - case OP_CREF: - case OP_DNCREF: - case OP_RREF: - case OP_DNRREF: - case OP_FAIL: - case OP_FALSE: - case OP_TRUE: - return FALSE; - - default: /* Assertion */ - if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; - do scode += GET(scode, 1); while (*scode == OP_ALT); - scode += 1 + LINK_SIZE; - break; - } - scode = first_significant_code(scode, FALSE); - op = *scode; - } - - /* Non-capturing brackets */ - - if (op == OP_BRA || op == OP_BRAPOS || - op == OP_SBRA || op == OP_SBRAPOS) - { - if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; - } - - /* Capturing brackets */ - - else if (op == OP_CBRA || op == OP_CBRAPOS || - op == OP_SCBRA || op == OP_SCBRAPOS) - { - int n = GET2(scode, 1+LINK_SIZE); - int new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_startline(scode, new_map, cb, atomcount)) return FALSE; - } - - /* Positive forward assertions */ - - else if (op == OP_ASSERT) - { - if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE; - } - - /* Atomic brackets */ - - else if (op == OP_ONCE || op == OP_ONCE_NC) - { - if (!is_startline(scode, bracket_map, cb, atomcount + 1)) return FALSE; - } - - /* .* means "start at start or after \n" if it isn't in atomic brackets or - brackets that may be referenced, as long as the pattern does not contain - *PRUNE or *SKIP, because these break the feature. Consider, for example, - /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the - start of a line. There is also an option that disables this optimization. */ - - else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) - { - if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || - (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) - return FALSE; - } - - /* Check for explicit circumflex; anything else gives a FALSE result. Note - in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC - because the number of characters matched by .* cannot be adjusted inside - them. */ - - else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; - - /* Move on to the next alternative */ - - code += GET(code, 1); - } -while (*code == OP_ALT); /* Loop for each alternative */ -return TRUE; -} - - - -/************************************************* -* Check for asserted fixed first code unit * -*************************************************/ - -/* During compilation, the "first code unit" settings from forward assertions -are discarded, because they can cause conflicts with actual literals that -follow. However, if we end up without a first code unit setting for an -unanchored pattern, it is worth scanning the regex to see if there is an -initial asserted first code unit. If all branches start with the same asserted -code unit, or with a non-conditional bracket all of whose alternatives start -with the same asserted code unit (recurse ad lib), then we return that code -unit, with the flags set to zero or REQ_CASELESS; otherwise return zero with -REQ_NONE in the flags. - -Arguments: - code points to start of compiled pattern - flags points to the first code unit flags - inassert TRUE if in an assertion - -Returns: the fixed first code unit, or 0 with REQ_NONE in flags -*/ - -static uint32_t -find_firstassertedcu(PCRE2_SPTR code, int32_t *flags, BOOL inassert) -{ -register uint32_t c = 0; -int cflags = REQ_NONE; - -*flags = REQ_NONE; -do { - uint32_t d; - int dflags; - int xl = (*code == OP_CBRA || *code == OP_SCBRA || - *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; - PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE); - register PCRE2_UCHAR op = *scode; - - switch(op) - { - default: - return 0; - - case OP_BRA: - case OP_BRAPOS: - case OP_CBRA: - case OP_SCBRA: - case OP_CBRAPOS: - case OP_SCBRAPOS: - case OP_ASSERT: - case OP_ONCE: - case OP_ONCE_NC: - d = find_firstassertedcu(scode, &dflags, op == OP_ASSERT); - if (dflags < 0) - return 0; - if (cflags < 0) { c = d; cflags = dflags; } - else if (c != d || cflags != dflags) return 0; - break; - - case OP_EXACT: - scode += IMM2_SIZE; - /* Fall through */ - - case OP_CHAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - if (!inassert) return 0; - if (cflags < 0) { c = scode[1]; cflags = 0; } - else if (c != scode[1]) return 0; - break; - - case OP_EXACTI: - scode += IMM2_SIZE; - /* Fall through */ - - case OP_CHARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - if (!inassert) return 0; - if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; } - else if (c != scode[1]) return 0; - break; - } - - code += GET(code, 1); - } -while (*code == OP_ALT); - -*flags = cflags; -return c; -} - - - -/************************************************* -* Add an entry to the name/number table * -*************************************************/ - -/* This function is called between compiling passes to add an entry to the -name/number table, maintaining alphabetical order. Checking for permitted -and forbidden duplicates has already been done. - -Arguments: - cb the compile data block - name the name to add - length the length of the name - groupno the group number - -Returns: nothing -*/ - -static void -add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length, - unsigned int groupno) -{ -int i; -PCRE2_UCHAR *slot = cb->name_table; - -for (i = 0; i < cb->names_found; i++) - { - int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length)); - if (crc == 0 && slot[IMM2_SIZE+length] != 0) - crc = -1; /* Current name is a substring */ - - /* Make space in the table and break the loop for an earlier name. For a - duplicate or later name, carry on. We do this for duplicates so that in the - simple case (when ?(| is not used) they are in order of their numbers. In all - cases they are in the order in which they appear in the pattern. */ - - if (crc < 0) - { - memmove(slot + cb->name_entry_size, slot, - CU2BYTES((cb->names_found - i) * cb->name_entry_size)); - break; - } - - /* Continue the loop for a later or duplicate name */ - - slot += cb->name_entry_size; - } - -PUT2(slot, 0, groupno); -memcpy(slot + IMM2_SIZE, name, CU2BYTES(length)); -cb->names_found++; - -/* Add a terminating zero and fill the rest of the slot with zeroes so that -the memory is all initialized. Otherwise valgrind moans about uninitialized -memory when saving serialized compiled patterns. */ - -memset(slot + IMM2_SIZE + length, 0, - CU2BYTES(cb->name_entry_size - length - IMM2_SIZE)); -} - - - -/************************************************* -* External function to compile a pattern * -*************************************************/ - -/* This function reads a regular expression in the form of a string and returns -a pointer to a block of store holding a compiled version of the expression. - -Arguments: - pattern the regular expression - patlen the length of the pattern, or PCRE2_ZERO_TERMINATED - options option bits - errorptr pointer to errorcode - erroroffset pointer to error offset - ccontext points to a compile context or is NULL - -Returns: pointer to compiled data block, or NULL on error, - with errorcode and erroroffset set -*/ - -PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION -pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options, - int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext) -{ -BOOL utf; /* Set TRUE for UTF mode */ -pcre2_real_code *re = NULL; /* What we will return */ -compile_block cb; /* "Static" compile-time data */ -const uint8_t *tables; /* Char tables base pointer */ - -PCRE2_UCHAR *code; /* Current pointer in compiled code */ -PCRE2_SPTR codestart; /* Start of compiled code */ -PCRE2_SPTR ptr; /* Current pointer in pattern */ - -size_t length = 1; /* Allow or final END opcode */ -size_t usedlength; /* Actual length used */ -size_t re_blocksize; /* Size of memory block */ - -int32_t firstcuflags, reqcuflags; /* Type of first/req code unit */ -uint32_t firstcu, reqcu; /* Value of first/req code unit */ -uint32_t setflags = 0; /* NL and BSR set flags */ - -uint32_t skipatstart; /* When checking (*UTF) etc */ -uint32_t limit_match = UINT32_MAX; /* Unset match limits */ -uint32_t limit_recursion = UINT32_MAX; - -int newline = 0; /* Unset; can be set by the pattern */ -int bsr = 0; /* Unset; can be set by the pattern */ -int errorcode = 0; /* Initialize to avoid compiler warn */ - -/* Comments at the head of this file explain about these variables. */ - -PCRE2_UCHAR *copied_pattern = NULL; -PCRE2_UCHAR stack_copied_pattern[COPIED_PATTERN_SIZE]; -named_group named_groups[NAMED_GROUP_LIST_SIZE]; - -/* The workspace is used in different ways in the different compiling phases. -It needs to be 16-bit aligned for the preliminary group scan, and 32-bit -aligned for the group information cache. */ - -uint32_t c32workspace[C32_WORK_SIZE]; -PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c32workspace; - - -/* -------------- Check arguments and set up the pattern ----------------- */ - -/* There must be error code and offset pointers. */ - -if (errorptr == NULL || erroroffset == NULL) return NULL; -*errorptr = ERR0; -*erroroffset = 0; - -/* There must be a pattern! */ - -if (pattern == NULL) - { - *errorptr = ERR16; - return NULL; - } - -/* Check that all undefined public option bits are zero. */ - -if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0) - { - *errorptr = ERR17; - return NULL; - } - -/* A NULL compile context means "use a default context" */ - -if (ccontext == NULL) - ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context)); - -/* A zero-terminated pattern is indicated by the special length value -PCRE2_ZERO_TERMINATED. Otherwise, we make a copy of the pattern and add a zero, -to ensure that it is always possible to look one code unit beyond the end of -the pattern's characters. In both cases, check that the pattern is overlong. */ - -if (patlen == PCRE2_ZERO_TERMINATED) - { - patlen = PRIV(strlen)(pattern); - if (patlen > ccontext->max_pattern_length) - { - *errorptr = ERR88; - return NULL; - } - } -else - { - if (patlen > ccontext->max_pattern_length) - { - *errorptr = ERR88; - return NULL; - } - if (patlen < COPIED_PATTERN_SIZE) - copied_pattern = stack_copied_pattern; - else - { - copied_pattern = ccontext->memctl.malloc(CU2BYTES(patlen + 1), - ccontext->memctl.memory_data); - if (copied_pattern == NULL) - { - *errorptr = ERR21; - return NULL; - } - } - memcpy(copied_pattern, pattern, CU2BYTES(patlen)); - copied_pattern[patlen] = 0; - pattern = copied_pattern; - } - -/* ------------ Initialize the "static" compile data -------------- */ - -tables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables); - -cb.lcc = tables + lcc_offset; /* Individual */ -cb.fcc = tables + fcc_offset; /* character */ -cb.cbits = tables + cbits_offset; /* tables */ -cb.ctypes = tables + ctypes_offset; - -cb.assert_depth = 0; -cb.bracount = cb.final_bracount = 0; -cb.cx = ccontext; -cb.dupnames = FALSE; -cb.end_pattern = pattern + patlen; -cb.nestptr[0] = cb.nestptr[1] = NULL; -cb.external_flags = 0; -cb.external_options = options; -cb.groupinfo = c32workspace; -cb.had_recurse = FALSE; -cb.iscondassert = FALSE; -cb.max_lookbehind = 0; -cb.name_entry_size = 0; -cb.name_table = NULL; -cb.named_groups = named_groups; -cb.named_group_list_size = NAMED_GROUP_LIST_SIZE; -cb.names_found = 0; -cb.open_caps = NULL; -cb.parens_depth = 0; -cb.req_varyopt = 0; -cb.start_code = cworkspace; -cb.start_pattern = pattern; -cb.start_workspace = cworkspace; -cb.workspace_size = COMPILE_WORK_SIZE; - -/* Maximum back reference and backref bitmap. The bitmap records up to 31 back -references to help in deciding whether (.*) can be treated as anchored or not. -*/ - -cb.top_backref = 0; -cb.backref_map = 0; - -/* --------------- Start looking at the pattern --------------- */ - -/* Check for global one-time option settings at the start of the pattern, and -remember the offset to the actual regex. */ - -ptr = pattern; -skipatstart = 0; - -while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && - ptr[skipatstart+1] == CHAR_ASTERISK) - { - unsigned int i; - for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) - { - pso *p = pso_list + i; - - if (PRIV(strncmp_c8)(ptr+skipatstart+2, (char *)(p->name), p->length) == 0) - { - uint32_t c, pp; - - skipatstart += p->length + 2; - switch(p->type) - { - case PSO_OPT: - cb.external_options |= p->value; - break; - - case PSO_FLG: - setflags |= p->value; - break; - - case PSO_NL: - newline = p->value; - setflags |= PCRE2_NL_SET; - break; - - case PSO_BSR: - bsr = p->value; - setflags |= PCRE2_BSR_SET; - break; - - case PSO_LIMM: - case PSO_LIMR: - c = 0; - pp = skipatstart; - if (!IS_DIGIT(ptr[pp])) - { - errorcode = ERR60; - ptr += pp; - goto HAD_ERROR; - } - while (IS_DIGIT(ptr[pp])) - { - if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */ - c = c*10 + (ptr[pp++] - CHAR_0); - } - if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS) - { - errorcode = ERR60; - ptr += pp; - goto HAD_ERROR; - } - if (p->type == PSO_LIMM) limit_match = c; - else limit_recursion = c; - skipatstart += pp - skipatstart; - break; - } - break; /* Out of the table scan loop */ - } - } - if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */ - } - -/* End of pattern-start options; advance to start of real regex. */ - -ptr += skipatstart; - -/* Can't support UTF or UCP unless PCRE2 has been compiled with UTF support. */ - -#ifndef SUPPORT_UNICODE -if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0) - { - errorcode = ERR32; - goto HAD_ERROR; - } -#endif - -/* Check UTF. We have the original options in 'options', with that value as -modified by (*UTF) etc in cb->external_options. */ - -utf = (cb.external_options & PCRE2_UTF) != 0; -if (utf) - { - if ((options & PCRE2_NEVER_UTF) != 0) - { - errorcode = ERR74; - goto HAD_ERROR; - } - if ((options & PCRE2_NO_UTF_CHECK) == 0 && - (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0) - goto HAD_UTF_ERROR; - } - -/* Check UCP lockout. */ - -if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) == - (PCRE2_UCP|PCRE2_NEVER_UCP)) - { - errorcode = ERR75; - goto HAD_ERROR; - } - -/* Process the BSR setting. */ - -if (bsr == 0) bsr = ccontext->bsr_convention; - -/* Process the newline setting. */ - -if (newline == 0) newline = ccontext->newline_convention; -cb.nltype = NLTYPE_FIXED; -switch(newline) - { - case PCRE2_NEWLINE_CR: - cb.nllen = 1; - cb.nl[0] = CHAR_CR; - break; - - case PCRE2_NEWLINE_LF: - cb.nllen = 1; - cb.nl[0] = CHAR_NL; - break; - - case PCRE2_NEWLINE_CRLF: - cb.nllen = 2; - cb.nl[0] = CHAR_CR; - cb.nl[1] = CHAR_NL; - break; - - case PCRE2_NEWLINE_ANY: - cb.nltype = NLTYPE_ANY; - break; - - case PCRE2_NEWLINE_ANYCRLF: - cb.nltype = NLTYPE_ANYCRLF; - break; - - default: - errorcode = ERR56; - goto HAD_ERROR; - } - -/* Before we do anything else, do a pre-scan of the pattern in order to -discover the named groups and their numerical equivalents, so that this -information is always available for the remaining processing. */ - -errorcode = scan_for_captures(&ptr, cb.external_options, &cb); -if (errorcode != 0) goto HAD_ERROR; - -/* For obscure debugging this code can be enabled. */ - -#if 0 - { - int i; - named_group *ng = cb.named_groups; - fprintf(stderr, "+++Captures: %d\n", cb.final_bracount); - for (i = 0; i < cb.names_found; i++, ng++) - { - fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name); - } - } -#endif - -/* Reset current bracket count to zero and current pointer to the start of the -pattern. */ - -cb.bracount = 0; -ptr = pattern + skipatstart; - -/* Pretend to compile the pattern while actually just accumulating the amount -of memory required in the 'length' variable. This behaviour is triggered by -passing a non-NULL final argument to compile_regex(). We pass a block of -workspace (cworkspace) for it to compile parts of the pattern into; the -compiled code is discarded when it is no longer needed, so hopefully this -workspace will never overflow, though there is a test for its doing so. - -On error, errorcode will be set non-zero, so we don't need to look at the -result of the function. The initial options have been put into the cb block so -that they can be changed if an option setting is found within the regex right -at the beginning. Bringing initial option settings outside can help speed up -starting point checks. We still have to pass a separate options variable (the -first argument) because that may change as the pattern is processed. */ - -code = cworkspace; -*code = OP_BRA; - -(void)compile_regex(cb.external_options, &code, &ptr, &errorcode, FALSE, - FALSE, 0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, - &cb, &length); - -if (errorcode != 0) goto HAD_ERROR; -if (length > MAX_PATTERN_SIZE) - { - errorcode = ERR20; - goto HAD_ERROR; - } - -/* Compute the size of, and then get and initialize, the data block for storing -the compiled pattern and names table. Integer overflow should no longer be -possible because nowadays we limit the maximum value of cb.names_found and -cb.name_entry_size. */ - -re_blocksize = sizeof(pcre2_real_code) + - CU2BYTES(length + cb.names_found * cb.name_entry_size); -re = (pcre2_real_code *) - ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data); -if (re == NULL) - { - errorcode = ERR21; - goto HAD_ERROR; - } - -re->memctl = ccontext->memctl; -re->tables = tables; -re->executable_jit = NULL; -memset(re->start_bitmap, 0, 32 * sizeof(uint8_t)); -re->blocksize = re_blocksize; -re->magic_number = MAGIC_NUMBER; -re->compile_options = options; -re->overall_options = cb.external_options; -re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags; -re->limit_match = limit_match; -re->limit_recursion = limit_recursion; -re->first_codeunit = 0; -re->last_codeunit = 0; -re->bsr_convention = bsr; -re->newline_convention = newline; -re->max_lookbehind = 0; -re->minlength = 0; -re->top_bracket = 0; -re->top_backref = 0; -re->name_entry_size = cb.name_entry_size; -re->name_count = cb.names_found; - -/* The basic block is immediately followed by the name table, and the compiled -code follows after that. */ - -codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_entry_size * re->name_count; - -/* Workspace is needed to remember information about numbered groups: whether a -group can match an empty string and what its fixed length is. This is done to -avoid the possibility of recursive references causing very long compile times -when checking these features. Unnumbered groups do not have this exposure since -they cannot be referenced. We use an indexed vector for this purpose. If there -are sufficiently few groups, it can be the c32workspace vector, as set up -above. Otherwise we have to get/free a special vector. The vector must be -initialized to zero. */ - -if (cb.final_bracount >= C32_WORK_SIZE) - { - cb.groupinfo = ccontext->memctl.malloc( - (cb.final_bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data); - if (cb.groupinfo == NULL) - { - errorcode = ERR21; - goto HAD_ERROR; - } - } -memset(cb.groupinfo, 0, (cb.final_bracount + 1) * sizeof(uint32_t)); - -/* Update the compile data block for the actual compile. The starting points of -the name/number translation table and of the code are passed around in the -compile data block. The start/end pattern and initial options are already set -from the pre-compile phase, as is the name_entry_size field. Reset the bracket -count and the names_found field. */ - -cb.parens_depth = 0; -cb.assert_depth = 0; -cb.bracount = 0; -cb.max_lookbehind = 0; -cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); -cb.start_code = codestart; -cb.iscondassert = FALSE; -cb.req_varyopt = 0; -cb.had_accept = FALSE; -cb.had_pruneorskip = FALSE; -cb.check_lookbehind = FALSE; -cb.open_caps = NULL; - -/* If any named groups were found, create the name/number table from the list -created in the pre-pass. */ - -if (cb.names_found > 0) - { - int i = cb.names_found; - named_group *ng = cb.named_groups; - cb.names_found = 0; - for (; i > 0; i--, ng++) - add_name_to_table(&cb, ng->name, ng->length, ng->number); - } - -/* Set up a starting, non-extracting bracket, then compile the expression. On -error, errorcode will be set non-zero, so we don't need to look at the result -of the function here. */ - -ptr = pattern + skipatstart; -code = (PCRE2_UCHAR *)codestart; -*code = OP_BRA; -(void)compile_regex(re->overall_options, &code, &ptr, &errorcode, FALSE, FALSE, - 0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL); - -re->top_bracket = cb.bracount; -re->top_backref = cb.top_backref; -re->max_lookbehind = cb.max_lookbehind; - -if (cb.had_accept) - { - reqcu = 0; /* Must disable after (*ACCEPT) */ - reqcuflags = REQ_NONE; - } - -/* If we have not reached end of pattern after a successful compile, there's an -excess bracket. Fill in the final opcode and check for disastrous overflow. -If no overflow, but the estimated length exceeds the really used length, adjust -the value of re->blocksize, and if valgrind support is configured, mark the -extra allocated memory as unaddressable, so that any out-of-bound reads can be -detected. */ - -if (errorcode == 0 && ptr < cb.end_pattern) errorcode = ERR22; -*code++ = OP_END; -usedlength = code - codestart; -if (usedlength > length) errorcode = ERR23; else - { - re->blocksize -= CU2BYTES(length - usedlength); -#ifdef SUPPORT_VALGRIND - VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength)); -#endif - } - -/* Scan the pattern for recursion/subroutine calls and convert the group -numbers into offsets. Maintain a small cache so that repeated groups containing -recursions are efficiently handled. */ - -#define RSCAN_CACHE_SIZE 8 - -if (errorcode == 0 && cb.had_recurse) - { - PCRE2_UCHAR *rcode; - PCRE2_SPTR rgroup; - int ccount = 0; - int start = RSCAN_CACHE_SIZE; - recurse_cache rc[RSCAN_CACHE_SIZE]; - - for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf); - rcode != NULL; - rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf)) - { - int i, p, recno; - - recno = (int)GET(rcode, 1); - if (recno == 0) rgroup = codestart; else - { - PCRE2_SPTR search_from = codestart; - rgroup = NULL; - for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7) - { - if (recno == rc[p].recno) - { - rgroup = rc[p].group; - break; - } - - /* Group n+1 must always start to the right of group n, so we can save - search time below when the new group number is greater than any of the - previously found groups. */ - - if (recno > rc[p].recno) search_from = rc[p].group; - } - - if (rgroup == NULL) - { - rgroup = PRIV(find_bracket)(search_from, utf, recno); - if (rgroup == NULL) - { - errorcode = ERR53; - break; - } - if (--start < 0) start = RSCAN_CACHE_SIZE - 1; - rc[start].recno = recno; - rc[start].group = rgroup; - if (ccount < RSCAN_CACHE_SIZE) ccount++; - } - } - - PUT(rcode, 1, rgroup - codestart); - } - } - -/* In rare debugging situations we sometimes need to look at the compiled code -at this stage. */ - -#ifdef CALL_PRINTINT -pcre2_printint(re, stderr, TRUE); -fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength); -#endif - -/* After a successful compile, give an error if there's back reference to a -non-existent capturing subpattern. Then, unless disabled, check whether any -single character iterators can be auto-possessified. The function overwrites -the appropriate opcode values, so the type of the pointer must be cast. NOTE: -the intermediate variable "temp" is used in this code because at least one -compiler gives a warning about loss of "const" attribute if the cast -(PCRE2_UCHAR *)codestart is used directly in the function call. */ - -if (errorcode == 0) - { - if (re->top_backref > re->top_bracket) errorcode = ERR15; - else if ((re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0) - { - PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart; - if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80; - } - } - -/* If there were any lookbehind assertions that contained OP_RECURSE -(recursions or subroutine calls), a flag is set for them to be checked here, -because they may contain forward references. Actual recursions cannot be fixed -length, but subroutine calls can. It is done like this so that those without -OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The -exceptional ones forgo this. We scan the pattern to check that they are fixed -length, and set their lengths. */ - -if (errorcode == 0 && cb.check_lookbehind) - { - PCRE2_UCHAR *cc = (PCRE2_UCHAR *)codestart; - - /* Loop, searching for OP_REVERSE items, and process those that do not have - their length set. (Actually, it will also re-process any that have a length - of zero, but that is a pathological case, and it does no harm.) When we find - one, we temporarily terminate the branch it is in while we scan it. Note that - calling find_bracket() with a negative group number returns a pointer to the - OP_REVERSE item, not the actual lookbehind. */ - - for (cc = (PCRE2_UCHAR *)PRIV(find_bracket)(codestart, utf, -1); - cc != NULL; - cc = (PCRE2_UCHAR *)PRIV(find_bracket)(cc, utf, -1)) - { - if (GET(cc, 1) == 0) - { - int fixed_length; - int count = 0; - PCRE2_UCHAR *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); - int end_op = *be; - *be = OP_END; - fixed_length = find_fixedlength(cc, utf, TRUE, &cb, NULL, &count); - *be = end_op; - if (fixed_length < 0) - { - errorcode = fixed_length_errors[-fixed_length]; - break; - } - if (fixed_length > cb.max_lookbehind) cb.max_lookbehind = fixed_length; - PUT(cc, 1, fixed_length); - } - cc += 1 + LINK_SIZE; - } - - /* The previous value of the maximum lookbehind was transferred to the - compiled regex block above. We could have updated this value in the loop - above, but keep the two values in step, just in case some later code below - uses the cb value. */ - - re->max_lookbehind = cb.max_lookbehind; - } - -/* Failed to compile, or error while post-processing. Earlier errors get here -via the dreaded goto. */ - -if (errorcode != 0) - { - HAD_ERROR: - *erroroffset = (int)(ptr - pattern); - HAD_UTF_ERROR: - *errorptr = errorcode; - pcre2_code_free(re); - re = NULL; - goto EXIT; - } - -/* Successful compile. If the anchored option was not passed, set it if -we can determine that the pattern is anchored by virtue of ^ characters or \A -or anything else, such as starting with non-atomic .* when DOTALL is set and -there are no occurrences of *PRUNE or *SKIP (though there is an option to -disable this case). */ - -if ((re->overall_options & PCRE2_ANCHORED) == 0 && - is_anchored(codestart, 0, &cb, 0)) - re->overall_options |= PCRE2_ANCHORED; - -/* If the pattern is still not anchored and we do not have a first code unit, -see if there is one that is asserted (these are not saved during the compile -because they can cause conflicts with actual literals that follow). This code -need not be obeyed if PCRE2_NO_START_OPTIMIZE is set, as the data it would -create will not be used. */ - -if ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0) - { - if (firstcuflags < 0) - firstcu = find_firstassertedcu(codestart, &firstcuflags, FALSE); - - /* Save the data for a first code unit. */ - - if (firstcuflags >= 0) - { - re->first_codeunit = firstcu; - re->flags |= PCRE2_FIRSTSET; - - /* Handle caseless first code units. */ - - if ((firstcuflags & REQ_CASELESS) != 0) - { - if (firstcu < 128 || (!utf && firstcu < 255)) - { - if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS; - } - - /* The first code unit is > 128 in UTF mode, or > 255 otherwise. In - 8-bit UTF mode, codepoints in the range 128-255 are introductory code - points and cannot have another case. In 16-bit and 32-bit modes, we can - check wide characters when UTF (and therefore UCP) is supported. */ - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - else if (firstcu <= MAX_UTF_CODE_POINT && - UCD_OTHERCASE(firstcu) != firstcu) - re->flags |= PCRE2_FIRSTCASELESS; -#endif - } - } - - /* When there is no first code unit, see if we can set the PCRE2_STARTLINE - flag. This is helpful for multiline matches when all branches start with ^ - and also when all branches start with non-atomic .* for non-DOTALL matches - when *PRUNE and SKIP are not present. (There is an option that disables this - case.) */ - - else if (is_startline(codestart, 0, &cb, 0)) re->flags |= PCRE2_STARTLINE; - } - -/* Handle the "required code unit", if one is set. In the case of an anchored -pattern, do this only if it follows a variable length item in the pattern. -Again, skip this if PCRE2_NO_START_OPTIMIZE is set. */ - -if (reqcuflags >= 0 && - ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0 || - (reqcuflags & REQ_VARY) != 0)) - { - re->last_codeunit = reqcu; - re->flags |= PCRE2_LASTSET; - - /* Handle caseless required code units as for first code units (above). */ - - if ((reqcuflags & REQ_CASELESS) != 0) - { - if (reqcu < 128 || (!utf && reqcu < 255)) - { - if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS; - } -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu) - re->flags |= PCRE2_LASTCASELESS; -#endif - } - } - -/* Check for a pattern than can match an empty string, so that this information -can be provided to applications. */ - -do - { - int count = 0; - int rc = could_be_empty_branch(codestart, code, utf, &cb, TRUE, NULL, &count); - if (rc < 0) - { - errorcode = ERR86; - goto HAD_ERROR; - } - if (rc > 0) - { - re->flags |= PCRE2_MATCH_EMPTY; - break; - } - codestart += GET(codestart, 1); - } -while (*codestart == OP_ALT); - -/* Finally, unless PCRE2_NO_START_OPTIMIZE is set, study the compiled pattern -to set up information such as a bitmap of starting code units and a minimum -matching length. */ - -if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && - PRIV(study)(re) != 0) - { - errorcode = ERR31; - goto HAD_ERROR; - } - -/* Control ends up here in all cases. If memory was obtained for a -zero-terminated copy of the pattern, remember to free it before returning. Also -free the list of named groups if a larger one had to be obtained, and likewise -the group information vector. */ - -EXIT: -if (copied_pattern != stack_copied_pattern) - ccontext->memctl.free(copied_pattern, ccontext->memctl.memory_data); -if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE) - ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data); -if (cb.groupinfo != c32workspace) - ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data); - -return re; /* Will be NULL after an error */ -} - -/* End of pcre2_compile.c */ diff --git a/pcre2/src/pcre2_config.c b/pcre2/src/pcre2_config.c deleted file mode 100644 index 921845949..000000000 --- a/pcre2/src/pcre2_config.c +++ /dev/null @@ -1,217 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes -its value gets changed by pcre2_internal.h to be in code units. */ - -static int configured_link_size = LINK_SIZE; - -#include "pcre2_internal.h" - -/* These macros are the standard way of turning unquoted text into C strings. -They allow macros like PCRE2_MAJOR to be defined without quotes, which is -convenient for user programs that want to test their values. */ - -#define STRING(a) # a -#define XSTRING(s) STRING(s) - - -/************************************************* -* Return info about what features are configured * -*************************************************/ - -/* -Arguments: - what what information is required - where where to put the information - -Returns: 0 if data returned - >= 0 if where is NULL, giving length required - PCRE2_ERROR_BADOPTION if "where" not recognized - or JIT target requested when JIT not enabled -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_config(uint32_t what, void *where) -{ -if (where == NULL) /* Requests a length */ - { - switch(what) - { - default: - return PCRE2_ERROR_BADOPTION; - - case PCRE2_CONFIG_BSR: - case PCRE2_CONFIG_JIT: - case PCRE2_CONFIG_LINKSIZE: - case PCRE2_CONFIG_MATCHLIMIT: - case PCRE2_CONFIG_NEWLINE: - case PCRE2_CONFIG_PARENSLIMIT: - case PCRE2_CONFIG_RECURSIONLIMIT: - case PCRE2_CONFIG_STACKRECURSE: - case PCRE2_CONFIG_UNICODE: - return sizeof(uint32_t); - - /* These are handled below */ - - case PCRE2_CONFIG_JITTARGET: - case PCRE2_CONFIG_UNICODE_VERSION: - case PCRE2_CONFIG_VERSION: - break; - } - } - -switch (what) - { - default: - return PCRE2_ERROR_BADOPTION; - - case PCRE2_CONFIG_BSR: -#ifdef BSR_ANYCRLF - *((uint32_t *)where) = PCRE2_BSR_ANYCRLF; -#else - *((uint32_t *)where) = PCRE2_BSR_UNICODE; -#endif - break; - - case PCRE2_CONFIG_JIT: -#ifdef SUPPORT_JIT - *((uint32_t *)where) = 1; -#else - *((uint32_t *)where) = 0; -#endif - break; - - case PCRE2_CONFIG_JITTARGET: -#ifdef SUPPORT_JIT - { - const char *v = PRIV(jit_get_target)(); - return 1 + ((where == NULL)? - strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); - } -#else - return PCRE2_ERROR_BADOPTION; -#endif - - case PCRE2_CONFIG_LINKSIZE: - *((uint32_t *)where) = configured_link_size; - break; - - case PCRE2_CONFIG_MATCHLIMIT: - *((uint32_t *)where) = MATCH_LIMIT; - break; - - case PCRE2_CONFIG_NEWLINE: - *((uint32_t *)where) = NEWLINE_DEFAULT; - break; - - case PCRE2_CONFIG_PARENSLIMIT: - *((uint32_t *)where) = PARENS_NEST_LIMIT; - break; - - case PCRE2_CONFIG_RECURSIONLIMIT: - *((uint32_t *)where) = MATCH_LIMIT_RECURSION; - break; - - case PCRE2_CONFIG_STACKRECURSE: -#ifdef HEAP_MATCH_RECURSE - *((uint32_t *)where) = 0; -#else - *((uint32_t *)where) = 1; -#endif - break; - - case PCRE2_CONFIG_UNICODE_VERSION: - { -#if defined SUPPORT_UNICODE - const char *v = PRIV(unicode_version); -#else - const char *v = "Unicode not supported"; -#endif - return 1 + ((where == NULL)? - strlen(v): PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); - } - break; - - case PCRE2_CONFIG_UNICODE: -#if defined SUPPORT_UNICODE - *((uint32_t *)where) = 1; -#else - *((uint32_t *)where) = 0; -#endif - break; - - /* The hackery in setting "v" below is to cope with the case when - PCRE2_PRERELEASE is set to an empty string (which it is for real releases). - If the second alternative is used in this case, it does not leave a space - before the date. On the other hand, if all four macros are put into a single - XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted. - There are problems using an "obvious" approach like this: - - XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR) - XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE) - - because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion - of STRING(). The C standard states: "If (before argument substitution) any - argument consists of no preprocessing tokens, the behavior is undefined." It - turns out the gcc treats this case as a single empty string - which is what - we really want - but Visual C grumbles about the lack of an argument for the - macro. Unfortunately, both are within their rights. As there seems to be no - way to test for a macro's value being empty at compile time, we have to - resort to a runtime test. */ - - case PCRE2_CONFIG_VERSION: - { - const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)? - XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) : - XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE); - return 1 + ((where == NULL)? - strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); - } - } - -return 0; -} - -/* End of pcre2_config.c */ diff --git a/pcre2/src/pcre2_context.c b/pcre2/src/pcre2_context.c deleted file mode 100644 index ae050fe92..000000000 --- a/pcre2/src/pcre2_context.c +++ /dev/null @@ -1,391 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - - -/************************************************* -* Default malloc/free functions * -*************************************************/ - -/* Ignore the "user data" argument in each case. */ - -static void *default_malloc(size_t size, void *data) -{ -(void)data; -return malloc(size); -} - - -static void default_free(void *block, void *data) -{ -(void)data; -free(block); -} - - - -/************************************************* -* Get a block and save memory control * -*************************************************/ - -/* This internal function is called to get a block of memory in which the -memory control data is to be stored at the start for future use. - -Arguments: - size amount of memory required - memctl pointer to a memctl block or NULL - -Returns: pointer to memory or NULL on failure -*/ - -extern void * -PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl) -{ -pcre2_memctl *newmemctl; -void *yield = (memctl == NULL)? malloc(size) : - memctl->malloc(size, memctl->memory_data); -if (yield == NULL) return NULL; -newmemctl = (pcre2_memctl *)yield; -if (memctl == NULL) - { - newmemctl->malloc = default_malloc; - newmemctl->free = default_free; - newmemctl->memory_data = NULL; - } -else *newmemctl = *memctl; -return yield; -} - - - -/************************************************* -* Create and initialize contexts * -*************************************************/ - -/* Initializing for compile and match contexts is done in separate, private -functions so that these can be called from functions such as pcre2_compile() -when an external context is not supplied. The initializing functions have an -option to set up default memory management. */ - -PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION -pcre2_general_context_create(void *(*private_malloc)(size_t, void *), - void (*private_free)(void *, void *), void *memory_data) -{ -pcre2_general_context *gcontext; -if (private_malloc == NULL) private_malloc = default_malloc; -if (private_free == NULL) private_free = default_free; -gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data); -if (gcontext == NULL) return NULL; -gcontext->memctl.malloc = private_malloc; -gcontext->memctl.free = private_free; -gcontext->memctl.memory_data = memory_data; -return gcontext; -} - - -/* A default compile context is set up to save having to initialize at run time -when no context is supplied to the compile function. */ - -const pcre2_compile_context PRIV(default_compile_context) = { - { default_malloc, default_free, NULL }, /* Default memory handling */ - NULL, /* Stack guard */ - NULL, /* Stack guard data */ - PRIV(default_tables), /* Character tables */ - PCRE2_UNSET, /* Max pattern length */ - BSR_DEFAULT, /* Backslash R default */ - NEWLINE_DEFAULT, /* Newline convention */ - PARENS_NEST_LIMIT }; /* As it says */ - -/* The create function copies the default into the new memory, but must -override the default memory handling functions if a gcontext was provided. */ - -PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION -pcre2_compile_context_create(pcre2_general_context *gcontext) -{ -pcre2_compile_context *ccontext = PRIV(memctl_malloc)( - sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext); -if (ccontext == NULL) return NULL; -*ccontext = PRIV(default_compile_context); -if (gcontext != NULL) - *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext); -return ccontext; -} - - -/* A default match context is set up to save having to initialize at run time -when no context is supplied to a match function. */ - -const pcre2_match_context PRIV(default_match_context) = { - { default_malloc, default_free, NULL }, -#ifdef HEAP_MATCH_RECURSE - { default_malloc, default_free, NULL }, -#endif -#ifdef SUPPORT_JIT - NULL, - NULL, -#endif - NULL, - NULL, - PCRE2_UNSET, /* Offset limit */ - MATCH_LIMIT, - MATCH_LIMIT_RECURSION }; - -/* The create function copies the default into the new memory, but must -override the default memory handling functions if a gcontext was provided. */ - -PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION -pcre2_match_context_create(pcre2_general_context *gcontext) -{ -pcre2_match_context *mcontext = PRIV(memctl_malloc)( - sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext); -if (mcontext == NULL) return NULL; -*mcontext = PRIV(default_match_context); -if (gcontext != NULL) - *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext); -return mcontext; -} - - -/************************************************* -* Context copy functions * -*************************************************/ - -PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION -pcre2_general_context_copy(pcre2_general_context *gcontext) -{ -pcre2_general_context *new = - gcontext->memctl.malloc(sizeof(pcre2_real_general_context), - gcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, gcontext, sizeof(pcre2_real_general_context)); -return new; -} - - -PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION -pcre2_compile_context_copy(pcre2_compile_context *ccontext) -{ -pcre2_compile_context *new = - ccontext->memctl.malloc(sizeof(pcre2_real_compile_context), - ccontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, ccontext, sizeof(pcre2_real_compile_context)); -return new; -} - - -PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION -pcre2_match_context_copy(pcre2_match_context *mcontext) -{ -pcre2_match_context *new = - mcontext->memctl.malloc(sizeof(pcre2_real_match_context), - mcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, mcontext, sizeof(pcre2_real_match_context)); -return new; -} - - - -/************************************************* -* Context free functions * -*************************************************/ - - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_general_context_free(pcre2_general_context *gcontext) -{ -if (gcontext != NULL) - gcontext->memctl.free(gcontext, gcontext->memctl.memory_data); -} - - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_compile_context_free(pcre2_compile_context *ccontext) -{ -if (ccontext != NULL) - ccontext->memctl.free(ccontext, ccontext->memctl.memory_data); -} - - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_match_context_free(pcre2_match_context *mcontext) -{ -if (mcontext != NULL) - mcontext->memctl.free(mcontext, mcontext->memctl.memory_data); -} - - - - -/************************************************* -* Set values in contexts * -*************************************************/ - -/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid -data is given. Only some of the functions are able to test the validity of the -data. */ - - -/* ------------ Compile contexts ------------ */ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_character_tables(pcre2_compile_context *ccontext, - const unsigned char *tables) -{ -ccontext->tables = tables; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value) -{ -switch(value) - { - case PCRE2_BSR_ANYCRLF: - case PCRE2_BSR_UNICODE: - ccontext->bsr_convention = value; - return 0; - - default: - return PCRE2_ERROR_BADDATA; - } -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length) -{ -ccontext->max_pattern_length = length; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline) -{ -switch(newline) - { - case PCRE2_NEWLINE_CR: - case PCRE2_NEWLINE_LF: - case PCRE2_NEWLINE_CRLF: - case PCRE2_NEWLINE_ANY: - case PCRE2_NEWLINE_ANYCRLF: - ccontext->newline_convention = newline; - return 0; - - default: - return PCRE2_ERROR_BADDATA; - } -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit) -{ -ccontext->parens_nest_limit = limit; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext, - int (*guard)(uint32_t, void *), void *user_data) -{ -ccontext->stack_guard = guard; -ccontext->stack_guard_data = user_data; -return 0; -} - - -/* ------------ Match contexts ------------ */ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_callout(pcre2_match_context *mcontext, - int (*callout)(pcre2_callout_block *, void *), void *callout_data) -{ -mcontext->callout = callout; -mcontext->callout_data = callout_data; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit) -{ -mcontext->match_limit = limit; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit) -{ -mcontext->offset_limit = limit; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit) -{ -mcontext->recursion_limit = limit; -return 0; -} - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_recursion_memory_management(pcre2_match_context *mcontext, - void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *), - void *mydata) -{ -#ifdef HEAP_MATCH_RECURSE -mcontext->stack_memctl.malloc = mymalloc; -mcontext->stack_memctl.free = myfree; -mcontext->stack_memctl.memory_data = mydata; -#else -(void)mcontext; -(void)mymalloc; -(void)myfree; -(void)mydata; -#endif -return 0; -} - -/* End of pcre2_context.c */ diff --git a/pcre2/src/pcre2_dfa_match.c b/pcre2/src/pcre2_dfa_match.c deleted file mode 100644 index 76bc08525..000000000 --- a/pcre2/src/pcre2_dfa_match.c +++ /dev/null @@ -1,3618 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains the external function pcre2_dfa_match(), which is an -alternative matching function that uses a sort of DFA algorithm (not a true -FSM). This is NOT Perl-compatible, but it has advantages in certain -applications. */ - - -/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved -the performance of his patterns greatly. I could not use it as it stood, as it -was not thread safe, and made assumptions about pattern sizes. Also, it caused -test 7 to loop, and test 9 to crash with a segfault. - -The issue is the check for duplicate states, which is done by a simple linear -search up the state list. (Grep for "duplicate" below to find the code.) For -many patterns, there will never be many states active at one time, so a simple -linear search is fine. In patterns that have many active states, it might be a -bottleneck. The suggested code used an indexing scheme to remember which states -had previously been used for each character, and avoided the linear search when -it knew there was no chance of a duplicate. This was implemented when adding -states to the state lists. - -I wrote some thread-safe, not-limited code to try something similar at the time -of checking for duplicates (instead of when adding states), using index vectors -on the stack. It did give a 13% improvement with one specially constructed -pattern for certain subject strings, but on other strings and on many of the -simpler patterns in the test suite it did worse. The major problem, I think, -was the extra time to initialize the index. This had to be done for each call -of internal_dfa_match(). (The supplied patch used a static vector, initialized -only once - I suspect this was the cause of the problems with the tests.) - -Overall, I concluded that the gains in some cases did not outweigh the losses -in others, so I abandoned this code. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define NLBLOCK mb /* Block containing newline information */ -#define PSSTART start_subject /* Field containing processed string start */ -#define PSEND end_subject /* Field containing processed string end */ - -#include "pcre2_internal.h" - -#define PUBLIC_DFA_MATCH_OPTIONS \ - (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ - PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART) - - -/************************************************* -* Code parameters and static tables * -*************************************************/ - -/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes -into others, under special conditions. A gap of 20 between the blocks should be -enough. The resulting opcodes don't have to be less than 256 because they are -never stored, so we push them well clear of the normal opcodes. */ - -#define OP_PROP_EXTRA 300 -#define OP_EXTUNI_EXTRA 320 -#define OP_ANYNL_EXTRA 340 -#define OP_HSPACE_EXTRA 360 -#define OP_VSPACE_EXTRA 380 - - -/* This table identifies those opcodes that are followed immediately by a -character that is to be tested in some way. This makes it possible to -centralize the loading of these characters. In the case of Type * etc, the -"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a -small value. Non-zero values in the table are the offsets from the opcode where -the character is to be found. ***NOTE*** If the start of this table is -modified, the three tables that follow must also be modified. */ - -static const uint8_t coptable[] = { - 0, /* End */ - 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */ - 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */ - 0, 0, 0, /* Any, AllAny, Anybyte */ - 0, 0, /* \P, \p */ - 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ - 0, /* \X */ - 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ - 1, /* Char */ - 1, /* Chari */ - 1, /* not */ - 1, /* noti */ - /* Positive single-char repeats */ - 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */ - 1+IMM2_SIZE, /* exact */ - 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */ - 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */ - 1+IMM2_SIZE, /* exact I */ - 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ - /* Negative single-char repeats - only for chars < 256 */ - 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */ - 1+IMM2_SIZE, /* NOT exact */ - 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */ - 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */ - 1+IMM2_SIZE, /* NOT exact I */ - 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */ - /* Positive type repeats */ - 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */ - 1+IMM2_SIZE, /* Type exact */ - 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */ - /* Character class & ref repeats */ - 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ - 0, 0, /* CRRANGE, CRMINRANGE */ - 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */ - 0, /* CLASS */ - 0, /* NCLASS */ - 0, /* XCLASS - variable length */ - 0, /* REF */ - 0, /* REFI */ - 0, /* DNREF */ - 0, /* DNREFI */ - 0, /* RECURSE */ - 0, /* CALLOUT */ - 0, /* CALLOUT_STR */ - 0, /* Alt */ - 0, /* Ket */ - 0, /* KetRmax */ - 0, /* KetRmin */ - 0, /* KetRpos */ - 0, /* Reverse */ - 0, /* Assert */ - 0, /* Assert not */ - 0, /* Assert behind */ - 0, /* Assert behind not */ - 0, 0, /* ONCE, ONCE_NC */ - 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ - 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ - 0, 0, /* CREF, DNCREF */ - 0, 0, /* RREF, DNRREF */ - 0, 0, /* FALSE, TRUE */ - 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ - 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ -}; - -/* This table identifies those opcodes that inspect a character. It is used to -remember the fact that a character could have been inspected when the end of -the subject is reached. ***NOTE*** If the start of this table is modified, the -two tables that follow must also be modified. */ - -static const uint8_t poptable[] = { - 0, /* End */ - 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */ - 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ - 1, 1, 1, /* Any, AllAny, Anybyte */ - 1, 1, /* \P, \p */ - 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ - 1, /* \X */ - 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ - 1, /* Char */ - 1, /* Chari */ - 1, /* not */ - 1, /* noti */ - /* Positive single-char repeats */ - 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ - 1, 1, 1, /* upto, minupto, exact */ - 1, 1, 1, 1, /* *+, ++, ?+, upto+ */ - 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ - 1, 1, 1, /* upto I, minupto I, exact I */ - 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */ - /* Negative single-char repeats - only for chars < 256 */ - 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ - 1, 1, 1, /* NOT upto, minupto, exact */ - 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */ - 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ - 1, 1, 1, /* NOT upto I, minupto I, exact I */ - 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */ - /* Positive type repeats */ - 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ - 1, 1, 1, /* Type upto, minupto, exact */ - 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */ - /* Character class & ref repeats */ - 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ - 1, 1, /* CRRANGE, CRMINRANGE */ - 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */ - 1, /* CLASS */ - 1, /* NCLASS */ - 1, /* XCLASS - variable length */ - 0, /* REF */ - 0, /* REFI */ - 0, /* DNREF */ - 0, /* DNREFI */ - 0, /* RECURSE */ - 0, /* CALLOUT */ - 0, /* CALLOUT_STR */ - 0, /* Alt */ - 0, /* Ket */ - 0, /* KetRmax */ - 0, /* KetRmin */ - 0, /* KetRpos */ - 0, /* Reverse */ - 0, /* Assert */ - 0, /* Assert not */ - 0, /* Assert behind */ - 0, /* Assert behind not */ - 0, 0, /* ONCE, ONCE_NC */ - 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ - 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ - 0, 0, /* CREF, DNCREF */ - 0, 0, /* RREF, DNRREF */ - 0, 0, /* FALSE, TRUE */ - 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ - 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ -}; - -/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, -and \w */ - -static const uint8_t toptable1[] = { - 0, 0, 0, 0, 0, 0, - ctype_digit, ctype_digit, - ctype_space, ctype_space, - ctype_word, ctype_word, - 0, 0 /* OP_ANY, OP_ALLANY */ -}; - -static const uint8_t toptable2[] = { - 0, 0, 0, 0, 0, 0, - ctype_digit, 0, - ctype_space, 0, - ctype_word, 0, - 1, 1 /* OP_ANY, OP_ALLANY */ -}; - - -/* Structure for holding data about a particular state, which is in effect the -current data for an active path through the match tree. It must consist -entirely of ints because the working vector we are passed, and which we put -these structures in, is a vector of ints. */ - -typedef struct stateblock { - int offset; /* Offset to opcode (-ve has meaning) */ - int count; /* Count for repeats */ - int data; /* Some use extra data */ -} stateblock; - -#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) - - - -/************************************************* -* Match a Regular Expression - DFA engine * -*************************************************/ - -/* This internal function applies a compiled pattern to a subject string, -starting at a given point, using a DFA engine. This function is called from the -external one, possibly multiple times if the pattern is not anchored. The -function calls itself recursively for some kinds of subpattern. - -Arguments: - mb the match_data block with fixed information - this_start_code the opening bracket of this subexpression's code - current_subject where we currently are in the subject string - start_offset start offset in the subject string - offsets vector to contain the matching string offsets - offsetcount size of same - workspace vector of workspace - wscount size of same - rlevel function call recursion level - -Returns: > 0 => number of match offset pairs placed in offsets - = 0 => offsets overflowed; longest matches are present - -1 => failed to match - < -1 => some kind of unexpected problem - -The following macros are used for adding states to the two state vectors (one -for the current character, one for the following character). */ - -#define ADD_ACTIVE(x,y) \ - if (active_count++ < wscount) \ - { \ - next_active_state->offset = (x); \ - next_active_state->count = (y); \ - next_active_state++; \ - } \ - else return PCRE2_ERROR_DFA_WSSIZE - -#define ADD_ACTIVE_DATA(x,y,z) \ - if (active_count++ < wscount) \ - { \ - next_active_state->offset = (x); \ - next_active_state->count = (y); \ - next_active_state->data = (z); \ - next_active_state++; \ - } \ - else return PCRE2_ERROR_DFA_WSSIZE - -#define ADD_NEW(x,y) \ - if (new_count++ < wscount) \ - { \ - next_new_state->offset = (x); \ - next_new_state->count = (y); \ - next_new_state++; \ - } \ - else return PCRE2_ERROR_DFA_WSSIZE - -#define ADD_NEW_DATA(x,y,z) \ - if (new_count++ < wscount) \ - { \ - next_new_state->offset = (x); \ - next_new_state->count = (y); \ - next_new_state->data = (z); \ - next_new_state++; \ - } \ - else return PCRE2_ERROR_DFA_WSSIZE - -/* And now, here is the code */ - -static int -internal_dfa_match( - dfa_match_block *mb, - PCRE2_SPTR this_start_code, - PCRE2_SPTR current_subject, - PCRE2_SIZE start_offset, - PCRE2_SIZE *offsets, - uint32_t offsetcount, - int *workspace, - int wscount, - int rlevel) -{ -stateblock *active_states, *new_states, *temp_states; -stateblock *next_active_state, *next_new_state; - -const uint8_t *ctypes, *lcc, *fcc; -PCRE2_SPTR ptr; -PCRE2_SPTR end_code; -PCRE2_SPTR first_op; - -dfa_recursion_info new_recursive; - -int active_count, new_count, match_count; - -/* Some fields in the mb block are frequently referenced, so we load them into -independent variables in the hope that this will perform better. */ - -PCRE2_SPTR start_subject = mb->start_subject; -PCRE2_SPTR end_subject = mb->end_subject; -PCRE2_SPTR start_code = mb->start_code; - -#ifdef SUPPORT_UNICODE -BOOL utf = (mb->poptions & PCRE2_UTF) != 0; -#else -BOOL utf = FALSE; -#endif - -BOOL reset_could_continue = FALSE; - -rlevel++; -offsetcount &= (-2); - -wscount -= 2; -wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / - (2 * INTS_PER_STATEBLOCK); - -ctypes = mb->tables + ctypes_offset; -lcc = mb->tables + lcc_offset; -fcc = mb->tables + fcc_offset; - -match_count = PCRE2_ERROR_NOMATCH; /* A negative number */ - -active_states = (stateblock *)(workspace + 2); -next_new_state = new_states = active_states + wscount; -new_count = 0; - -first_op = this_start_code + 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || - *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) - ? IMM2_SIZE:0); - -/* The first thing in any (sub) pattern is a bracket of some sort. Push all -the alternative states onto the list, and find out where the end is. This -makes is possible to use this function recursively, when we want to stop at a -matching internal ket rather than at the end. - -If the first opcode in the first alternative is OP_REVERSE, we are dealing with -a backward assertion. In that case, we have to find out the maximum amount to -move back, and set up each alternative appropriately. */ - -if (*first_op == OP_REVERSE) - { - size_t max_back = 0; - size_t gone_back; - - end_code = this_start_code; - do - { - size_t back = GET(end_code, 2+LINK_SIZE); - if (back > max_back) max_back = back; - end_code += GET(end_code, 1); - } - while (*end_code == OP_ALT); - - /* If we can't go back the amount required for the longest lookbehind - pattern, go back as far as we can; some alternatives may still be viable. */ - -#ifdef SUPPORT_UNICODE - /* In character mode we have to step back character by character */ - - if (utf) - { - for (gone_back = 0; gone_back < max_back; gone_back++) - { - if (current_subject <= start_subject) break; - current_subject--; - ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--); - } - } - else -#endif - - /* In byte-mode we can do this quickly. */ - - { - size_t current_offset = (size_t)(current_subject - start_subject); - gone_back = (current_offset < max_back)? current_offset : max_back; - current_subject -= gone_back; - } - - /* Save the earliest consulted character */ - - if (current_subject < mb->start_used_ptr) - mb->start_used_ptr = current_subject; - - /* Now we can process the individual branches. */ - - end_code = this_start_code; - do - { - size_t back = GET(end_code, 2+LINK_SIZE); - if (back <= gone_back) - { - int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE); - ADD_NEW_DATA(-bstate, 0, gone_back - back); - } - end_code += GET(end_code, 1); - } - while (*end_code == OP_ALT); - } - -/* This is the code for a "normal" subpattern (not a backward assertion). The -start of a whole pattern is always one of these. If we are at the top level, -we may be asked to restart matching from the same point that we reached for a -previous partial match. We still have to scan through the top-level branches to -find the end state. */ - -else - { - end_code = this_start_code; - - /* Restarting */ - - if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0) - { - do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); - new_count = workspace[1]; - if (!workspace[0]) - memcpy(new_states, active_states, new_count * sizeof(stateblock)); - } - - /* Not restarting */ - - else - { - int length = 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || - *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) - ? IMM2_SIZE:0); - do - { - ADD_NEW((int)(end_code - start_code + length), 0); - end_code += GET(end_code, 1); - length = 1 + LINK_SIZE; - } - while (*end_code == OP_ALT); - } - } - -workspace[0] = 0; /* Bit indicating which vector is current */ - -/* Loop for scanning the subject */ - -ptr = current_subject; -for (;;) - { - int i, j; - int clen, dlen; - uint32_t c, d; - int forced_fail = 0; - BOOL partial_newline = FALSE; - BOOL could_continue = reset_could_continue; - reset_could_continue = FALSE; - - if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr; - - /* Make the new state list into the active state list and empty the - new state list. */ - - temp_states = active_states; - active_states = new_states; - new_states = temp_states; - active_count = new_count; - new_count = 0; - - workspace[0] ^= 1; /* Remember for the restarting feature */ - workspace[1] = active_count; - - /* Set the pointers for adding new states */ - - next_active_state = active_states + active_count; - next_new_state = new_states; - - /* Load the current character from the subject outside the loop, as many - different states may want to look at it, and we assume that at least one - will. */ - - if (ptr < end_subject) - { - clen = 1; /* Number of data items in the character */ -#ifdef SUPPORT_UNICODE - GETCHARLENTEST(c, ptr, clen); -#else - c = *ptr; -#endif /* SUPPORT_UNICODE */ - } - else - { - clen = 0; /* This indicates the end of the subject */ - c = NOTACHAR; /* This value should never actually be used */ - } - - /* Scan up the active states and act on each one. The result of an action - may be to add more states to the currently active list (e.g. on hitting a - parenthesis) or it may be to put states on the new list, for considering - when we move the character pointer on. */ - - for (i = 0; i < active_count; i++) - { - stateblock *current_state = active_states + i; - BOOL caseless = FALSE; - PCRE2_SPTR code; - int state_offset = current_state->offset; - int codevalue, rrc; - int count; - - /* A negative offset is a special case meaning "hold off going to this - (negated) state until the number of characters in the data field have - been skipped". If the could_continue flag was passed over from a previous - state, arrange for it to passed on. */ - - if (state_offset < 0) - { - if (current_state->data > 0) - { - ADD_NEW_DATA(state_offset, current_state->count, - current_state->data - 1); - if (could_continue) reset_could_continue = TRUE; - continue; - } - else - { - current_state->offset = state_offset = -state_offset; - } - } - - /* Check for a duplicate state with the same count, and skip if found. - See the note at the head of this module about the possibility of improving - performance here. */ - - for (j = 0; j < i; j++) - { - if (active_states[j].offset == state_offset && - active_states[j].count == current_state->count) - goto NEXT_ACTIVE_STATE; - } - - /* The state offset is the offset to the opcode */ - - code = start_code + state_offset; - codevalue = *code; - - /* If this opcode inspects a character, but we are at the end of the - subject, remember the fact for use when testing for a partial match. */ - - if (clen == 0 && poptable[codevalue] != 0) - could_continue = TRUE; - - /* If this opcode is followed by an inline character, load it. It is - tempting to test for the presence of a subject character here, but that - is wrong, because sometimes zero repetitions of the subject are - permitted. - - We also use this mechanism for opcodes such as OP_TYPEPLUS that take an - argument that is not a data character - but is always one byte long because - the values are small. We have to take special action to deal with \P, \p, - \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert - these ones to new opcodes. */ - - if (coptable[codevalue] > 0) - { - dlen = 1; -#ifdef SUPPORT_UNICODE - if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else -#endif /* SUPPORT_UNICODE */ - d = code[coptable[codevalue]]; - if (codevalue >= OP_TYPESTAR) - { - switch(d) - { - case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM; - case OP_NOTPROP: - case OP_PROP: codevalue += OP_PROP_EXTRA; break; - case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break; - case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break; - case OP_NOT_HSPACE: - case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break; - case OP_NOT_VSPACE: - case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break; - default: break; - } - } - } - else - { - dlen = 0; /* Not strictly necessary, but compilers moan */ - d = NOTACHAR; /* if these variables are not set. */ - } - - - /* Now process the individual opcodes */ - - switch (codevalue) - { -/* ========================================================================== */ - /* These cases are never obeyed. This is a fudge that causes a compile- - time error if the vectors coptable or poptable, which are indexed by - opcode, are not the correct length. It seems to be the only way to do - such a check at compile time, as the sizeof() operator does not work - in the C preprocessor. */ - - case OP_TABLE_LENGTH: - case OP_TABLE_LENGTH + - ((sizeof(coptable) == OP_TABLE_LENGTH) && - (sizeof(poptable) == OP_TABLE_LENGTH)): - break; - -/* ========================================================================== */ - /* Reached a closing bracket. If not at the end of the pattern, carry - on with the next opcode. For repeating opcodes, also add the repeat - state. Note that KETRPOS will always be encountered at the end of the - subpattern, because the possessive subpattern repeats are always handled - using recursive calls. Thus, it never adds any new states. - - At the end of the (sub)pattern, unless we have an empty string and - PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the - start of the subject, save the match data, shifting up all previous - matches so we always have the longest first. */ - - case OP_KET: - case OP_KETRMIN: - case OP_KETRMAX: - case OP_KETRPOS: - if (code != end_code) - { - ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); - if (codevalue != OP_KET) - { - ADD_ACTIVE(state_offset - GET(code, 1), 0); - } - } - else - { - if (ptr > current_subject || - ((mb->moptions & PCRE2_NOTEMPTY) == 0 && - ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 || - current_subject > start_subject + mb->start_offset))) - { - if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; - else if (match_count > 0 && ++match_count * 2 > (int)offsetcount) - match_count = 0; - count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2; - if (count > 0) memmove(offsets + 2, offsets, count * sizeof(PCRE2_SIZE)); - if (offsetcount >= 2) - { - offsets[0] = (int)(current_subject - start_subject); - offsets[1] = (int)(ptr - start_subject); - } - if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count; - } - } - break; - -/* ========================================================================== */ - /* These opcodes add to the current list of states without looking - at the current character. */ - - /*-----------------------------------------------------------------*/ - case OP_ALT: - do { code += GET(code, 1); } while (*code == OP_ALT); - ADD_ACTIVE((int)(code - start_code), 0); - break; - - /*-----------------------------------------------------------------*/ - case OP_BRA: - case OP_SBRA: - do - { - ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); - code += GET(code, 1); - } - while (*code == OP_ALT); - break; - - /*-----------------------------------------------------------------*/ - case OP_CBRA: - case OP_SCBRA: - ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0); - code += GET(code, 1); - while (*code == OP_ALT) - { - ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); - code += GET(code, 1); - } - break; - - /*-----------------------------------------------------------------*/ - case OP_BRAZERO: - case OP_BRAMINZERO: - ADD_ACTIVE(state_offset + 1, 0); - code += 1 + GET(code, 2); - while (*code == OP_ALT) code += GET(code, 1); - ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); - break; - - /*-----------------------------------------------------------------*/ - case OP_SKIPZERO: - code += 1 + GET(code, 2); - while (*code == OP_ALT) code += GET(code, 1); - ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); - break; - - /*-----------------------------------------------------------------*/ - case OP_CIRC: - if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) - { ADD_ACTIVE(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_CIRCM: - if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) || - ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 ) - && WAS_NEWLINE(ptr))) - { ADD_ACTIVE(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_EOD: - if (ptr >= end_subject) - { - if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; - else { ADD_ACTIVE(state_offset + 1, 0); } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_SOD: - if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_SOM: - if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); } - break; - - -/* ========================================================================== */ - /* These opcodes inspect the next subject character, and sometimes - the previous one as well, but do not have an argument. The variable - clen contains the length of the current character and is zero if we are - at the end of the subject. */ - - /*-----------------------------------------------------------------*/ - case OP_ANY: - if (clen > 0 && !IS_NEWLINE(ptr)) - { - if (ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else - { - ADD_NEW(state_offset + 1, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_ALLANY: - if (clen > 0) - { ADD_NEW(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_EODN: - if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; - else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen)) - { ADD_ACTIVE(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_DOLL: - if ((mb->moptions & PCRE2_NOTEOL) == 0) - { - if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; - else if (clen == 0 || - ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) && - (ptr == end_subject - mb->nllen) - )) - { ADD_ACTIVE(state_offset + 1, 0); } - else if (ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) - { - reset_could_continue = TRUE; - ADD_NEW_DATA(-(state_offset + 1), 0, 1); - } - else could_continue = partial_newline = TRUE; - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_DOLLM: - if ((mb->moptions & PCRE2_NOTEOL) == 0) - { - if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; - else if (clen == 0 || - ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) - { ADD_ACTIVE(state_offset + 1, 0); } - else if (ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) - { - reset_could_continue = TRUE; - ADD_NEW_DATA(-(state_offset + 1), 0, 1); - } - else could_continue = partial_newline = TRUE; - } - } - else if (IS_NEWLINE(ptr)) - { ADD_ACTIVE(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - - case OP_DIGIT: - case OP_WHITESPACE: - case OP_WORDCHAR: - if (clen > 0 && c < 256 && - ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0) - { ADD_NEW(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_NOT_DIGIT: - case OP_NOT_WHITESPACE: - case OP_NOT_WORDCHAR: - if (clen > 0 && (c >= 256 || - ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)) - { ADD_NEW(state_offset + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_WORD_BOUNDARY: - case OP_NOT_WORD_BOUNDARY: - { - int left_word, right_word; - - if (ptr > start_subject) - { - PCRE2_SPTR temp = ptr - 1; - if (temp < mb->start_used_ptr) mb->start_used_ptr = temp; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (utf) { BACKCHAR(temp); } -#endif - GETCHARTEST(d, temp); -#ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) - { - if (d == '_') left_word = TRUE; else - { - int cat = UCD_CATEGORY(d); - left_word = (cat == ucp_L || cat == ucp_N); - } - } - else -#endif - left_word = d < 256 && (ctypes[d] & ctype_word) != 0; - } - else left_word = FALSE; - - if (clen > 0) - { - if (ptr >= mb->last_used_ptr) - { - PCRE2_SPTR temp = ptr + 1; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (utf) { FORWARDCHARTEST(temp, mb->end_subject); } -#endif - mb->last_used_ptr = temp; - } -#ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) - { - if (c == '_') right_word = TRUE; else - { - int cat = UCD_CATEGORY(c); - right_word = (cat == ucp_L || cat == ucp_N); - } - } - else -#endif - right_word = c < 256 && (ctypes[c] & ctype_word) != 0; - } - else right_word = FALSE; - - if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) - { ADD_ACTIVE(state_offset + 1, 0); } - } - break; - - - /*-----------------------------------------------------------------*/ - /* Check the next character by Unicode property. We will get here only - if the support is in the binary; otherwise a compile-time error occurs. - */ - -#ifdef SUPPORT_UNICODE - case OP_PROP: - case OP_NOTPROP: - if (clen > 0) - { - BOOL OK; - const uint32_t *cp; - const ucd_record * prop = GET_UCD(c); - switch(code[1]) - { - case PT_ANY: - OK = TRUE; - break; - - case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; - break; - - case PT_GC: - OK = PRIV(ucp_gentype)[prop->chartype] == code[2]; - break; - - case PT_PC: - OK = prop->chartype == code[2]; - break; - - case PT_SC: - OK = prop->script == code[2]; - break; - - /* These are specials for combination cases. */ - - case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; - break; - } - break; - - case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; - break; - - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[2]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - - case PT_UCNC: - OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000; - break; - - /* Should never occur, but keep compilers from grumbling. */ - - default: - OK = codevalue != OP_PROP; - break; - } - - if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); } - } - break; -#endif - - - -/* ========================================================================== */ - /* These opcodes likewise inspect the subject character, but have an - argument that is not a data character. It is one of these opcodes: - OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE, - OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */ - - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) - { - if (d == OP_ANY && ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || - (c < 256 && - (d != OP_ANY || !IS_NEWLINE(ptr)) && - ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) - { - if (count > 0 && codevalue == OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW(state_offset, count); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSQUERY: - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - if (d == OP_ANY && ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || - (c < 256 && - (d != OP_ANY || !IS_NEWLINE(ptr)) && - ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) - { - if (codevalue == OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset + 2, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPOSSTAR: - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - if (d == OP_ANY && ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || - (c < 256 && - (d != OP_ANY || !IS_NEWLINE(ptr)) && - ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) - { - if (codevalue == OP_TYPEPOSSTAR) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_TYPEEXACT: - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - if (d == OP_ANY && ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || - (c < 256 && - (d != OP_ANY || !IS_NEWLINE(ptr)) && - ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) - { - if (++count >= (int)GET2(code, 1)) - { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); } - else - { ADD_NEW(state_offset, count); } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - if (d == OP_ANY && ptr + 1 >= mb->end_subject && - (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - could_continue = partial_newline = TRUE; - } - else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || - (c < 256 && - (d != OP_ANY || !IS_NEWLINE(ptr)) && - ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) - { - if (codevalue == OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } - else - { ADD_NEW(state_offset, count); } - } - } - break; - -/* ========================================================================== */ - /* These are virtual opcodes that are used when something like - OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its - argument. It keeps the code above fast for the other cases. The argument - is in the d variable. */ - -#ifdef SUPPORT_UNICODE - case OP_PROP_EXTRA + OP_TYPEPLUS: - case OP_PROP_EXTRA + OP_TYPEMINPLUS: - case OP_PROP_EXTRA + OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); } - if (clen > 0) - { - BOOL OK; - const uint32_t *cp; - const ucd_record * prop = GET_UCD(c); - switch(code[2]) - { - case PT_ANY: - OK = TRUE; - break; - - case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; - break; - - case PT_GC: - OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; - break; - - case PT_PC: - OK = prop->chartype == code[3]; - break; - - case PT_SC: - OK = prop->script == code[3]; - break; - - /* These are specials for combination cases. */ - - case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; - break; - } - break; - - case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; - break; - - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[3]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - - case PT_UCNC: - OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000; - break; - - /* Should never occur, but keep compilers from grumbling. */ - - default: - OK = codevalue != OP_PROP; - break; - } - - if (OK == (d == OP_PROP)) - { - if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW(state_offset, count); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_EXTUNI_EXTRA + OP_TYPEPLUS: - case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS: - case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) - { - int lgb, rgb; - PCRE2_SPTR nptr = ptr + clen; - int ncount = 0; - if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - lgb = UCD_GRAPHBREAK(c); - while (nptr < end_subject) - { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - ncount++; - lgb = rgb; - nptr += dlen; - } - count++; - ADD_NEW_DATA(-state_offset, count, ncount); - } - break; -#endif - - /*-----------------------------------------------------------------*/ - case OP_ANYNL_EXTRA + OP_TYPEPLUS: - case OP_ANYNL_EXTRA + OP_TYPEMINPLUS: - case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) - { - int ncount = 0; - switch (c) - { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - goto ANYNL01; - - case CHAR_CR: - if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; - /* Fall through */ - - ANYNL01: - case CHAR_LF: - if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW_DATA(-state_offset, count, ncount); - break; - - default: - break; - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_VSPACE_EXTRA + OP_TYPEPLUS: - case OP_VSPACE_EXTRA + OP_TYPEMINPLUS: - case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) - { - BOOL OK; - switch (c) - { - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - break; - } - - if (OK == (d == OP_VSPACE)) - { - if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW_DATA(-state_offset, count, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_HSPACE_EXTRA + OP_TYPEPLUS: - case OP_HSPACE_EXTRA + OP_TYPEMINPLUS: - case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) - { - BOOL OK; - switch (c) - { - HSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - break; - } - - if (OK == (d == OP_HSPACE)) - { - if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW_DATA(-state_offset, count, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ -#ifdef SUPPORT_UNICODE - case OP_PROP_EXTRA + OP_TYPEQUERY: - case OP_PROP_EXTRA + OP_TYPEMINQUERY: - case OP_PROP_EXTRA + OP_TYPEPOSQUERY: - count = 4; - goto QS1; - - case OP_PROP_EXTRA + OP_TYPESTAR: - case OP_PROP_EXTRA + OP_TYPEMINSTAR: - case OP_PROP_EXTRA + OP_TYPEPOSSTAR: - count = 0; - - QS1: - - ADD_ACTIVE(state_offset + 4, 0); - if (clen > 0) - { - BOOL OK; - const uint32_t *cp; - const ucd_record * prop = GET_UCD(c); - switch(code[2]) - { - case PT_ANY: - OK = TRUE; - break; - - case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; - break; - - case PT_GC: - OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; - break; - - case PT_PC: - OK = prop->chartype == code[3]; - break; - - case PT_SC: - OK = prop->script == code[3]; - break; - - /* These are specials for combination cases. */ - - case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; - break; - } - break; - - case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; - break; - - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[3]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - - case PT_UCNC: - OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000; - break; - - /* Should never occur, but keep compilers from grumbling. */ - - default: - OK = codevalue != OP_PROP; - break; - } - - if (OK == (d == OP_PROP)) - { - if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR || - codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset + count, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_EXTUNI_EXTRA + OP_TYPEQUERY: - case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY: - case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY: - count = 2; - goto QS2; - - case OP_EXTUNI_EXTRA + OP_TYPESTAR: - case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR: - case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR: - count = 0; - - QS2: - - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - int lgb, rgb; - PCRE2_SPTR nptr = ptr + clen; - int ncount = 0; - if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || - codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - lgb = UCD_GRAPHBREAK(c); - while (nptr < end_subject) - { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - ncount++; - lgb = rgb; - nptr += dlen; - } - ADD_NEW_DATA(-(state_offset + count), 0, ncount); - } - break; -#endif - - /*-----------------------------------------------------------------*/ - case OP_ANYNL_EXTRA + OP_TYPEQUERY: - case OP_ANYNL_EXTRA + OP_TYPEMINQUERY: - case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY: - count = 2; - goto QS3; - - case OP_ANYNL_EXTRA + OP_TYPESTAR: - case OP_ANYNL_EXTRA + OP_TYPEMINSTAR: - case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR: - count = 0; - - QS3: - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - int ncount = 0; - switch (c) - { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - goto ANYNL02; - - case CHAR_CR: - if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; - /* Fall through */ - - ANYNL02: - case CHAR_LF: - if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || - codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount); - break; - - default: - break; - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_VSPACE_EXTRA + OP_TYPEQUERY: - case OP_VSPACE_EXTRA + OP_TYPEMINQUERY: - case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY: - count = 2; - goto QS4; - - case OP_VSPACE_EXTRA + OP_TYPESTAR: - case OP_VSPACE_EXTRA + OP_TYPEMINSTAR: - case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR: - count = 0; - - QS4: - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - BOOL OK; - switch (c) - { - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - break; - } - if (OK == (d == OP_VSPACE)) - { - if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR || - codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_HSPACE_EXTRA + OP_TYPEQUERY: - case OP_HSPACE_EXTRA + OP_TYPEMINQUERY: - case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY: - count = 2; - goto QS5; - - case OP_HSPACE_EXTRA + OP_TYPESTAR: - case OP_HSPACE_EXTRA + OP_TYPEMINSTAR: - case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR: - count = 0; - - QS5: - ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) - { - BOOL OK; - switch (c) - { - HSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - break; - } - - if (OK == (d == OP_HSPACE)) - { - if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR || - codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ -#ifdef SUPPORT_UNICODE - case OP_PROP_EXTRA + OP_TYPEEXACT: - case OP_PROP_EXTRA + OP_TYPEUPTO: - case OP_PROP_EXTRA + OP_TYPEMINUPTO: - case OP_PROP_EXTRA + OP_TYPEPOSUPTO: - if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); } - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - BOOL OK; - const uint32_t *cp; - const ucd_record * prop = GET_UCD(c); - switch(code[1 + IMM2_SIZE + 1]) - { - case PT_ANY: - OK = TRUE; - break; - - case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; - break; - - case PT_GC: - OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2]; - break; - - case PT_PC: - OK = prop->chartype == code[1 + IMM2_SIZE + 2]; - break; - - case PT_SC: - OK = prop->script == code[1 + IMM2_SIZE + 2]; - break; - - /* These are specials for combination cases. */ - - case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; - break; - } - break; - - case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; - break; - - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - - case PT_UCNC: - OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000; - break; - - /* Should never occur, but keep compilers from grumbling. */ - - default: - OK = codevalue != OP_PROP; - break; - } - - if (OK == (d == OP_PROP)) - { - if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } - else - { ADD_NEW(state_offset, count); } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_EXTUNI_EXTRA + OP_TYPEEXACT: - case OP_EXTUNI_EXTRA + OP_TYPEUPTO: - case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: - case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: - if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - int lgb, rgb; - PCRE2_SPTR nptr = ptr + clen; - int ncount = 0; - if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - lgb = UCD_GRAPHBREAK(c); - while (nptr < end_subject) - { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - ncount++; - lgb = rgb; - nptr += dlen; - } - if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - reset_could_continue = TRUE; - if (++count >= (int)GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } - else - { ADD_NEW_DATA(-state_offset, count, ncount); } - } - break; -#endif - - /*-----------------------------------------------------------------*/ - case OP_ANYNL_EXTRA + OP_TYPEEXACT: - case OP_ANYNL_EXTRA + OP_TYPEUPTO: - case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: - case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: - if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - int ncount = 0; - switch (c) - { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - goto ANYNL03; - - case CHAR_CR: - if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; - /* Fall through */ - - ANYNL03: - case CHAR_LF: - if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } - else - { ADD_NEW_DATA(-state_offset, count, ncount); } - break; - - default: - break; - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_VSPACE_EXTRA + OP_TYPEEXACT: - case OP_VSPACE_EXTRA + OP_TYPEUPTO: - case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: - case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: - if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - BOOL OK; - switch (c) - { - VSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - } - - if (OK == (d == OP_VSPACE)) - { - if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } - else - { ADD_NEW_DATA(-state_offset, count, 0); } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_HSPACE_EXTRA + OP_TYPEEXACT: - case OP_HSPACE_EXTRA + OP_TYPEUPTO: - case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: - case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: - if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - BOOL OK; - switch (c) - { - HSPACE_CASES: - OK = TRUE; - break; - - default: - OK = FALSE; - break; - } - - if (OK == (d == OP_HSPACE)) - { - if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } - else - { ADD_NEW_DATA(-state_offset, count, 0); } - } - } - break; - -/* ========================================================================== */ - /* These opcodes are followed by a character that is usually compared - to the current subject character; it is loaded into d. We still get - here even if there is no subject character, because in some cases zero - repetitions are permitted. */ - - /*-----------------------------------------------------------------*/ - case OP_CHAR: - if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - case OP_CHARI: - if (clen == 0) break; - -#ifdef SUPPORT_UNICODE - if (utf) - { - if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else - { - unsigned int othercase; - if (c < 128) - othercase = fcc[c]; - else - othercase = UCD_OTHERCASE(c); - if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } - } - } - else -#endif /* SUPPORT_UNICODE */ - /* Not UTF mode */ - { - if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) - { ADD_NEW(state_offset + 2, 0); } - } - break; - - -#ifdef SUPPORT_UNICODE - /*-----------------------------------------------------------------*/ - /* This is a tricky one because it can match more than one character. - Find out how many characters to skip, and then set up a negative state - to wait for them to pass before continuing. */ - - case OP_EXTUNI: - if (clen > 0) - { - int lgb, rgb; - PCRE2_SPTR nptr = ptr + clen; - int ncount = 0; - lgb = UCD_GRAPHBREAK(c); - while (nptr < end_subject) - { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - ncount++; - lgb = rgb; - nptr += dlen; - } - if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - reset_could_continue = TRUE; - ADD_NEW_DATA(-(state_offset + 1), 0, ncount); - } - break; -#endif - - /*-----------------------------------------------------------------*/ - /* This is a tricky like EXTUNI because it too can match more than one - character (when CR is followed by LF). In this case, set up a negative - state to wait for one character to pass before continuing. */ - - case OP_ANYNL: - if (clen > 0) switch(c) - { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - - case CHAR_LF: - ADD_NEW(state_offset + 1, 0); - break; - - case CHAR_CR: - if (ptr + 1 >= end_subject) - { - ADD_NEW(state_offset + 1, 0); - if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) - reset_could_continue = TRUE; - } - else if (UCHAR21TEST(ptr + 1) == CHAR_LF) - { - ADD_NEW_DATA(-(state_offset + 1), 0, 1); - } - else - { - ADD_NEW(state_offset + 1, 0); - } - break; - } - break; - - /*-----------------------------------------------------------------*/ - case OP_NOT_VSPACE: - if (clen > 0) switch(c) - { - VSPACE_CASES: - break; - - default: - ADD_NEW(state_offset + 1, 0); - break; - } - break; - - /*-----------------------------------------------------------------*/ - case OP_VSPACE: - if (clen > 0) switch(c) - { - VSPACE_CASES: - ADD_NEW(state_offset + 1, 0); - break; - - default: - break; - } - break; - - /*-----------------------------------------------------------------*/ - case OP_NOT_HSPACE: - if (clen > 0) switch(c) - { - HSPACE_CASES: - break; - - default: - ADD_NEW(state_offset + 1, 0); - break; - } - break; - - /*-----------------------------------------------------------------*/ - case OP_HSPACE: - if (clen > 0) switch(c) - { - HSPACE_CASES: - ADD_NEW(state_offset + 1, 0); - break; - - default: - break; - } - break; - - /*-----------------------------------------------------------------*/ - /* Match a negated single character casefully. */ - - case OP_NOT: - if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); } - break; - - /*-----------------------------------------------------------------*/ - /* Match a negated single character caselessly. */ - - case OP_NOTI: - if (clen > 0) - { - unsigned int otherd; -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - if (c != d && c != otherd) - { ADD_NEW(state_offset + dlen + 1, 0); } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTPOSPLUSI: - caseless = TRUE; - codevalue -= OP_STARI - OP_STAR; - - /* Fall through */ - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } - if (clen > 0) - { - uint32_t otherd = NOTACHAR; - if (caseless) - { -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - } - if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) - { - if (count > 0 && - (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS)) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW(state_offset, count); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_QUERYI: - case OP_MINQUERYI: - case OP_POSQUERYI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTPOSQUERYI: - caseless = TRUE; - codevalue -= OP_STARI - OP_STAR; - /* Fall through */ - case OP_QUERY: - case OP_MINQUERY: - case OP_POSQUERY: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTPOSQUERY: - ADD_ACTIVE(state_offset + dlen + 1, 0); - if (clen > 0) - { - uint32_t otherd = NOTACHAR; - if (caseless) - { -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - } - if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) - { - if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset + dlen + 1, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_STARI: - case OP_MINSTARI: - case OP_POSSTARI: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPOSSTARI: - caseless = TRUE; - codevalue -= OP_STARI - OP_STAR; - /* Fall through */ - case OP_STAR: - case OP_MINSTAR: - case OP_POSSTAR: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPOSSTAR: - ADD_ACTIVE(state_offset + dlen + 1, 0); - if (clen > 0) - { - uint32_t otherd = NOTACHAR; - if (caseless) - { -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - } - if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) - { - if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset, 0); - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_EXACTI: - case OP_NOTEXACTI: - caseless = TRUE; - codevalue -= OP_STARI - OP_STAR; - /* Fall through */ - case OP_EXACT: - case OP_NOTEXACT: - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - uint32_t otherd = NOTACHAR; - if (caseless) - { -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - } - if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) - { - if (++count >= (int)GET2(code, 1)) - { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } - else - { ADD_NEW(state_offset, count); } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_UPTOI: - case OP_MINUPTOI: - case OP_POSUPTOI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTPOSUPTOI: - caseless = TRUE; - codevalue -= OP_STARI - OP_STAR; - /* Fall through */ - case OP_UPTO: - case OP_MINUPTO: - case OP_POSUPTO: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTPOSUPTO: - ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0); - count = current_state->count; /* Number already matched */ - if (clen > 0) - { - uint32_t otherd = NOTACHAR; - if (caseless) - { -#ifdef SUPPORT_UNICODE - if (utf && d >= 128) - otherd = UCD_OTHERCASE(d); - else -#endif /* SUPPORT_UNICODE */ - otherd = TABLE_GET(d, fcc, d); - } - if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) - { - if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= (int)GET2(code, 1)) - { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } - else - { ADD_NEW(state_offset, count); } - } - } - break; - - -/* ========================================================================== */ - /* These are the class-handling opcodes */ - - case OP_CLASS: - case OP_NCLASS: - case OP_XCLASS: - { - BOOL isinclass = FALSE; - int next_state_offset; - PCRE2_SPTR ecode; - - /* For a simple class, there is always just a 32-byte table, and we - can set isinclass from it. */ - - if (codevalue != OP_XCLASS) - { - ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); - if (clen > 0) - { - isinclass = (c > 255)? (codevalue == OP_NCLASS) : - ((((uint8_t *)(code + 1))[c/8] & (1 << (c&7))) != 0); - } - } - - /* An extended class may have a table or a list of single characters, - ranges, or both, and it may be positive or negative. There's a - function that sorts all this out. */ - - else - { - ecode = code + GET(code, 1); - if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); - } - - /* At this point, isinclass is set for all kinds of class, and ecode - points to the byte after the end of the class. If there is a - quantifier, this is where it will be. */ - - next_state_offset = (int)(ecode - start_code); - - switch (*ecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPOSSTAR: - ADD_ACTIVE(next_state_offset + 1, 0); - if (isinclass) - { - if (*ecode == OP_CRPOSSTAR) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(state_offset, 0); - } - break; - - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - count = current_state->count; /* Already matched */ - if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } - if (isinclass) - { - if (count > 0 && *ecode == OP_CRPOSPLUS) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - count++; - ADD_NEW(state_offset, count); - } - break; - - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSQUERY: - ADD_ACTIVE(next_state_offset + 1, 0); - if (isinclass) - { - if (*ecode == OP_CRPOSQUERY) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - ADD_NEW(next_state_offset + 1, 0); - } - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - count = current_state->count; /* Already matched */ - if (count >= (int)GET2(ecode, 1)) - { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } - if (isinclass) - { - int max = (int)GET2(ecode, 1 + IMM2_SIZE); - if (*ecode == OP_CRPOSRANGE) - { - active_count--; /* Remove non-match possibility */ - next_active_state--; - } - if (++count >= max && max != 0) /* Max 0 => no limit */ - { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } - else - { ADD_NEW(state_offset, count); } - } - break; - - default: - if (isinclass) { ADD_NEW(next_state_offset, 0); } - break; - } - } - break; - -/* ========================================================================== */ - /* These are the opcodes for fancy brackets of various kinds. We have - to use recursion in order to handle them. The "always failing" assertion - (?!) is optimised to OP_FAIL when compiling, so we have to support that, - though the other "backtracking verbs" are not supported. */ - - case OP_FAIL: - forced_fail++; /* Count FAILs for multiple states */ - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - { - PCRE2_SPTR endasscode = code + GET(code, 1); - PCRE2_SIZE local_offsets[2]; - int rc; - int local_workspace[1000]; - - while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); - - rc = internal_dfa_match( - mb, /* static match data */ - code, /* this subexpression's code */ - ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ - local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ - local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ - - if (rc == PCRE2_ERROR_DFA_UITEM) return rc; - if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) - { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_COND: - case OP_SCOND: - { - PCRE2_SIZE local_offsets[1000]; - int local_workspace[1000]; - int codelink = GET(code, 1); - int condcode; - - /* Because of the way auto-callout works during compile, a callout item - is inserted between OP_COND and an assertion condition. This does not - happen for the other conditions. */ - - if (code[LINK_SIZE + 1] == OP_CALLOUT - || code[LINK_SIZE + 1] == OP_CALLOUT_STR) - { - unsigned int callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 2 + 3*LINK_SIZE); - rrc = 0; - if (mb->callout != NULL) - { - pcre2_callout_block cb; - cb.version = 1; - cb.capture_top = 1; - cb.capture_last = 0; - cb.offset_vector = offsets; - cb.mark = NULL; /* No (*MARK) support */ - cb.subject = start_subject; - cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject); - cb.start_match = (PCRE2_SIZE)(current_subject - start_subject); - cb.current_position = (PCRE2_SIZE)(ptr - start_subject); - cb.pattern_position = GET(code, LINK_SIZE + 2); - cb.next_item_length = GET(code, LINK_SIZE + 2 + LINK_SIZE); - - if (code[LINK_SIZE + 1] == OP_CALLOUT) - { - cb.callout_number = code[2 + 3*LINK_SIZE]; - cb.callout_string_offset = 0; - cb.callout_string = NULL; - cb.callout_string_length = 0; - } - else - { - cb.callout_number = 0; - cb.callout_string_offset = GET(code, 2 + 4*LINK_SIZE); - cb.callout_string = code + (2 + 5*LINK_SIZE) + 1; - cb.callout_string_length = - callout_length - (1 + 4*LINK_SIZE) - 2; - } - - if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0) - return rrc; /* Abandon */ - } - if (rrc > 0) break; /* Fail this thread */ - code += callout_length; /* Skip callout data */ - } - - condcode = code[LINK_SIZE+1]; - - /* Back reference conditions and duplicate named recursion conditions - are not supported */ - - if (condcode == OP_CREF || condcode == OP_DNCREF || - condcode == OP_DNRREF) - return PCRE2_ERROR_DFA_UCOND; - - /* The DEFINE condition is always false, and the assertion (?!) is - converted to OP_FAIL. */ - - if (condcode == OP_FALSE || condcode == OP_FAIL) - { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } - - /* There is also an always-true condition */ - - else if (condcode == OP_TRUE) - { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } - - /* The only supported version of OP_RREF is for the value RREF_ANY, - which means "test if in any recursion". We can't test for specifically - recursed groups. */ - - else if (condcode == OP_RREF) - { - int value = GET2(code, LINK_SIZE + 2); - if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND; - if (mb->recursive != NULL) - { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } - else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } - } - - /* Otherwise, the condition is an assertion */ - - else - { - int rc; - PCRE2_SPTR asscode = code + LINK_SIZE + 1; - PCRE2_SPTR endasscode = asscode + GET(asscode, 1); - - while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); - - rc = internal_dfa_match( - mb, /* fixed match data */ - asscode, /* this subexpression's code */ - ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ - local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ - local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ - - if (rc == PCRE2_ERROR_DFA_UITEM) return rc; - if ((rc >= 0) == - (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) - { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } - else - { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_RECURSE: - { - dfa_recursion_info *ri; - PCRE2_SIZE local_offsets[1000]; - int local_workspace[1000]; - PCRE2_SPTR callpat = start_code + GET(code, 1); - uint32_t recno = (callpat == mb->start_code)? 0 : - GET2(callpat, 1 + LINK_SIZE); - int rc; - - /* Check for repeating a recursion without advancing the subject - pointer. This should catch convoluted mutual recursions. (Some simple - cases are caught at compile time.) */ - - for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) - if (recno == ri->group_num && ptr == ri->subject_position) - return PCRE2_ERROR_RECURSELOOP; - - /* Remember this recursion and where we started it so as to - catch infinite loops. */ - - new_recursive.group_num = recno; - new_recursive.subject_position = ptr; - new_recursive.prevrec = mb->recursive; - mb->recursive = &new_recursive; - - rc = internal_dfa_match( - mb, /* fixed match data */ - callpat, /* this subexpression's code */ - ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ - local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ - local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ - - mb->recursive = new_recursive.prevrec; /* Done this recursion */ - - /* Ran out of internal offsets */ - - if (rc == 0) return PCRE2_ERROR_DFA_RECURSE; - - /* For each successful matched substring, set up the next state with a - count of characters to skip before trying it. Note that the count is in - characters, not bytes. */ - - if (rc > 0) - { - for (rc = rc*2 - 2; rc >= 0; rc -= 2) - { - int charcount = local_offsets[rc+1] - local_offsets[rc]; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (utf) - { - PCRE2_SPTR p = start_subject + local_offsets[rc]; - PCRE2_SPTR pp = start_subject + local_offsets[rc+1]; - while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; - } -#endif - if (charcount > 0) - { - ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); - } - else - { - ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0); - } - } - } - else if (rc != PCRE2_ERROR_NOMATCH) return rc; - } - break; - - /*-----------------------------------------------------------------*/ - case OP_BRAPOS: - case OP_SBRAPOS: - case OP_CBRAPOS: - case OP_SCBRAPOS: - case OP_BRAPOSZERO: - { - int charcount, matched_count; - PCRE2_SPTR local_ptr = ptr; - BOOL allow_zero; - - if (codevalue == OP_BRAPOSZERO) - { - allow_zero = TRUE; - codevalue = *(++code); /* Codevalue will be one of above BRAs */ - } - else allow_zero = FALSE; - - /* Loop to match the subpattern as many times as possible as if it were - a complete pattern. */ - - for (matched_count = 0;; matched_count++) - { - PCRE2_SIZE local_offsets[2]; - int local_workspace[1000]; - - int rc = internal_dfa_match( - mb, /* fixed match data */ - code, /* this subexpression's code */ - local_ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ - local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ - local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ - - /* Failed to match */ - - if (rc < 0) - { - if (rc != PCRE2_ERROR_NOMATCH) return rc; - break; - } - - /* Matched: break the loop if zero characters matched. */ - - charcount = local_offsets[1] - local_offsets[0]; - if (charcount == 0) break; - local_ptr += charcount; /* Advance temporary position ptr */ - } - - /* At this point we have matched the subpattern matched_count - times, and local_ptr is pointing to the character after the end of the - last match. */ - - if (matched_count > 0 || allow_zero) - { - PCRE2_SPTR end_subpattern = code; - int next_state_offset; - - do { end_subpattern += GET(end_subpattern, 1); } - while (*end_subpattern == OP_ALT); - next_state_offset = - (int)(end_subpattern - start_code + LINK_SIZE + 1); - - /* Optimization: if there are no more active states, and there - are no new states yet set up, then skip over the subject string - right here, to save looping. Otherwise, set up the new state to swing - into action when the end of the matched substring is reached. */ - - if (i + 1 >= active_count && new_count == 0) - { - ptr = local_ptr; - clen = 0; - ADD_NEW(next_state_offset, 0); - } - else - { - PCRE2_SPTR p = ptr; - PCRE2_SPTR pp = local_ptr; - charcount = (int)(pp - p); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; -#endif - ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); - } - } - } - break; - - /*-----------------------------------------------------------------*/ - case OP_ONCE: - case OP_ONCE_NC: - { - PCRE2_SIZE local_offsets[2]; - int local_workspace[1000]; - - int rc = internal_dfa_match( - mb, /* fixed match data */ - code, /* this subexpression's code */ - ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ - local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ - local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ - - if (rc >= 0) - { - PCRE2_SPTR end_subpattern = code; - int charcount = local_offsets[1] - local_offsets[0]; - int next_state_offset, repeat_state_offset; - - do { end_subpattern += GET(end_subpattern, 1); } - while (*end_subpattern == OP_ALT); - next_state_offset = - (int)(end_subpattern - start_code + LINK_SIZE + 1); - - /* If the end of this subpattern is KETRMAX or KETRMIN, we must - arrange for the repeat state also to be added to the relevant list. - Calculate the offset, or set -1 for no repeat. */ - - repeat_state_offset = (*end_subpattern == OP_KETRMAX || - *end_subpattern == OP_KETRMIN)? - (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1; - - /* If we have matched an empty string, add the next state at the - current character pointer. This is important so that the duplicate - checking kicks in, which is what breaks infinite loops that match an - empty string. */ - - if (charcount == 0) - { - ADD_ACTIVE(next_state_offset, 0); - } - - /* Optimization: if there are no more active states, and there - are no new states yet set up, then skip over the subject string - right here, to save looping. Otherwise, set up the new state to swing - into action when the end of the matched substring is reached. */ - - else if (i + 1 >= active_count && new_count == 0) - { - ptr += charcount; - clen = 0; - ADD_NEW(next_state_offset, 0); - - /* If we are adding a repeat state at the new character position, - we must fudge things so that it is the only current state. - Otherwise, it might be a duplicate of one we processed before, and - that would cause it to be skipped. */ - - if (repeat_state_offset >= 0) - { - next_active_state = active_states; - active_count = 0; - i = -1; - ADD_ACTIVE(repeat_state_offset, 0); - } - } - else - { -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (utf) - { - PCRE2_SPTR p = start_subject + local_offsets[0]; - PCRE2_SPTR pp = start_subject + local_offsets[1]; - while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; - } -#endif - ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); - if (repeat_state_offset >= 0) - { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } - } - } - else if (rc != PCRE2_ERROR_NOMATCH) return rc; - } - break; - - -/* ========================================================================== */ - /* Handle callouts */ - - case OP_CALLOUT: - case OP_CALLOUT_STR: - { - unsigned int callout_length = (*code == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 1 + 2*LINK_SIZE); - rrc = 0; - - if (mb->callout != NULL) - { - pcre2_callout_block cb; - cb.version = 1; - cb.capture_top = 1; - cb.capture_last = 0; - cb.offset_vector = offsets; - cb.mark = NULL; /* No (*MARK) support */ - cb.subject = start_subject; - cb.subject_length = (PCRE2_SIZE)(end_subject - start_subject); - cb.start_match = (PCRE2_SIZE)(current_subject - start_subject); - cb.current_position = (PCRE2_SIZE)(ptr - start_subject); - cb.pattern_position = GET(code, 1); - cb.next_item_length = GET(code, 1 + LINK_SIZE); - - if (*code == OP_CALLOUT) - { - cb.callout_number = code[1 + 2*LINK_SIZE]; - cb.callout_string_offset = 0; - cb.callout_string = NULL; - cb.callout_string_length = 0; - } - else - { - cb.callout_number = 0; - cb.callout_string_offset = GET(code, 1 + 3*LINK_SIZE); - cb.callout_string = code + (1 + 4*LINK_SIZE) + 1; - cb.callout_string_length = - callout_length - (1 + 4*LINK_SIZE) - 2; - } - - if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0) - return rrc; /* Abandon */ - } - if (rrc == 0) - { ADD_ACTIVE(state_offset + callout_length, 0); } - } - break; - - -/* ========================================================================== */ - default: /* Unsupported opcode */ - return PCRE2_ERROR_DFA_UITEM; - } - - NEXT_ACTIVE_STATE: continue; - - } /* End of loop scanning active states */ - - /* We have finished the processing at the current subject character. If no - new states have been set for the next character, we have found all the - matches that we are going to find. If we are at the top level and partial - matching has been requested, check for appropriate conditions. - - The "forced_ fail" variable counts the number of (*F) encountered for the - character. If it is equal to the original active_count (saved in - workspace[1]) it means that (*F) was found on every active state. In this - case we don't want to give a partial match. - - The "could_continue" variable is true if a state could have continued but - for the fact that the end of the subject was reached. */ - - if (new_count <= 0) - { - if (rlevel == 1 && /* Top level, and */ - could_continue && /* Some could go on, and */ - forced_fail != workspace[1] && /* Not all forced fail & */ - ( /* either... */ - (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */ - || /* or... */ - ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */ - match_count < 0) /* no matches */ - ) && /* And... */ - ( - partial_newline || /* Either partial NL */ - ( /* or ... */ - ptr >= end_subject && /* End of subject and */ - ptr > mb->start_used_ptr) /* Inspected non-empty string */ - ) - ) - match_count = PCRE2_ERROR_PARTIAL; - break; /* In effect, "return", but see the comment below */ - } - - /* One or more states are active for the next character. */ - - ptr += clen; /* Advance to next subject character */ - } /* Loop to move along the subject string */ - -/* Control gets here from "break" a few lines above. We do it this way because -if we use "return" above, we have compiler trouble. Some compilers warn if -there's nothing here because they think the function doesn't return a value. On -the other hand, if we put a dummy statement here, some more clever compilers -complain that it can't be reached. Sigh. */ - -return match_count; -} - - - -/************************************************* -* Match a pattern using the DFA algorithm * -*************************************************/ - -/* This function matches a compiled pattern to a subject string, using the -alternate matching algorithm that finds all matches at once. - -Arguments: - code points to the compiled pattern - subject subject string - length length of subject string - startoffset where to start matching in the subject - options option bits - match_data points to a match data structure - gcontext points to a match context - workspace pointer to workspace - wscount size of workspace - -Returns: > 0 => number of match offset pairs placed in offsets - = 0 => offsets overflowed; longest matches are present - -1 => failed to match - < -1 => some kind of unexpected problem -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, - PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, - pcre2_match_context *mcontext, int *workspace, size_t wscount) -{ -const pcre2_real_code *re = (const pcre2_real_code *)code; - -PCRE2_SPTR start_match; -PCRE2_SPTR end_subject; -PCRE2_SPTR bumpalong_limit; -PCRE2_SPTR req_cu_ptr; - -BOOL utf, anchored, startline, firstline; - -BOOL has_first_cu = FALSE; -BOOL has_req_cu = FALSE; -PCRE2_UCHAR first_cu = 0; -PCRE2_UCHAR first_cu2 = 0; -PCRE2_UCHAR req_cu = 0; -PCRE2_UCHAR req_cu2 = 0; - -const uint8_t *start_bits = NULL; - -/* We need to have mb pointing to a match block, because the IS_NEWLINE macro -is used below, and it expects NLBLOCK to be defined as a pointer. */ - -dfa_match_block actual_match_block; -dfa_match_block *mb = &actual_match_block; - -/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated -subject string. */ - -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); - -/* Plausibility checks */ - -if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; -if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL) - return PCRE2_ERROR_NULL; -if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE; -if (start_offset > length) return PCRE2_ERROR_BADOFFSET; - -/* Check that the first field in the block is the magic number. If it is not, -return with PCRE2_ERROR_BADMAGIC. */ - -if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; - -/* Check the code unit width. */ - -if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) - return PCRE2_ERROR_BADMODE; - -/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the -options variable for this function. Users of PCRE2 who are not calling the -function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with -constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and -(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be -transferred to the options for this function. The bits are guaranteed to be -adjacent, but do not have the same values. This bit of Boolean trickery assumes -that the match-time bits are not more significant than the flag bits. If by -accident this is not the case, a compile-time division by zero error will -occur. */ - -#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET) -#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART) -options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1))); -#undef FF -#undef OO - -/* If restarting after a partial match, do some sanity checks on the contents -of the workspace. */ - -if ((options & PCRE2_DFA_RESTART) != 0) - { - if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 || - workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK)) - return PCRE2_ERROR_DFA_BADRESTART; - } - -/* Set some local values */ - -utf = (re->overall_options & PCRE2_UTF) != 0; -start_match = subject + start_offset; -end_subject = subject + length; -req_cu_ptr = start_match - 1; -anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 || - (re->overall_options & PCRE2_ANCHORED) != 0; - -/* The "must be at the start of a line" flags are used in a loop when finding -where to start. */ - -startline = (re->flags & PCRE2_STARTLINE) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; -bumpalong_limit = end_subject; - -/* Get data from the match context, if present, and fill in the fields in the -match block. It is an error to set an offset limit without setting the flag at -compile time. */ - -if (mcontext == NULL) - { - mb->callout = NULL; - mb->memctl = re->memctl; - } -else - { - if (mcontext->offset_limit != PCRE2_UNSET) - { - if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) - return PCRE2_ERROR_BADOFFSETLIMIT; - bumpalong_limit = subject + mcontext->offset_limit; - } - mb->callout = mcontext->callout; - mb->callout_data = mcontext->callout_data; - mb->memctl = mcontext->memctl; - } - -mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_count * re->name_entry_size; -mb->tables = re->tables; -mb->start_subject = subject; -mb->end_subject = end_subject; -mb->start_offset = start_offset; -mb->moptions = options; -mb->poptions = re->overall_options; - -/* Process the \R and newline settings. */ - -mb->bsr_convention = re->bsr_convention; -mb->nltype = NLTYPE_FIXED; -switch(re->newline_convention) - { - case PCRE2_NEWLINE_CR: - mb->nllen = 1; - mb->nl[0] = CHAR_CR; - break; - - case PCRE2_NEWLINE_LF: - mb->nllen = 1; - mb->nl[0] = CHAR_NL; - break; - - case PCRE2_NEWLINE_CRLF: - mb->nllen = 2; - mb->nl[0] = CHAR_CR; - mb->nl[1] = CHAR_NL; - break; - - case PCRE2_NEWLINE_ANY: - mb->nltype = NLTYPE_ANY; - break; - - case PCRE2_NEWLINE_ANYCRLF: - mb->nltype = NLTYPE_ANYCRLF; - break; - - default: return PCRE2_ERROR_INTERNAL; - } - -/* Check a UTF string for validity if required. For 8-bit and 16-bit strings, -we must also check that a starting offset does not point into the middle of a -multiunit character. We check only the portion of the subject that is going to -be inspected during matching - from the offset minus the maximum back reference -to the given length. This saves time when a small part of a large subject is -being matched by the use of a starting offset. Note that the maximum lookbehind -is a number of characters, not code units. */ - -#ifdef SUPPORT_UNICODE -if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) - { - PCRE2_SPTR check_subject = start_match; /* start_match includes offset */ - - if (start_offset > 0) - { -#if PCRE2_CODE_UNIT_WIDTH != 32 - unsigned int i; - if (start_match < end_subject && NOT_FIRSTCU(*start_match)) - return PCRE2_ERROR_BADUTFOFFSET; - for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--) - { - check_subject--; - while (check_subject > subject && -#if PCRE2_CODE_UNIT_WIDTH == 8 - (*check_subject & 0xc0) == 0x80) -#else /* 16-bit */ - (*check_subject & 0xfc00) == 0xdc00) -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - check_subject--; - } -#else /* In the 32-bit library, one code unit equals one character. */ - check_subject -= re->max_lookbehind; - if (check_subject < subject) check_subject = subject; -#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - } - - /* Validate the relevant portion of the subject. After an error, adjust the - offset to be an absolute offset in the whole string. */ - - match_data->rc = PRIV(valid_utf)(check_subject, - length - (check_subject - subject), &(match_data->startchar)); - if (match_data->rc != 0) - { - match_data->startchar += check_subject - subject; - return match_data->rc; - } - } -#endif /* SUPPORT_UNICODE */ - -/* Set up the first code unit to match, if available. The first_codeunit value -is never set for an anchored regular expression, but the anchoring may be -forced at run time, so we have to test for anchoring. The first code unit may -be unset for an unanchored pattern, of course. If there's no first code unit -there may be a bitmap of possible first characters. */ - -if (!anchored) - { - if ((re->flags & PCRE2_FIRSTSET) != 0) - { - has_first_cu = TRUE; - first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit); - if ((re->flags & PCRE2_FIRSTCASELESS) != 0) - { - first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); -#endif - } - } - else - if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0) - start_bits = re->start_bitmap; - } - -/* For anchored or unanchored matches, there may be a "last known required -character" set. */ - -if ((re->flags & PCRE2_LASTSET) != 0) - { - has_req_cu = TRUE; - req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit); - if ((re->flags & PCRE2_LASTCASELESS) != 0) - { - req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); -#endif - } - } - -/* Fill in fields that are always returned in the match data. */ - -match_data->code = re; -match_data->subject = subject; -match_data->mark = NULL; -match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER; - -/* Call the main matching function, looping for a non-anchored regex after a -failed match. If not restarting, perform certain optimizations at the start of -a match. */ - -for (;;) - { - int rc; - - /* ----------------- Start of match optimizations ---------------- */ - - /* There are some optimizations that avoid running the match if a known - starting point is not found, or if a known later code unit is not present. - However, there is an option (settable at compile time) that disables - these, for testing and for ensuring that all callouts do actually occur. - The optimizations must also be avoided when restarting a DFA match. */ - - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && - (options & PCRE2_DFA_RESTART) == 0) - { - PCRE2_SPTR save_end_subject = end_subject; - - /* If firstline is TRUE, the start of the match is constrained to the first - line of a multiline string. That is, the match must be before or at the - first newline. Implement this by temporarily adjusting end_subject so that - we stop the optimization scans at a newline. If the match fails at the - newline, later code breaks this loop. */ - - if (firstline) - { - PCRE2_SPTR t = start_match; -#ifdef SUPPORT_UNICODE - if (utf) - { - while (t < mb->end_subject && !IS_NEWLINE(t)) - { - t++; - ACROSSCHAR(t < end_subject, *t, t++); - } - } - else -#endif - while (t < mb->end_subject && !IS_NEWLINE(t)) t++; - end_subject = t; - } - - /* Advance to a unique first code unit if there is one. */ - - if (has_first_cu) - { - PCRE2_UCHAR smc; - if (first_cu != first_cu2) - while (start_match < end_subject && - (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) - start_match++; - else - while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu) - start_match++; - } - - /* Or to just after a linebreak for a multiline match */ - - else if (startline) - { - if (start_match > mb->start_subject + start_offset) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - while (start_match < end_subject && !WAS_NEWLINE(start_match)) - { - start_match++; - ACROSSCHAR(start_match < end_subject, *start_match, - start_match++); - } - } - else -#endif - while (start_match < end_subject && !WAS_NEWLINE(start_match)) - start_match++; - - /* If we have just passed a CR and the newline option is ANY or - ANYCRLF, and we are now at a LF, advance the match position by one more - code unit. */ - - if (start_match[-1] == CHAR_CR && - (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) && - start_match < end_subject && - UCHAR21TEST(start_match) == CHAR_NL) - start_match++; - } - } - - /* Or to a non-unique first code unit if any have been identified. The - bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all - code units greater than 254 set the 255 bit. */ - - else if (start_bits != NULL) - { - while (start_match < end_subject) - { - register uint32_t c = UCHAR21TEST(start_match); -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) c = 255; -#endif - if ((start_bits[c/8] & (1 << (c&7))) != 0) break; - start_match++; - } - } - - /* Restore fudged end_subject */ - - end_subject = save_end_subject; - - /* The following two optimizations are disabled for partial matching. */ - - if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0) - { - /* The minimum matching length is a lower bound; no actual string of that - length may actually match the pattern. Although the value is, strictly, - in characters, we treat it as code units to avoid spending too much time - in this optimization. */ - - if (end_subject - start_match < re->minlength) return PCRE2_ERROR_NOMATCH; - - /* If req_cu is set, we know that that code unit must appear in the - subject for the match to succeed. If the first code unit is set, req_cu - must be later in the subject; otherwise the test starts at the match - point. This optimization can save a huge amount of backtracking in - patterns with nested unlimited repeats that aren't going to match. - Writing separate code for cased/caseless versions makes it go faster, as - does using an autoincrement and backing off on a match. - - HOWEVER: when the subject string is very, very long, searching to its end - can take a long time, and give bad performance on quite ordinary - patterns. This showed up when somebody was matching something like - /^\d+C/ on a 32-megabyte string... so we don't do this when the string is - sufficiently long. */ - - if (has_req_cu && end_subject - start_match < REQ_CU_MAX) - { - register PCRE2_SPTR p = start_match + (has_first_cu? 1:0); - - /* We don't need to repeat the search if we haven't yet reached the - place we found it at last time. */ - - if (p > req_cu_ptr) - { - if (req_cu != req_cu2) - { - while (p < end_subject) - { - register uint32_t pp = UCHAR21INCTEST(p); - if (pp == req_cu || pp == req_cu2) { p--; break; } - } - } - else - { - while (p < end_subject) - { - if (UCHAR21INCTEST(p) == req_cu) { p--; break; } - } - } - - /* If we can't find the required code unit, break the matching loop, - forcing a match failure. */ - - if (p >= end_subject) break; - - /* If we have found the required code unit, save the point where we - found it, so that we don't search again next time round the loop if - the start hasn't passed this code unit yet. */ - - req_cu_ptr = p; - } - } - } - } - - /* ------------ End of start of match optimizations ------------ */ - - /* Give no match if we have passed the bumpalong limit. */ - - if (start_match > bumpalong_limit) break; - - /* OK, now we can do the business */ - - mb->start_used_ptr = start_match; - mb->last_used_ptr = start_match; - mb->recursive = NULL; - - rc = internal_dfa_match( - mb, /* fixed match data */ - mb->start_code, /* this subexpression's code */ - start_match, /* where we currently are */ - start_offset, /* start offset in subject */ - match_data->ovector, /* offset vector */ - match_data->oveccount * 2, /* actual size of same */ - workspace, /* workspace vector */ - wscount, /* size of same */ - 0); /* function recurse level */ - - /* Anything other than "no match" means we are done, always; otherwise, carry - on only if not anchored. */ - - if (rc != PCRE2_ERROR_NOMATCH || anchored) - { - if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0) - { - match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject); - match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject); - } - match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject); - match_data->rightchar = mb->last_used_ptr - subject; - match_data->startchar = (PCRE2_SIZE)(start_match - subject); - match_data->rc = rc; - return rc; - } - - /* Advance to the next subject character unless we are at the end of a line - and firstline is set. */ - - if (firstline && IS_NEWLINE(start_match)) break; - start_match++; -#ifdef SUPPORT_UNICODE - if (utf) - { - ACROSSCHAR(start_match < end_subject, *start_match, - start_match++); - } -#endif - if (start_match > end_subject) break; - - /* If we have just passed a CR and we are now at a LF, and the pattern does - not contain any explicit matches for \r or \n, and the newline option is CRLF - or ANY or ANYCRLF, advance the match position by one more character. */ - - if (UCHAR21TEST(start_match - 1) == CHAR_CR && - start_match < end_subject && - UCHAR21TEST(start_match) == CHAR_NL && - (re->flags & PCRE2_HASCRORLF) == 0 && - (mb->nltype == NLTYPE_ANY || - mb->nltype == NLTYPE_ANYCRLF || - mb->nllen == 2)) - start_match++; - - } /* "Bumpalong" loop */ - - -return PCRE2_ERROR_NOMATCH; -} - -/* End of pcre2_dfa_match.c */ diff --git a/pcre2/src/pcre2_error.c b/pcre2/src/pcre2_error.c deleted file mode 100644 index 6b4756aec..000000000 --- a/pcre2/src/pcre2_error.c +++ /dev/null @@ -1,321 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - -#define STRING(a) # a -#define XSTRING(s) STRING(s) - -/* The texts of compile-time error messages. Compile-time error numbers start -at COMPILE_ERROR_BASE (100). - -This used to be a table of strings, but in order to reduce the number of -relocations needed when a shared library is loaded dynamically, it is now one -long string. We cannot use a table of offsets, because the lengths of inserts -such as XSTRING(MAX_NAME_SIZE) are not known. Instead, -pcre2_get_error_message() counts through to the one it wants - this isn't a -performance issue because these strings are used only when there is an error. - -Each substring ends with \0 to insert a null character. This includes the final -substring, so that the whole string ends with \0\0, which can be detected when -counting through. */ - -static const char compile_error_texts[] = - "no error\0" - "\\ at end of pattern\0" - "\\c at end of pattern\0" - "unrecognized character follows \\\0" - "numbers out of order in {} quantifier\0" - /* 5 */ - "number too big in {} quantifier\0" - "missing terminating ] for character class\0" - "invalid escape sequence in character class\0" - "range out of order in character class\0" - "quantifier does not follow a repeatable item\0" - /* 10 */ - "internal error: unexpected repeat\0" - "unrecognized character after (? or (?-\0" - "POSIX named classes are supported only within a class\0" - "POSIX collating elements are not supported\0" - "missing closing parenthesis\0" - /* 15 */ - "reference to non-existent subpattern\0" - "pattern passed as NULL\0" - "unrecognised compile-time option bit(s)\0" - "missing ) after (?# comment\0" - "parentheses are too deeply nested\0" - /* 20 */ - "regular expression is too large\0" - "failed to allocate heap memory\0" - "unmatched closing parenthesis\0" - "internal error: code overflow\0" - "letter or underscore expected after (?< or (?'\0" - /* 25 */ - "lookbehind assertion is not fixed length\0" - "malformed number or name after (?(\0" - "conditional group contains more than two branches\0" - "assertion expected after (?( or (?(?C)\0" - "(?R or (?[+-]digits must be followed by )\0" - /* 30 */ - "unknown POSIX class name\0" - "internal error in pcre2_study(): should not occur\0" - "this version of PCRE2 does not have Unicode support\0" - "parentheses are too deeply nested (stack check)\0" - "character code point value in \\x{} or \\o{} is too large\0" - /* 35 */ - "invalid condition (?(0)\0" - "\\C is not allowed in a lookbehind assertion\0" - "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" - "number after (?C is greater than 255\0" - "closing parenthesis for (?C expected\0" - /* 40 */ - "invalid escape sequence in (*VERB) name\0" - "unrecognized character after (?P\0" - "syntax error in subpattern name (missing terminator)\0" - "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0" - "group name must start with a non-digit\0" - /* 45 */ - "this version of PCRE2 does not have support for \\P, \\p, or \\X\0" - "malformed \\P or \\p sequence\0" - "unknown property name after \\P or \\p\0" - "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0" - "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" - /* 50 */ - "invalid range in character class\0" - "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" - "internal error: overran compiling workspace\0" - "internal error: previously-checked referenced subpattern not found\0" - "DEFINE group contains more than one branch\0" - /* 55 */ - "missing opening brace after \\o\0" - "internal error: unknown newline setting\0" - "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" - "a numbered reference must not be zero\0" - "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" - /* 60 */ - "(*VERB) not recognized or malformed\0" - "number is too big\0" - "subpattern name expected\0" - "digit expected after (?+\0" - "non-octal character in \\o{} (closing brace missing?)\0" - /* 65 */ - "different names for subpatterns of the same number are not allowed\0" - "(*MARK) must have an argument\0" - "non-hex character in \\x{} (closing brace missing?)\0" -#ifndef EBCDIC - "\\c must be followed by a printable ASCII character\0" -#else - "\\c must be followed by a letter or one of [\\]^_?\0" -#endif - "\\k is not followed by a braced, angle-bracketed, or quoted name\0" - /* 70 */ - "internal error: unknown opcode in find_fixedlength()\0" - "\\N is not supported in a class\0" - "SPARE ERROR\0" - "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0" - "using UTF is disabled by the application\0" - /* 75 */ - "using UCP is disabled by the application\0" - "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" - "character code point value in \\u.... sequence is too large\0" - "digits missing in \\x{} or \\o{}\0" - "syntax error in (?(VERSION condition\0" - /* 80 */ - "internal error: unknown opcode in auto_possessify()\0" - "missing terminating delimiter for callout with string argument\0" - "unrecognized string delimiter follows (?C\0" - "using \\C is disabled by the application\0" - "(?| and/or (?J: or (?x: parentheses are too deeply nested\0" - /* 85 */ - "using \\C is disabled in this PCRE2 library\0" - "regular expression is too complicated\0" - "lookbehind assertion is too long\0" - "pattern string is longer than the limit set by the application\0" - ; - -/* Match-time and UTF error texts are in the same format. */ - -static const char match_error_texts[] = - "no error\0" - "no match\0" - "partial match\0" - "UTF-8 error: 1 byte missing at end\0" - "UTF-8 error: 2 bytes missing at end\0" - /* 5 */ - "UTF-8 error: 3 bytes missing at end\0" - "UTF-8 error: 4 bytes missing at end\0" - "UTF-8 error: 5 bytes missing at end\0" - "UTF-8 error: byte 2 top bits not 0x80\0" - "UTF-8 error: byte 3 top bits not 0x80\0" - /* 10 */ - "UTF-8 error: byte 4 top bits not 0x80\0" - "UTF-8 error: byte 5 top bits not 0x80\0" - "UTF-8 error: byte 6 top bits not 0x80\0" - "UTF-8 error: 5-byte character is not allowed (RFC 3629)\0" - "UTF-8 error: 6-byte character is not allowed (RFC 3629)\0" - /* 15 */ - "UTF-8 error: code points greater than 0x10ffff are not defined\0" - "UTF-8 error: code points 0xd800-0xdfff are not defined\0" - "UTF-8 error: overlong 2-byte sequence\0" - "UTF-8 error: overlong 3-byte sequence\0" - "UTF-8 error: overlong 4-byte sequence\0" - /* 20 */ - "UTF-8 error: overlong 5-byte sequence\0" - "UTF-8 error: overlong 6-byte sequence\0" - "UTF-8 error: isolated byte with 0x80 bit set\0" - "UTF-8 error: illegal byte (0xfe or 0xff)\0" - "UTF-16 error: missing low surrogate at end\0" - /* 25 */ - "UTF-16 error: invalid low surrogate\0" - "UTF-16 error: isolated low surrogate\0" - "UTF-32 error: code points 0xd800-0xdfff are not defined\0" - "UTF-32 error: code points greater than 0x10ffff are not defined\0" - "bad data value\0" - /* 30 */ - "patterns do not all use the same character tables\0" - "magic number missing\0" - "pattern compiled in wrong mode: 8/16/32-bit error\0" - "bad offset value\0" - "bad option value\0" - /* 35 */ - "invalid replacement string\0" - "bad offset into UTF string\0" - "callout error code\0" /* Never returned by PCRE2 itself */ - "invalid data in workspace for DFA restart\0" - "too much recursion for DFA matching\0" - /* 40 */ - "backreference condition or recursion test is not supported for DFA matching\0" - "function is not supported for DFA matching\0" - "pattern contains an item that is not supported for DFA matching\0" - "workspace size exceeded in DFA matching\0" - "internal error - pattern overwritten?\0" - /* 45 */ - "bad JIT option\0" - "JIT stack limit reached\0" - "match limit exceeded\0" - "no more memory\0" - "unknown substring\0" - /* 50 */ - "non-unique substring name\0" - "NULL argument passed\0" - "nested recursion at the same subject position\0" - "recursion limit exceeded\0" - "requested value is not available\0" - /* 55 */ - "requested value is not set\0" - "offset limit set without PCRE2_USE_OFFSET_LIMIT\0" - "bad escape sequence in replacement string\0" - "expected closing curly bracket in replacement string\0" - "bad substitution in replacement string\0" - /* 60 */ - "match with end before start is not supported\0" - "too many replacements (more than INT_MAX)\0" - ; - - -/************************************************* -* Return error message * -*************************************************/ - -/* This function copies an error message into a buffer whose units are of an -appropriate width. Error numbers are positive for compile-time errors, and -negative for match-time errors (except for UTF errors), but the numbers are all -distinct. - -Arguments: - enumber error number - buffer where to put the message (zero terminated) - size size of the buffer - -Returns: length of message if all is well - negative on error -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, size_t size) -{ -char xbuff[128]; -const char *message; -size_t i; -uint32_t n; - -if (size == 0) return PCRE2_ERROR_NOMEMORY; - -if (enumber > COMPILE_ERROR_BASE) /* Compile error */ - { - message = compile_error_texts; - n = enumber - COMPILE_ERROR_BASE; - } -else /* Match or UTF error */ - { - message = match_error_texts; - n = -enumber; - } - -for (; n > 0; n--) - { - while (*message++ != CHAR_NULL) {}; - if (*message == CHAR_NULL) - { - sprintf(xbuff, "No text for error %d", enumber); - break; - } - } - -for (i = 0; *message != 0; i++) - { - if (i >= size - 1) - { - buffer[i] = 0; /* Terminate partial message */ - return PCRE2_ERROR_NOMEMORY; - } - buffer[i] = *message++; - } - -buffer[i] = 0; -return i; -} - -/* End of pcre2_error.c */ diff --git a/pcre2/src/pcre2_find_bracket.c b/pcre2/src/pcre2_find_bracket.c deleted file mode 100644 index 803e71976..000000000 --- a/pcre2/src/pcre2_find_bracket.c +++ /dev/null @@ -1,218 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains a single function that scans through a compiled pattern -until it finds a capturing bracket with the given number, or, if the number is -negative, an instance of OP_REVERSE for a lookbehind. The function is called -from pcre2_compile.c and also from pcre2_study.c when finding the minimum -matching length. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - -/************************************************* -* Scan compiled regex for specific bracket * -*************************************************/ - -/* -Arguments: - code points to start of expression - utf TRUE in UTF mode - number the required bracket number or negative to find a lookbehind - -Returns: pointer to the opcode for the bracket, or NULL if not found -*/ - -PCRE2_SPTR -PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number) -{ -for (;;) - { - register PCRE2_UCHAR c = *code; - - if (c == OP_END) return NULL; - - /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. CALLOUT_STR is used for - callouts with string arguments. In both cases the length in the table is - zero; the actual length is stored in the compiled code. */ - - if (c == OP_XCLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); - - /* Handle lookbehind */ - - else if (c == OP_REVERSE) - { - if (number < 0) return (PCRE2_UCHAR *)code; - code += PRIV(OP_lengths)[c]; - } - - /* Handle capturing bracket */ - - else if (c == OP_CBRA || c == OP_SCBRA || - c == OP_CBRAPOS || c == OP_SCBRAPOS) - { - int n = (int)GET2(code, 1+LINK_SIZE); - if (n == number) return (PCRE2_UCHAR *)code; - code += PRIV(OP_lengths)[c]; - } - - /* Otherwise, we can get the item's length from the table, except that for - repeated character types, we have to test for \p and \P, which have an extra - two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we - must add in its length. */ - - else - { - switch(c) - { - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; - break; - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - code += code[1]; - break; - } - - /* Add in the fixed length from the table */ - - code += PRIV(OP_lengths)[c]; - - /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be - followed by a multi-byte character. The length in the table is a minimum, so - we have to arrange to skip the extra bytes. */ - -#ifdef MAYBE_UTF_MULTI - if (utf) switch(c) - { - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - case OP_UPTO: - case OP_UPTOI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_MINUPTO: - case OP_MINUPTOI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - case OP_STAR: - case OP_STARI: - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_MINSTAR: - case OP_MINSTARI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_POSSTAR: - case OP_POSSTARI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - case OP_PLUS: - case OP_PLUSI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_MINPLUS: - case OP_MINPLUSI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_POSPLUS: - case OP_POSPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - case OP_QUERY: - case OP_QUERYI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_MINQUERY: - case OP_MINQUERYI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - case OP_POSQUERY: - case OP_POSQUERYI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); - break; - } -#else - (void)(utf); /* Keep compiler happy by referencing function argument */ -#endif /* MAYBE_UTF_MULTI */ - } - } -} - -/* End of pcre2_find_bracket.c */ diff --git a/pcre2/src/pcre2_internal.h b/pcre2/src/pcre2_internal.h deleted file mode 100644 index 7c9f66cc0..000000000 --- a/pcre2/src/pcre2_internal.h +++ /dev/null @@ -1,1944 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* We do not support both EBCDIC and Unicode at the same time. The "configure" -script prevents both being selected, but not everybody uses "configure". EBCDIC -is only supported for the 8-bit library, but the check for this has to be later -in this file, because the first part is not width-dependent, and is included by -pcre2test.c with CODE_UNIT_WIDTH == 0. */ - -#if defined EBCDIC && defined SUPPORT_UNICODE -#error The use of both EBCDIC and SUPPORT_UNICODE is not supported. -#endif - -/* Standard C headers */ - -#include -#include -#include -#include -#include -#include - -/* Macros to make boolean values more obvious. The #ifndef is to pacify -compiler warnings in environments where these macros are defined elsewhere. -Unfortunately, there is no way to do the same for the typedef. */ - -typedef int BOOL; -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif - -/* Valgrind (memcheck) support */ - -#ifdef SUPPORT_VALGRIND -#include -#endif - -/* When compiling a DLL for Windows, the exported symbols have to be declared -using some MS magic. I found some useful information on this web page: -http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the -information there, using __declspec(dllexport) without "extern" we have a -definition; with "extern" we have a declaration. The settings here override the -setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL, -which is all that is needed for applications (they just import the symbols). We -use: - - PCRE2_EXP_DECL for declarations - PCRE2_EXP_DEFN for definitions - -The reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test, -which is an application, but needs to import this file in order to "peek" at -internals, can #include pcre2.h first to get an application's-eye view. - -In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon, -special-purpose environments) might want to stick other stuff in front of -exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN -only if it is not already set. */ - -#ifndef PCRE2_EXP_DECL -# ifdef _WIN32 -# ifndef PCRE2_STATIC -# define PCRE2_EXP_DECL extern __declspec(dllexport) -# define PCRE2_EXP_DEFN __declspec(dllexport) -# else -# define PCRE2_EXP_DECL extern -# define PCRE2_EXP_DEFN -# endif -# else -# ifdef __cplusplus -# define PCRE2_EXP_DECL extern "C" -# else -# define PCRE2_EXP_DECL extern -# endif -# ifndef PCRE2_EXP_DEFN -# define PCRE2_EXP_DEFN PCRE2_EXP_DECL -# endif -# endif -#endif - -/* Include the public PCRE2 header and the definitions of UCP character -property values. This must follow the setting of PCRE2_EXP_DECL above. */ - -#include "pcre2.h" -#include "pcre2_ucp.h" - -/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced -with a custom type. This makes it possible, for example, to allow pcre2_match() -to process subject strings that are discontinuous by using a smart pointer -class. It must always be possible to inspect all of the subject string in -pcre2_match() because of the way it backtracks. */ - -/* WARNING: This is as yet untested for PCRE2. */ - -#ifdef CUSTOM_SUBJECT_PTR -#undef PCRE2_SPTR -#define PCRE2_SPTR CUSTOM_SUBJECT_PTR -#endif - -/* When compiling with the MSVC compiler, it is sometimes necessary to include -a "calling convention" before exported function names. (This is secondhand -information; I know nothing about MSVC myself). For example, something like - - void __cdecl function(....) - -might be needed. In order so make this easy, all the exported functions have -PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not -set, we ensure here that it has no effect. */ - -#ifndef PCRE2_CALL_CONVENTION -#define PCRE2_CALL_CONVENTION -#endif - -/* When checking for integer overflow in pcre2_compile(), we need to handle -large integers. If a 64-bit integer type is available, we can use that. -Otherwise we have to cast to double, which of course requires floating point -arithmetic. Handle this by defining a macro for the appropriate type. If -stdint.h is available, include it; it may define INT64_MAX. Systems that do not -have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set -by "configure". */ - -#if defined HAVE_STDINT_H -#include -#elif defined HAVE_INTTYPES_H -#include -#endif - -#if defined INT64_MAX || defined int64_t -#define INT64_OR_DOUBLE int64_t -#else -#define INT64_OR_DOUBLE double -#endif - -/* When compiling for use with the Virtual Pascal compiler, these functions -need to have their names changed. PCRE must be compiled with the -DVPCOMPAT -option on the command line. */ - -#ifdef VPCOMPAT -#define strlen(s) _strlen(s) -#define strncmp(s1,s2,m) _strncmp(s1,s2,m) -#define memcmp(s,c,n) _memcmp(s,c,n) -#define memcpy(d,s,n) _memcpy(d,s,n) -#define memmove(d,s,n) _memmove(d,s,n) -#define memset(s,c,n) _memset(s,c,n) -#else /* VPCOMPAT */ - -/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), -define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY -is set. Otherwise, include an emulating function for those systems that have -neither (there some non-Unix environments where this is the case). */ - -#ifndef HAVE_MEMMOVE -#undef memmove /* some systems may have a macro */ -#ifdef HAVE_BCOPY -#define memmove(a, b, c) bcopy(b, a, c) -#else /* HAVE_BCOPY */ -static void * -pcre_memmove(void *d, const void *s, size_t n) -{ -size_t i; -unsigned char *dest = (unsigned char *)d; -const unsigned char *src = (const unsigned char *)s; -if (dest > src) - { - dest += n; - src += n; - for (i = 0; i < n; ++i) *(--dest) = *(--src); - return (void *)dest; - } -else - { - for (i = 0; i < n; ++i) *dest++ = *src++; - return (void *)(dest - n); - } -} -#define memmove(a, b, c) pcre_memmove(a, b, c) -#endif /* not HAVE_BCOPY */ -#endif /* not HAVE_MEMMOVE */ -#endif /* not VPCOMPAT */ - -/* External (in the C sense) functions and tables that are private to the -libraries are always referenced using the PRIV macro. This makes it possible -for pcre2test.c to include some of the source files from the libraries using a -different PRIV definition to avoid name clashes. It also makes it clear in the -code that a non-static object is being referenced. */ - -#ifndef PRIV -#define PRIV(name) _pcre2_##name -#endif - -/* This is an unsigned int value that no UTF character can ever have, as -Unicode doesn't go beyond 0x0010ffff. */ - -#define NOTACHAR 0xffffffff - -/* This is the largest valid UTF/Unicode code point. */ - -#define MAX_UTF_CODE_POINT 0x10ffff - -/* Compile-time errors are added to this value. As they are documented, it -should probably never be changed. */ - -#define COMPILE_ERROR_BASE 100 - -/* Define the default BSR convention. */ - -#ifdef BSR_ANYCRLF -#define BSR_DEFAULT PCRE2_BSR_ANYCRLF -#else -#define BSR_DEFAULT PCRE2_BSR_UNICODE -#endif - - -/* ---------------- Basic UTF-8 macros ---------------- */ - -/* These UTF-8 macros are always defined because they are used in pcre2test for -handling wide characters in 16-bit and 32-bit modes, even if an 8-bit library -is not supported. */ - -/* Tests whether a UTF-8 code point needs extra bytes to decode. */ - -#define HASUTF8EXTRALEN(c) ((c) >= 0xc0) - -/* The following macros were originally written in the form of loops that used -data from the tables whose names start with PRIV(utf8_table). They were -rewritten by a user so as not to use loops, because in some environments this -gives a significant performance advantage, and it seems never to do any harm. -*/ - -/* Base macro to pick up the remaining bytes of a UTF-8 character, not -advancing the pointer. */ - -#define GETUTF8(c, eptr) \ - { \ - if ((c & 0x20) == 0) \ - c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ - else if ((c & 0x10) == 0) \ - c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ - else if ((c & 0x08) == 0) \ - c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ - ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ - else if ((c & 0x04) == 0) \ - c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ - ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ - (eptr[4] & 0x3f); \ - else \ - c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ - ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ - ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ - } - -/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing -the pointer. */ - -#define GETUTF8INC(c, eptr) \ - { \ - if ((c & 0x20) == 0) \ - c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \ - else if ((c & 0x10) == 0) \ - { \ - c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \ - eptr += 2; \ - } \ - else if ((c & 0x08) == 0) \ - { \ - c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \ - ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ - eptr += 3; \ - } \ - else if ((c & 0x04) == 0) \ - { \ - c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \ - ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \ - (eptr[3] & 0x3f); \ - eptr += 4; \ - } \ - else \ - { \ - c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \ - ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \ - ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \ - eptr += 5; \ - } \ - } - -/* Base macro to pick up the remaining bytes of a UTF-8 character, not -advancing the pointer, incrementing the length. */ - -#define GETUTF8LEN(c, eptr, len) \ - { \ - if ((c & 0x20) == 0) \ - { \ - c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ - len++; \ - } \ - else if ((c & 0x10) == 0) \ - { \ - c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ - len += 2; \ - } \ - else if ((c & 0x08) == 0) \ - {\ - c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ - ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ - len += 3; \ - } \ - else if ((c & 0x04) == 0) \ - { \ - c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ - ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ - (eptr[4] & 0x3f); \ - len += 4; \ - } \ - else \ - {\ - c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ - ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ - ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ - len += 5; \ - } \ - } - -/* --------------- Whitespace macros ---------------- */ - -/* Tests for Unicode horizontal and vertical whitespace characters must check a -number of different values. Using a switch statement for this generates the -fastest code (no loop, no memory access), and there are several places in the -interpreter code where this happens. In order to ensure that all the case lists -remain in step, we use macros so that there is only one place where the lists -are defined. - -These values are also required as lists in pcre2_compile.c when processing \h, -\H, \v and \V in a character class. The lists are defined in pcre2_tables.c, -but macros that define the values are here so that all the definitions are -together. The lists must be in ascending character order, terminated by -NOTACHAR (which is 0xffffffff). - -Any changes should ensure that the various macros are kept in step with each -other. NOTE: The values also appear in pcre2_jit_compile.c. */ - -/* -------------- ASCII/Unicode environments -------------- */ - -#ifndef EBCDIC - -/* Character U+180E (Mongolian Vowel Separator) is not included in the list of -spaces in the Unicode file PropList.txt, and Perl does not recognize it as a -space. However, in many other sources it is listed as a space and has been in -PCRE for a long time. */ - -#define HSPACE_LIST \ - CHAR_HT, CHAR_SPACE, CHAR_NBSP, \ - 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \ - 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \ - NOTACHAR - -#define HSPACE_MULTIBYTE_CASES \ - case 0x1680: /* OGHAM SPACE MARK */ \ - case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \ - case 0x2000: /* EN QUAD */ \ - case 0x2001: /* EM QUAD */ \ - case 0x2002: /* EN SPACE */ \ - case 0x2003: /* EM SPACE */ \ - case 0x2004: /* THREE-PER-EM SPACE */ \ - case 0x2005: /* FOUR-PER-EM SPACE */ \ - case 0x2006: /* SIX-PER-EM SPACE */ \ - case 0x2007: /* FIGURE SPACE */ \ - case 0x2008: /* PUNCTUATION SPACE */ \ - case 0x2009: /* THIN SPACE */ \ - case 0x200A: /* HAIR SPACE */ \ - case 0x202f: /* NARROW NO-BREAK SPACE */ \ - case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \ - case 0x3000 /* IDEOGRAPHIC SPACE */ - -#define HSPACE_BYTE_CASES \ - case CHAR_HT: \ - case CHAR_SPACE: \ - case CHAR_NBSP - -#define HSPACE_CASES \ - HSPACE_BYTE_CASES: \ - HSPACE_MULTIBYTE_CASES - -#define VSPACE_LIST \ - CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR - -#define VSPACE_MULTIBYTE_CASES \ - case 0x2028: /* LINE SEPARATOR */ \ - case 0x2029 /* PARAGRAPH SEPARATOR */ - -#define VSPACE_BYTE_CASES \ - case CHAR_LF: \ - case CHAR_VT: \ - case CHAR_FF: \ - case CHAR_CR: \ - case CHAR_NEL - -#define VSPACE_CASES \ - VSPACE_BYTE_CASES: \ - VSPACE_MULTIBYTE_CASES - -/* -------------- EBCDIC environments -------------- */ - -#else -#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR - -#define HSPACE_BYTE_CASES \ - case CHAR_HT: \ - case CHAR_SPACE: \ - case CHAR_NBSP - -#define HSPACE_CASES HSPACE_BYTE_CASES - -#ifdef EBCDIC_NL25 -#define VSPACE_LIST \ - CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR -#else -#define VSPACE_LIST \ - CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR -#endif - -#define VSPACE_BYTE_CASES \ - case CHAR_LF: \ - case CHAR_VT: \ - case CHAR_FF: \ - case CHAR_CR: \ - case CHAR_NEL - -#define VSPACE_CASES VSPACE_BYTE_CASES -#endif /* EBCDIC */ - -/* -------------- End of whitespace macros -------------- */ - - -/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF, -"any" and "anycrlf" at present). The following macros are used to package up -testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various -modules to indicate in which datablock the parameters exist, and what the -start/end of string field names are. */ - -#define NLTYPE_FIXED 0 /* Newline is a fixed length string */ -#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */ -#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */ - -/* This macro checks for a newline at the given position */ - -#define IS_NEWLINE(p) \ - ((NLBLOCK->nltype != NLTYPE_FIXED)? \ - ((p) < NLBLOCK->PSEND && \ - PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ - &(NLBLOCK->nllen), utf)) \ - : \ - ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ - UCHAR21TEST(p) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \ - ) \ - ) - -/* This macro checks for a newline immediately preceding the given position */ - -#define WAS_NEWLINE(p) \ - ((NLBLOCK->nltype != NLTYPE_FIXED)? \ - ((p) > NLBLOCK->PSSTART && \ - PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ - &(NLBLOCK->nllen), utf)) \ - : \ - ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ - UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ - ) \ - ) - -/* Private flags containing information about the compiled pattern. The first -three must not be changed, because whichever is set is actually the number of -bytes in a code unit in that mode. */ - -#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */ -#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */ -#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */ -#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */ -#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */ -#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */ -#define PCRE2_LASTSET 0x00000080 /* last code unit is set */ -#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */ -#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */ -#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */ -#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */ -#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */ -#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */ -#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */ -#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */ -#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */ -#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */ -#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */ -#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */ -#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */ -#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */ -#define PCRE2_HASBKC 0x00400000 /* contains \C */ - -#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32) - -/* Values for the matchedby field in a match data block. */ - -enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */ - PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */ - PCRE2_MATCHEDBY_JIT }; /* pcre2_jit_match() */ - -/* Magic number to provide a small check against being handed junk. */ - -#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ - -/* The maximum remaining length of subject we are prepared to search for a -req_unit match. */ - -#define REQ_CU_MAX 1000 - -/* Bit definitions for entries in the pcre_ctypes table. */ - -#define ctype_space 0x01 -#define ctype_letter 0x02 -#define ctype_digit 0x04 -#define ctype_xdigit 0x08 -#define ctype_word 0x10 /* alphanumeric or '_' */ -#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ - -/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set -of bits for a class map. Some classes are built by combining these tables. */ - -#define cbit_space 0 /* [:space:] or \s */ -#define cbit_xdigit 32 /* [:xdigit:] */ -#define cbit_digit 64 /* [:digit:] or \d */ -#define cbit_upper 96 /* [:upper:] */ -#define cbit_lower 128 /* [:lower:] */ -#define cbit_word 160 /* [:word:] or \w */ -#define cbit_graph 192 /* [:graph:] */ -#define cbit_print 224 /* [:print:] */ -#define cbit_punct 256 /* [:punct:] */ -#define cbit_cntrl 288 /* [:cntrl:] */ -#define cbit_length 320 /* Length of the cbits table */ - -/* Offsets of the various tables from the base tables pointer, and -total length. */ - -#define lcc_offset 0 -#define fcc_offset 256 -#define cbits_offset 512 -#define ctypes_offset (cbits_offset + cbit_length) -#define tables_length (ctypes_offset + 256) - - -/* -------------------- Character and string names ------------------------ */ - -/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal -character constants like '*' because the compiler would emit their EBCDIC code, -which is different from their ASCII/UTF-8 code. Instead we define macros for -the characters so that they always use the ASCII/UTF-8 code when UTF-8 support -is enabled. When UTF-8 support is not enabled, the definitions use character -literals. Both character and string versions of each character are needed, and -there are some longer strings as well. - -This means that, on EBCDIC platforms, the PCRE library can handle either -EBCDIC, or UTF-8, but not both. To support both in the same compiled library -would need different lookups depending on whether PCRE2_UTF was set or not. -This would make it impossible to use characters in switch/case statements, -which would reduce performance. For a theoretical use (which nobody has asked -for) in a minority area (EBCDIC platforms), this is not sensible. Any -application that did need both could compile two versions of the library, using -macros to give the functions distinct names. */ - -#ifndef SUPPORT_UNICODE - -/* UTF-8 support is not enabled; use the platform-dependent character literals -so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF -mode. Newline characters are problematic in EBCDIC. Though it has CR and LF -characters, a common practice has been to use its NL (0x15) character as the -line terminator in C-like processing environments. However, sometimes the LF -(0x25) character is used instead, according to this Unicode document: - -http://unicode.org/standard/reports/tr13/tr13-5.html - -PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 -instead. Whichever is *not* chosen is defined as NEL. - -In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the -same code point. */ - -#ifdef EBCDIC - -#ifndef EBCDIC_NL25 -#define CHAR_NL '\x15' -#define CHAR_NEL '\x25' -#define STR_NL "\x15" -#define STR_NEL "\x25" -#else -#define CHAR_NL '\x25' -#define CHAR_NEL '\x15' -#define STR_NL "\x25" -#define STR_NEL "\x15" -#endif - -#define CHAR_LF CHAR_NL -#define STR_LF STR_NL - -#define CHAR_ESC '\047' -#define CHAR_DEL '\007' -#define CHAR_NBSP ((unsigned char)'\x41') -#define STR_ESC "\047" -#define STR_DEL "\007" - -#else /* Not EBCDIC */ - -/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for -compatibility. NEL is the Unicode newline character; make sure it is -a positive value. */ - -#define CHAR_LF '\n' -#define CHAR_NL CHAR_LF -#define CHAR_NEL ((unsigned char)'\x85') -#define CHAR_ESC '\033' -#define CHAR_DEL '\177' -#define CHAR_NBSP ((unsigned char)'\xa0') - -#define STR_LF "\n" -#define STR_NL STR_LF -#define STR_NEL "\x85" -#define STR_ESC "\033" -#define STR_DEL "\177" - -#endif /* EBCDIC */ - -/* The remaining definitions work in both environments. */ - -#define CHAR_NULL '\0' -#define CHAR_HT '\t' -#define CHAR_VT '\v' -#define CHAR_FF '\f' -#define CHAR_CR '\r' -#define CHAR_BS '\b' -#define CHAR_BEL '\a' - -#define CHAR_SPACE ' ' -#define CHAR_EXCLAMATION_MARK '!' -#define CHAR_QUOTATION_MARK '"' -#define CHAR_NUMBER_SIGN '#' -#define CHAR_DOLLAR_SIGN '$' -#define CHAR_PERCENT_SIGN '%' -#define CHAR_AMPERSAND '&' -#define CHAR_APOSTROPHE '\'' -#define CHAR_LEFT_PARENTHESIS '(' -#define CHAR_RIGHT_PARENTHESIS ')' -#define CHAR_ASTERISK '*' -#define CHAR_PLUS '+' -#define CHAR_COMMA ',' -#define CHAR_MINUS '-' -#define CHAR_DOT '.' -#define CHAR_SLASH '/' -#define CHAR_0 '0' -#define CHAR_1 '1' -#define CHAR_2 '2' -#define CHAR_3 '3' -#define CHAR_4 '4' -#define CHAR_5 '5' -#define CHAR_6 '6' -#define CHAR_7 '7' -#define CHAR_8 '8' -#define CHAR_9 '9' -#define CHAR_COLON ':' -#define CHAR_SEMICOLON ';' -#define CHAR_LESS_THAN_SIGN '<' -#define CHAR_EQUALS_SIGN '=' -#define CHAR_GREATER_THAN_SIGN '>' -#define CHAR_QUESTION_MARK '?' -#define CHAR_COMMERCIAL_AT '@' -#define CHAR_A 'A' -#define CHAR_B 'B' -#define CHAR_C 'C' -#define CHAR_D 'D' -#define CHAR_E 'E' -#define CHAR_F 'F' -#define CHAR_G 'G' -#define CHAR_H 'H' -#define CHAR_I 'I' -#define CHAR_J 'J' -#define CHAR_K 'K' -#define CHAR_L 'L' -#define CHAR_M 'M' -#define CHAR_N 'N' -#define CHAR_O 'O' -#define CHAR_P 'P' -#define CHAR_Q 'Q' -#define CHAR_R 'R' -#define CHAR_S 'S' -#define CHAR_T 'T' -#define CHAR_U 'U' -#define CHAR_V 'V' -#define CHAR_W 'W' -#define CHAR_X 'X' -#define CHAR_Y 'Y' -#define CHAR_Z 'Z' -#define CHAR_LEFT_SQUARE_BRACKET '[' -#define CHAR_BACKSLASH '\\' -#define CHAR_RIGHT_SQUARE_BRACKET ']' -#define CHAR_CIRCUMFLEX_ACCENT '^' -#define CHAR_UNDERSCORE '_' -#define CHAR_GRAVE_ACCENT '`' -#define CHAR_a 'a' -#define CHAR_b 'b' -#define CHAR_c 'c' -#define CHAR_d 'd' -#define CHAR_e 'e' -#define CHAR_f 'f' -#define CHAR_g 'g' -#define CHAR_h 'h' -#define CHAR_i 'i' -#define CHAR_j 'j' -#define CHAR_k 'k' -#define CHAR_l 'l' -#define CHAR_m 'm' -#define CHAR_n 'n' -#define CHAR_o 'o' -#define CHAR_p 'p' -#define CHAR_q 'q' -#define CHAR_r 'r' -#define CHAR_s 's' -#define CHAR_t 't' -#define CHAR_u 'u' -#define CHAR_v 'v' -#define CHAR_w 'w' -#define CHAR_x 'x' -#define CHAR_y 'y' -#define CHAR_z 'z' -#define CHAR_LEFT_CURLY_BRACKET '{' -#define CHAR_VERTICAL_LINE '|' -#define CHAR_RIGHT_CURLY_BRACKET '}' -#define CHAR_TILDE '~' - -#define STR_HT "\t" -#define STR_VT "\v" -#define STR_FF "\f" -#define STR_CR "\r" -#define STR_BS "\b" -#define STR_BEL "\a" - -#define STR_SPACE " " -#define STR_EXCLAMATION_MARK "!" -#define STR_QUOTATION_MARK "\"" -#define STR_NUMBER_SIGN "#" -#define STR_DOLLAR_SIGN "$" -#define STR_PERCENT_SIGN "%" -#define STR_AMPERSAND "&" -#define STR_APOSTROPHE "'" -#define STR_LEFT_PARENTHESIS "(" -#define STR_RIGHT_PARENTHESIS ")" -#define STR_ASTERISK "*" -#define STR_PLUS "+" -#define STR_COMMA "," -#define STR_MINUS "-" -#define STR_DOT "." -#define STR_SLASH "/" -#define STR_0 "0" -#define STR_1 "1" -#define STR_2 "2" -#define STR_3 "3" -#define STR_4 "4" -#define STR_5 "5" -#define STR_6 "6" -#define STR_7 "7" -#define STR_8 "8" -#define STR_9 "9" -#define STR_COLON ":" -#define STR_SEMICOLON ";" -#define STR_LESS_THAN_SIGN "<" -#define STR_EQUALS_SIGN "=" -#define STR_GREATER_THAN_SIGN ">" -#define STR_QUESTION_MARK "?" -#define STR_COMMERCIAL_AT "@" -#define STR_A "A" -#define STR_B "B" -#define STR_C "C" -#define STR_D "D" -#define STR_E "E" -#define STR_F "F" -#define STR_G "G" -#define STR_H "H" -#define STR_I "I" -#define STR_J "J" -#define STR_K "K" -#define STR_L "L" -#define STR_M "M" -#define STR_N "N" -#define STR_O "O" -#define STR_P "P" -#define STR_Q "Q" -#define STR_R "R" -#define STR_S "S" -#define STR_T "T" -#define STR_U "U" -#define STR_V "V" -#define STR_W "W" -#define STR_X "X" -#define STR_Y "Y" -#define STR_Z "Z" -#define STR_LEFT_SQUARE_BRACKET "[" -#define STR_BACKSLASH "\\" -#define STR_RIGHT_SQUARE_BRACKET "]" -#define STR_CIRCUMFLEX_ACCENT "^" -#define STR_UNDERSCORE "_" -#define STR_GRAVE_ACCENT "`" -#define STR_a "a" -#define STR_b "b" -#define STR_c "c" -#define STR_d "d" -#define STR_e "e" -#define STR_f "f" -#define STR_g "g" -#define STR_h "h" -#define STR_i "i" -#define STR_j "j" -#define STR_k "k" -#define STR_l "l" -#define STR_m "m" -#define STR_n "n" -#define STR_o "o" -#define STR_p "p" -#define STR_q "q" -#define STR_r "r" -#define STR_s "s" -#define STR_t "t" -#define STR_u "u" -#define STR_v "v" -#define STR_w "w" -#define STR_x "x" -#define STR_y "y" -#define STR_z "z" -#define STR_LEFT_CURLY_BRACKET "{" -#define STR_VERTICAL_LINE "|" -#define STR_RIGHT_CURLY_BRACKET "}" -#define STR_TILDE "~" - -#define STRING_ACCEPT0 "ACCEPT\0" -#define STRING_COMMIT0 "COMMIT\0" -#define STRING_F0 "F\0" -#define STRING_FAIL0 "FAIL\0" -#define STRING_MARK0 "MARK\0" -#define STRING_PRUNE0 "PRUNE\0" -#define STRING_SKIP0 "SKIP\0" -#define STRING_THEN "THEN" - -#define STRING_alpha0 "alpha\0" -#define STRING_lower0 "lower\0" -#define STRING_upper0 "upper\0" -#define STRING_alnum0 "alnum\0" -#define STRING_ascii0 "ascii\0" -#define STRING_blank0 "blank\0" -#define STRING_cntrl0 "cntrl\0" -#define STRING_digit0 "digit\0" -#define STRING_graph0 "graph\0" -#define STRING_print0 "print\0" -#define STRING_punct0 "punct\0" -#define STRING_space0 "space\0" -#define STRING_word0 "word\0" -#define STRING_xdigit "xdigit" - -#define STRING_DEFINE "DEFINE" -#define STRING_VERSION "VERSION" -#define STRING_WEIRD_STARTWORD "[:<:]]" -#define STRING_WEIRD_ENDWORD "[:>:]]" - -#define STRING_CR_RIGHTPAR "CR)" -#define STRING_LF_RIGHTPAR "LF)" -#define STRING_CRLF_RIGHTPAR "CRLF)" -#define STRING_ANY_RIGHTPAR "ANY)" -#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" -#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" -#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" -#define STRING_UTF8_RIGHTPAR "UTF8)" -#define STRING_UTF16_RIGHTPAR "UTF16)" -#define STRING_UTF32_RIGHTPAR "UTF32)" -#define STRING_UTF_RIGHTPAR "UTF)" -#define STRING_UCP_RIGHTPAR "UCP)" -#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)" -#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)" -#define STRING_NO_JIT_RIGHTPAR "NO_JIT)" -#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" -#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)" -#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)" -#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" -#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION=" -#define STRING_MARK "MARK" - -#else /* SUPPORT_UNICODE */ - -/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This -works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode -only. */ - -#define CHAR_HT '\011' -#define CHAR_VT '\013' -#define CHAR_FF '\014' -#define CHAR_CR '\015' -#define CHAR_LF '\012' -#define CHAR_NL CHAR_LF -#define CHAR_NEL ((unsigned char)'\x85') -#define CHAR_BS '\010' -#define CHAR_BEL '\007' -#define CHAR_ESC '\033' -#define CHAR_DEL '\177' - -#define CHAR_NULL '\0' -#define CHAR_SPACE '\040' -#define CHAR_EXCLAMATION_MARK '\041' -#define CHAR_QUOTATION_MARK '\042' -#define CHAR_NUMBER_SIGN '\043' -#define CHAR_DOLLAR_SIGN '\044' -#define CHAR_PERCENT_SIGN '\045' -#define CHAR_AMPERSAND '\046' -#define CHAR_APOSTROPHE '\047' -#define CHAR_LEFT_PARENTHESIS '\050' -#define CHAR_RIGHT_PARENTHESIS '\051' -#define CHAR_ASTERISK '\052' -#define CHAR_PLUS '\053' -#define CHAR_COMMA '\054' -#define CHAR_MINUS '\055' -#define CHAR_DOT '\056' -#define CHAR_SLASH '\057' -#define CHAR_0 '\060' -#define CHAR_1 '\061' -#define CHAR_2 '\062' -#define CHAR_3 '\063' -#define CHAR_4 '\064' -#define CHAR_5 '\065' -#define CHAR_6 '\066' -#define CHAR_7 '\067' -#define CHAR_8 '\070' -#define CHAR_9 '\071' -#define CHAR_COLON '\072' -#define CHAR_SEMICOLON '\073' -#define CHAR_LESS_THAN_SIGN '\074' -#define CHAR_EQUALS_SIGN '\075' -#define CHAR_GREATER_THAN_SIGN '\076' -#define CHAR_QUESTION_MARK '\077' -#define CHAR_COMMERCIAL_AT '\100' -#define CHAR_A '\101' -#define CHAR_B '\102' -#define CHAR_C '\103' -#define CHAR_D '\104' -#define CHAR_E '\105' -#define CHAR_F '\106' -#define CHAR_G '\107' -#define CHAR_H '\110' -#define CHAR_I '\111' -#define CHAR_J '\112' -#define CHAR_K '\113' -#define CHAR_L '\114' -#define CHAR_M '\115' -#define CHAR_N '\116' -#define CHAR_O '\117' -#define CHAR_P '\120' -#define CHAR_Q '\121' -#define CHAR_R '\122' -#define CHAR_S '\123' -#define CHAR_T '\124' -#define CHAR_U '\125' -#define CHAR_V '\126' -#define CHAR_W '\127' -#define CHAR_X '\130' -#define CHAR_Y '\131' -#define CHAR_Z '\132' -#define CHAR_LEFT_SQUARE_BRACKET '\133' -#define CHAR_BACKSLASH '\134' -#define CHAR_RIGHT_SQUARE_BRACKET '\135' -#define CHAR_CIRCUMFLEX_ACCENT '\136' -#define CHAR_UNDERSCORE '\137' -#define CHAR_GRAVE_ACCENT '\140' -#define CHAR_a '\141' -#define CHAR_b '\142' -#define CHAR_c '\143' -#define CHAR_d '\144' -#define CHAR_e '\145' -#define CHAR_f '\146' -#define CHAR_g '\147' -#define CHAR_h '\150' -#define CHAR_i '\151' -#define CHAR_j '\152' -#define CHAR_k '\153' -#define CHAR_l '\154' -#define CHAR_m '\155' -#define CHAR_n '\156' -#define CHAR_o '\157' -#define CHAR_p '\160' -#define CHAR_q '\161' -#define CHAR_r '\162' -#define CHAR_s '\163' -#define CHAR_t '\164' -#define CHAR_u '\165' -#define CHAR_v '\166' -#define CHAR_w '\167' -#define CHAR_x '\170' -#define CHAR_y '\171' -#define CHAR_z '\172' -#define CHAR_LEFT_CURLY_BRACKET '\173' -#define CHAR_VERTICAL_LINE '\174' -#define CHAR_RIGHT_CURLY_BRACKET '\175' -#define CHAR_TILDE '\176' -#define CHAR_NBSP ((unsigned char)'\xa0') - -#define STR_HT "\011" -#define STR_VT "\013" -#define STR_FF "\014" -#define STR_CR "\015" -#define STR_NL "\012" -#define STR_BS "\010" -#define STR_BEL "\007" -#define STR_ESC "\033" -#define STR_DEL "\177" - -#define STR_SPACE "\040" -#define STR_EXCLAMATION_MARK "\041" -#define STR_QUOTATION_MARK "\042" -#define STR_NUMBER_SIGN "\043" -#define STR_DOLLAR_SIGN "\044" -#define STR_PERCENT_SIGN "\045" -#define STR_AMPERSAND "\046" -#define STR_APOSTROPHE "\047" -#define STR_LEFT_PARENTHESIS "\050" -#define STR_RIGHT_PARENTHESIS "\051" -#define STR_ASTERISK "\052" -#define STR_PLUS "\053" -#define STR_COMMA "\054" -#define STR_MINUS "\055" -#define STR_DOT "\056" -#define STR_SLASH "\057" -#define STR_0 "\060" -#define STR_1 "\061" -#define STR_2 "\062" -#define STR_3 "\063" -#define STR_4 "\064" -#define STR_5 "\065" -#define STR_6 "\066" -#define STR_7 "\067" -#define STR_8 "\070" -#define STR_9 "\071" -#define STR_COLON "\072" -#define STR_SEMICOLON "\073" -#define STR_LESS_THAN_SIGN "\074" -#define STR_EQUALS_SIGN "\075" -#define STR_GREATER_THAN_SIGN "\076" -#define STR_QUESTION_MARK "\077" -#define STR_COMMERCIAL_AT "\100" -#define STR_A "\101" -#define STR_B "\102" -#define STR_C "\103" -#define STR_D "\104" -#define STR_E "\105" -#define STR_F "\106" -#define STR_G "\107" -#define STR_H "\110" -#define STR_I "\111" -#define STR_J "\112" -#define STR_K "\113" -#define STR_L "\114" -#define STR_M "\115" -#define STR_N "\116" -#define STR_O "\117" -#define STR_P "\120" -#define STR_Q "\121" -#define STR_R "\122" -#define STR_S "\123" -#define STR_T "\124" -#define STR_U "\125" -#define STR_V "\126" -#define STR_W "\127" -#define STR_X "\130" -#define STR_Y "\131" -#define STR_Z "\132" -#define STR_LEFT_SQUARE_BRACKET "\133" -#define STR_BACKSLASH "\134" -#define STR_RIGHT_SQUARE_BRACKET "\135" -#define STR_CIRCUMFLEX_ACCENT "\136" -#define STR_UNDERSCORE "\137" -#define STR_GRAVE_ACCENT "\140" -#define STR_a "\141" -#define STR_b "\142" -#define STR_c "\143" -#define STR_d "\144" -#define STR_e "\145" -#define STR_f "\146" -#define STR_g "\147" -#define STR_h "\150" -#define STR_i "\151" -#define STR_j "\152" -#define STR_k "\153" -#define STR_l "\154" -#define STR_m "\155" -#define STR_n "\156" -#define STR_o "\157" -#define STR_p "\160" -#define STR_q "\161" -#define STR_r "\162" -#define STR_s "\163" -#define STR_t "\164" -#define STR_u "\165" -#define STR_v "\166" -#define STR_w "\167" -#define STR_x "\170" -#define STR_y "\171" -#define STR_z "\172" -#define STR_LEFT_CURLY_BRACKET "\173" -#define STR_VERTICAL_LINE "\174" -#define STR_RIGHT_CURLY_BRACKET "\175" -#define STR_TILDE "\176" - -#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" -#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" -#define STRING_F0 STR_F "\0" -#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" -#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" -#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" -#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" -#define STRING_THEN STR_T STR_H STR_E STR_N - -#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" -#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" -#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" -#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" -#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" -#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" -#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" -#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" -#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" -#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" -#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" -#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" -#define STRING_word0 STR_w STR_o STR_r STR_d "\0" -#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t - -#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E -#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N -#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET -#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET - -#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS -#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS -#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS -#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS -#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS -#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS -#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS -#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS -#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS -#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS -#define STRING_NO_JIT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS -#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS -#define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS -#define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS -#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN -#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN -#define STRING_MARK STR_M STR_A STR_R STR_K - -#endif /* SUPPORT_UNICODE */ - -/* -------------------- End of character and string names -------------------*/ - -/* -------------------- Definitions for compiled patterns -------------------*/ - -/* Codes for different types of Unicode property */ - -#define PT_ANY 0 /* Any property - matches all chars */ -#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ -#define PT_GC 2 /* Specified general characteristic (e.g. L) */ -#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ -#define PT_SC 4 /* Script (e.g. Han) */ -#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ -#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */ -#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ -#define PT_WORD 8 /* Word - L plus N plus underscore */ -#define PT_CLIST 9 /* Pseudo-property: match character list */ -#define PT_UCNC 10 /* Universal Character nameable character */ -#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */ - -/* The following special properties are used only in XCLASS items, when POSIX -classes are specified and PCRE_UCP is set - in other words, for Unicode -handling of these classes. They are not available via the \p or \P escapes like -those in the above list, and so they do not take part in the autopossessifying -table. */ - -#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */ -#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */ -#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */ - -/* Flag bits and data types for the extended class (OP_XCLASS) for classes that -contain characters with values greater than 255. */ - -#define XCL_NOT 0x01 /* Flag: this is a negative class */ -#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ -#define XCL_HASPROP 0x04 /* Flag: property checks are present. */ - -#define XCL_END 0 /* Marks end of individual items */ -#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ -#define XCL_RANGE 2 /* A range (two multibyte chars) follows */ -#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ -#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ - -/* Escape items that are just an encoding of a particular data value. These -appear in the escapes[] table in pcre2_compile.c as positive numbers. */ - -#ifndef ESC_a -#define ESC_a CHAR_BEL -#endif - -#ifndef ESC_e -#define ESC_e CHAR_ESC -#endif - -#ifndef ESC_f -#define ESC_f CHAR_FF -#endif - -#ifndef ESC_n -#define ESC_n CHAR_LF -#endif - -#ifndef ESC_r -#define ESC_r CHAR_CR -#endif - -/* We can't officially use ESC_t because it is a POSIX reserved identifier -(presumably because of all the others like size_t). */ - -#ifndef ESC_tee -#define ESC_tee CHAR_HT -#endif - -/* These are escaped items that aren't just an encoding of a particular data -value such as \n. They must have non-zero values, as check_escape() returns 0 -for a data character. In the escapes[] table in pcre2_compile.c their values -are negated in order to distinguish them from data values. - -They must appear here in the same order as in the opcode definitions below, up -to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL -mode rather than an escape sequence. It is also used for [^] in JavaScript -compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves -like \N. - -The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. -when PCRE_UCP is set and replacement of \d etc by \p sequences is required. -They must be contiguous, and remain in order so that the replacements can be -looked up from a table. - -Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in -check_escape(). There are two tests in the code for an escape -greater than ESC_b and less than ESC_Z to detect the types that may be -repeated. These are the types that consume characters. If any new escapes are -put in between that don't consume a character, that code will have to change. -*/ - -enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, - ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, - ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, - ESC_E, ESC_Q, ESC_g, ESC_k, - ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu }; - - -/********************** Opcode definitions ******************/ - -/****** NOTE NOTE NOTE ****** - -Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in -order to the list of escapes immediately above. Furthermore, values up to -OP_DOLLM must not be changed without adjusting the table called autoposstab in -pcre_compile.c - -Whenever this list is updated, the two macro definitions that follow must be -updated to match. The possessification table called "opcode_possessify" in -pcre_compile.c must also be updated, and also the tables called "coptable" -and "poptable" in pcre_dfa_exec.c. - -****** NOTE NOTE NOTE ******/ - - -/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive, -are used in a table for deciding whether a repeated character type can be -auto-possessified. */ - -#define FIRST_AUTOTAB_OP OP_NOT_DIGIT -#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI -#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM - -enum { - OP_END, /* 0 End of pattern */ - - /* Values corresponding to backslashed metacharacters */ - - OP_SOD, /* 1 Start of data: \A */ - OP_SOM, /* 2 Start of match (subject + offset): \G */ - OP_SET_SOM, /* 3 Set start of match (\K) */ - OP_NOT_WORD_BOUNDARY, /* 4 \B */ - OP_WORD_BOUNDARY, /* 5 \b */ - OP_NOT_DIGIT, /* 6 \D */ - OP_DIGIT, /* 7 \d */ - OP_NOT_WHITESPACE, /* 8 \S */ - OP_WHITESPACE, /* 9 \s */ - OP_NOT_WORDCHAR, /* 10 \W */ - OP_WORDCHAR, /* 11 \w */ - - OP_ANY, /* 12 Match any character except newline (\N) */ - OP_ALLANY, /* 13 Match any character */ - OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ - OP_NOTPROP, /* 15 \P (not Unicode property) */ - OP_PROP, /* 16 \p (Unicode property) */ - OP_ANYNL, /* 17 \R (any newline sequence) */ - OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */ - OP_HSPACE, /* 19 \h (horizontal whitespace) */ - OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */ - OP_VSPACE, /* 21 \v (vertical whitespace) */ - OP_EXTUNI, /* 22 \X (extended Unicode sequence */ - OP_EODN, /* 23 End of data or \n at end of data (\Z) */ - OP_EOD, /* 24 End of data (\z) */ - - /* Line end assertions */ - - OP_DOLL, /* 25 End of line - not multiline */ - OP_DOLLM, /* 26 End of line - multiline */ - OP_CIRC, /* 27 Start of line - not multiline */ - OP_CIRCM, /* 28 Start of line - multiline */ - - /* Single characters; caseful must precede the caseless ones */ - - OP_CHAR, /* 29 Match one character, casefully */ - OP_CHARI, /* 30 Match one character, caselessly */ - OP_NOT, /* 31 Match one character, not the given one, casefully */ - OP_NOTI, /* 32 Match one character, not the given one, caselessly */ - - /* The following sets of 13 opcodes must always be kept in step because - the offset from the first one is used to generate the others. */ - - /* Repeated characters; caseful must precede the caseless ones */ - - OP_STAR, /* 33 The maximizing and minimizing versions of */ - OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ - OP_PLUS, /* 35 the minimizing one second. */ - OP_MINPLUS, /* 36 */ - OP_QUERY, /* 37 */ - OP_MINQUERY, /* 38 */ - - OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/ - OP_MINUPTO, /* 40 */ - OP_EXACT, /* 41 Exactly n matches */ - - OP_POSSTAR, /* 42 Possessified star, caseful */ - OP_POSPLUS, /* 43 Possessified plus, caseful */ - OP_POSQUERY, /* 44 Posesssified query, caseful */ - OP_POSUPTO, /* 45 Possessified upto, caseful */ - - /* Repeated characters; caseless must follow the caseful ones */ - - OP_STARI, /* 46 */ - OP_MINSTARI, /* 47 */ - OP_PLUSI, /* 48 */ - OP_MINPLUSI, /* 49 */ - OP_QUERYI, /* 50 */ - OP_MINQUERYI, /* 51 */ - - OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */ - OP_MINUPTOI, /* 53 */ - OP_EXACTI, /* 54 */ - - OP_POSSTARI, /* 55 Possessified star, caseless */ - OP_POSPLUSI, /* 56 Possessified plus, caseless */ - OP_POSQUERYI, /* 57 Posesssified query, caseless */ - OP_POSUPTOI, /* 58 Possessified upto, caseless */ - - /* The negated ones must follow the non-negated ones, and match them */ - /* Negated repeated character, caseful; must precede the caseless ones */ - - OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ - OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ - OP_NOTPLUS, /* 61 the minimizing one second. They must be in */ - OP_NOTMINPLUS, /* 62 exactly the same order as those above. */ - OP_NOTQUERY, /* 63 */ - OP_NOTMINQUERY, /* 64 */ - - OP_NOTUPTO, /* 65 From 0 to n matches, caseful */ - OP_NOTMINUPTO, /* 66 */ - OP_NOTEXACT, /* 67 Exactly n matches */ - - OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */ - OP_NOTPOSPLUS, /* 69 */ - OP_NOTPOSQUERY, /* 70 */ - OP_NOTPOSUPTO, /* 71 */ - - /* Negated repeated character, caseless; must follow the caseful ones */ - - OP_NOTSTARI, /* 72 */ - OP_NOTMINSTARI, /* 73 */ - OP_NOTPLUSI, /* 74 */ - OP_NOTMINPLUSI, /* 75 */ - OP_NOTQUERYI, /* 76 */ - OP_NOTMINQUERYI, /* 77 */ - - OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */ - OP_NOTMINUPTOI, /* 79 */ - OP_NOTEXACTI, /* 80 Exactly n matches */ - - OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */ - OP_NOTPOSPLUSI, /* 82 */ - OP_NOTPOSQUERYI, /* 83 */ - OP_NOTPOSUPTOI, /* 84 */ - - /* Character types */ - - OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ - OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ - OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */ - OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */ - OP_TYPEQUERY, /* 89 */ - OP_TYPEMINQUERY, /* 90 */ - - OP_TYPEUPTO, /* 91 From 0 to n matches */ - OP_TYPEMINUPTO, /* 92 */ - OP_TYPEEXACT, /* 93 Exactly n matches */ - - OP_TYPEPOSSTAR, /* 94 Possessified versions */ - OP_TYPEPOSPLUS, /* 95 */ - OP_TYPEPOSQUERY, /* 96 */ - OP_TYPEPOSUPTO, /* 97 */ - - /* These are used for character classes and back references; only the - first six are the same as the sets above. */ - - OP_CRSTAR, /* 98 The maximizing and minimizing versions of */ - OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */ - OP_CRPLUS, /* 100 the minimizing one second. These codes must */ - OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */ - OP_CRQUERY, /* 102 */ - OP_CRMINQUERY, /* 103 */ - - OP_CRRANGE, /* 104 These are different to the three sets above. */ - OP_CRMINRANGE, /* 105 */ - - OP_CRPOSSTAR, /* 106 Possessified versions */ - OP_CRPOSPLUS, /* 107 */ - OP_CRPOSQUERY, /* 108 */ - OP_CRPOSRANGE, /* 109 */ - - /* End of quantifier opcodes */ - - OP_CLASS, /* 110 Match a character class, chars < 256 only */ - OP_NCLASS, /* 111 Same, but the bitmap was created from a negative - class - the difference is relevant only when a - character > 255 is encountered. */ - OP_XCLASS, /* 112 Extended class for handling > 255 chars within the - class. This does both positive and negative. */ - OP_REF, /* 113 Match a back reference, casefully */ - OP_REFI, /* 114 Match a back reference, caselessly */ - OP_DNREF, /* 115 Match a duplicate name backref, casefully */ - OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */ - OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 118 Call out to external function if provided */ - OP_CALLOUT_STR, /* 119 Call out with string argument */ - - OP_ALT, /* 120 Start of alternation */ - OP_KET, /* 121 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 122 These two must remain together and in this */ - OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */ - OP_KETRPOS, /* 124 Possessive unlimited repeat. */ - - /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four - asserts must remain in order. */ - - OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ - OP_ASSERT, /* 126 Positive lookahead */ - OP_ASSERT_NOT, /* 127 Negative lookahead */ - OP_ASSERTBACK, /* 128 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ - - /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately - after the assertions, with ONCE first, as there's a test for >= ONCE for a - subpattern that isn't an assertion. The POS versions must immediately follow - the non-POS versions in each case. */ - - OP_ONCE, /* 130 Atomic group, contains captures */ - OP_ONCE_NC, /* 131 Atomic group containing no captures */ - OP_BRA, /* 132 Start of non-capturing bracket */ - OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 134 Start of capturing bracket */ - OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 136 Conditional group */ - - /* These five must follow the previous five, in the same order. There's a - check for >= SBRA to distinguish the two sets. */ - - OP_SBRA, /* 137 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 139 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 141 Conditional group, check empty */ - - /* The next two pairs must (respectively) be kept together. */ - - OP_CREF, /* 142 Used to hold a capture number as condition */ - OP_DNCREF, /* 143 Used to point to duplicate names as a condition */ - OP_RREF, /* 144 Used to hold a recursion number as condition */ - OP_DNRREF, /* 145 Used to point to duplicate names as a condition */ - OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 147 Always true (used by VERSION) */ - - OP_BRAZERO, /* 148 These two must remain together and in this */ - OP_BRAMINZERO, /* 149 order. */ - OP_BRAPOSZERO, /* 150 */ - - /* These are backtracking control verbs */ - - OP_MARK, /* 151 always has an argument */ - OP_PRUNE, /* 152 */ - OP_PRUNE_ARG, /* 153 same, but with argument */ - OP_SKIP, /* 154 */ - OP_SKIP_ARG, /* 155 same, but with argument */ - OP_THEN, /* 156 */ - OP_THEN_ARG, /* 157 same, but with argument */ - OP_COMMIT, /* 158 */ - - /* These are forced failure and success verbs */ - - OP_FAIL, /* 159 */ - OP_ACCEPT, /* 160 */ - OP_ASSERT_ACCEPT, /* 161 Used inside assertions */ - OP_CLOSE, /* 162 Used before OP_ACCEPT to close open captures */ - - /* This is used to skip a subpattern with a {0} quantifier */ - - OP_SKIPZERO, /* 163 */ - - /* This is used to identify a DEFINE group during compilation so that it can - be checked for having only one branch. It is changed to OP_FALSE before - compilation finishes. */ - - OP_DEFINE, /* 164 */ - - /* This is not an opcode, but is used to check that tables indexed by opcode - are the correct length, in order to catch updating errors - there have been - some in the past. */ - - OP_TABLE_LENGTH - -}; - -/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro -definitions that follow must also be updated to match. There are also tables -called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in -pcre2_dfa_exec.c that must be updated. */ - - -/* This macro defines textual names for all the opcodes. These are used only -for debugging, and some of them are only partial names. The macro is referenced -only in pcre2_printint.c, which fills out the full names in many cases (and in -some cases doesn't actually use these names at all). */ - -#define OP_NAME_LIST \ - "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ - "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ - "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ - "extuni", "\\Z", "\\z", \ - "$", "$", "^", "^", "char", "chari", "not", "noti", \ - "*", "*?", "+", "+?", "?", "??", \ - "{", "{", "{", \ - "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", \ - "{", "{", "{", \ - "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", \ - "{", "{", "{", \ - "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", \ - "{", "{", "{", \ - "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ - "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", \ - "*+","++", "?+", "{", \ - "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ - "Recurse", "Callout", "CalloutStr", \ - "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ - "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ - "Once", "Once_NC", \ - "Bra", "BraPos", "CBra", "CBraPos", \ - "Cond", \ - "SBra", "SBraPos", "SCBra", "SCBraPos", \ - "SCond", \ - "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \ - "Cond false", "Cond true", \ - "Brazero", "Braminzero", "Braposzero", \ - "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ - "*THEN", "*THEN", "*COMMIT", "*FAIL", \ - "*ACCEPT", "*ASSERT_ACCEPT", \ - "Close", "Skip zero", "Define" - - -/* This macro defines the length of fixed length operations in the compiled -regex. The lengths are used when searching for specific things, and also in the -debugging printing of a compiled regex. We use a macro so that it can be -defined close to the definitions of the opcodes themselves. - -As things have been extended, some of these are no longer fixed lenths, but are -minima instead. For example, the length of a single-character repeat may vary -in UTF-8 mode. The code that uses this table must know about such things. */ - -#define OP_LENGTHS \ - 1, /* End */ \ - 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \ - 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \ - 1, 1, 1, /* Any, AllAny, Anybyte */ \ - 3, 3, /* \P, \p */ \ - 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ - 1, /* \X */ \ - 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \ - 2, /* Char - the minimum length */ \ - 2, /* Chari - the minimum length */ \ - 2, /* not */ \ - 2, /* noti */ \ - /* Positive single-char repeats ** These are */ \ - 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ - 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \ - 2+IMM2_SIZE, /* exact */ \ - 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \ - 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ - 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \ - 2+IMM2_SIZE, /* exact I */ \ - 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \ - /* Negative single-char repeats - only for chars < 256 */ \ - 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ - 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \ - 2+IMM2_SIZE, /* NOT exact */ \ - 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \ - 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ - 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \ - 2+IMM2_SIZE, /* NOT exact I */ \ - 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \ - /* Positive type repeats */ \ - 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ - 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \ - 2+IMM2_SIZE, /* Type exact */ \ - 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \ - /* Character class & ref repeats */ \ - 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ - 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ - 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \ - 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \ - 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \ - 0, /* XCLASS - variable length */ \ - 1+IMM2_SIZE, /* REF */ \ - 1+IMM2_SIZE, /* REFI */ \ - 1+2*IMM2_SIZE, /* DNREF */ \ - 1+2*IMM2_SIZE, /* DNREFI */ \ - 1+LINK_SIZE, /* RECURSE */ \ - 1+2*LINK_SIZE+1, /* CALLOUT */ \ - 0, /* CALLOUT_STR - variable length */ \ - 1+LINK_SIZE, /* Alt */ \ - 1+LINK_SIZE, /* Ket */ \ - 1+LINK_SIZE, /* KetRmax */ \ - 1+LINK_SIZE, /* KetRmin */ \ - 1+LINK_SIZE, /* KetRpos */ \ - 1+LINK_SIZE, /* Reverse */ \ - 1+LINK_SIZE, /* Assert */ \ - 1+LINK_SIZE, /* Assert not */ \ - 1+LINK_SIZE, /* Assert behind */ \ - 1+LINK_SIZE, /* Assert behind not */ \ - 1+LINK_SIZE, /* ONCE */ \ - 1+LINK_SIZE, /* ONCE_NC */ \ - 1+LINK_SIZE, /* BRA */ \ - 1+LINK_SIZE, /* BRAPOS */ \ - 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ - 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ - 1+LINK_SIZE, /* COND */ \ - 1+LINK_SIZE, /* SBRA */ \ - 1+LINK_SIZE, /* SBRAPOS */ \ - 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ - 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ - 1+LINK_SIZE, /* SCOND */ \ - 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \ - 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \ - 1, 1, /* FALSE, TRUE */ \ - 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ - 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ - 1, 3, /* SKIP, SKIP_ARG */ \ - 1, 3, /* THEN, THEN_ARG */ \ - 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ - 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \ - 1 /* DEFINE */ - -/* A magic value for OP_RREF to indicate the "any recursion" condition. */ - -#define RREF_ANY 0xffff - - -/* ---------- Private structures that are mode-independent. ---------- */ - -/* Structure to hold data for custom memory management. */ - -typedef struct pcre2_memctl { - void * (*malloc)(size_t, void *); - void (*free)(void *, void *); - void *memory_data; -} pcre2_memctl; - -/* Structure for building a chain of open capturing subpatterns during -compiling, so that instructions to close them can be compiled when (*ACCEPT) is -encountered. This is also used to identify subpatterns that contain recursive -back references to themselves, so that they can be made atomic. */ - -typedef struct open_capitem { - struct open_capitem *next; /* Chain link */ - uint16_t number; /* Capture number */ - uint16_t flag; /* Set TRUE if recursive back ref */ -} open_capitem; - -/* Layout of the UCP type table that translates property names into types and -codes. Each entry used to point directly to a name, but to reduce the number of -relocations in shared libraries, it now has an offset into a single string -instead. */ - -typedef struct { - uint16_t name_offset; - uint16_t type; - uint16_t value; -} ucp_type_table; - -/* Unicode character database (UCD) record format */ - -typedef struct { - uint8_t script; /* ucp_Arabic, etc. */ - uint8_t chartype; /* ucp_Cc, etc. (general categories) */ - uint8_t gbprop; /* ucp_gbControl, etc. (grapheme break property) */ - uint8_t caseset; /* offset to multichar other cases or zero */ - int32_t other_case; /* offset to other case, or zero if none */ -} ucd_record; - -/* UCD access macros */ - -#define UCD_BLOCK_SIZE 128 -#define GET_UCD(ch) (PRIV(ucd_records) + \ - PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \ - UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE]) - -#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype -#define UCD_SCRIPT(ch) GET_UCD(ch)->script -#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] -#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop -#define UCD_CASESET(ch) GET_UCD(ch)->caseset -#define UCD_OTHERCASE(ch) ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case))) - -/* Header for serialized pcre2 codes. */ - -typedef struct pcre2_serialized_data { - uint32_t magic; - uint32_t version; - uint32_t config; - int32_t number_of_codes; -} pcre2_serialized_data; - - - -/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */ - -/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as -0, so the following items are omitted. */ - -#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0 - -/* EBCDIC is supported only for the 8-bit library. */ - -#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8 -#error EBCDIC is not supported for the 16-bit or 32-bit libraries -#endif - -/* This is the largest non-UTF code point. */ - -#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH)) - -/* Internal shared data tables and variables. These are used by more than one -of the exported public functions. They have to be "external" in the C sense, -but are not part of the PCRE2 public API. Although the data for some of them is -identical in all libraries, they must have different names so that multiple -libraries can be simultaneously linked to a single application. However, UTF-8 -tables are needed only when compiling the 8-bit library. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -extern const int PRIV(utf8_table1)[]; -extern const int PRIV(utf8_table1_size); -extern const int PRIV(utf8_table2)[]; -extern const int PRIV(utf8_table3)[]; -extern const uint8_t PRIV(utf8_table4)[]; -#endif - -#define _pcre2_OP_lengths PCRE2_SUFFIX(_pcre2_OP_lengths_) -#define _pcre2_callout_end_delims PCRE2_SUFFIX(_pcre2_callout_end_delims_) -#define _pcre2_callout_start_delims PCRE2_SUFFIX(_pcre2_callout_start_delims_) -#define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_) -#define _pcre2_default_match_context PCRE2_SUFFIX(_pcre2_default_match_context_) -#define _pcre2_default_tables PCRE2_SUFFIX(_pcre2_default_tables_) -#define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_) -#define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) -#define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) -#define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_) -#define _pcre2_ucd_stage1 PCRE2_SUFFIX(_pcre2_ucd_stage1_) -#define _pcre2_ucd_stage2 PCRE2_SUFFIX(_pcre2_ucd_stage2_) -#define _pcre2_ucp_gbtable PCRE2_SUFFIX(_pcre2_ucp_gbtable_) -#define _pcre2_ucp_gentype PCRE2_SUFFIX(_pcre2_ucp_gentype_) -#define _pcre2_ucp_typerange PCRE2_SUFFIX(_pcre2_ucp_typerange_) -#define _pcre2_unicode_version PCRE2_SUFFIX(_pcre2_unicode_version_) -#define _pcre2_utt PCRE2_SUFFIX(_pcre2_utt_) -#define _pcre2_utt_names PCRE2_SUFFIX(_pcre2_utt_names_) -#define _pcre2_utt_size PCRE2_SUFFIX(_pcre2_utt_size_) - -extern const uint8_t PRIV(OP_lengths)[]; -extern const uint32_t PRIV(callout_end_delims)[]; -extern const uint32_t PRIV(callout_start_delims)[]; -extern const pcre2_compile_context PRIV(default_compile_context); -extern const pcre2_match_context PRIV(default_match_context); -extern const uint8_t PRIV(default_tables)[]; -extern const uint32_t PRIV(hspace_list)[]; -extern const uint32_t PRIV(vspace_list)[]; -extern const uint32_t PRIV(ucd_caseless_sets)[]; -extern const ucd_record PRIV(ucd_records)[]; -extern const uint8_t PRIV(ucd_stage1)[]; -extern const uint16_t PRIV(ucd_stage2)[]; -extern const uint32_t PRIV(ucp_gbtable)[]; -extern const uint32_t PRIV(ucp_gentype)[]; -#ifdef SUPPORT_JIT -extern const int PRIV(ucp_typerange)[]; -#endif -extern const char *PRIV(unicode_version); -extern const ucp_type_table PRIV(utt)[]; -extern const char PRIV(utt_names)[]; -extern const size_t PRIV(utt_size); - -/* Mode-dependent macros and hidden and private structures are defined in a -separate file so that pcre2test can include them at all supported widths. When -compiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can -include them at the appropriate width, after setting up suffix macros for the -private structures. */ - -#define branch_chain PCRE2_SUFFIX(branch_chain_) -#define compile_block PCRE2_SUFFIX(compile_block_) -#define dfa_match_block PCRE2_SUFFIX(dfa_match_block_) -#define match_block PCRE2_SUFFIX(match_block_) -#define named_group PCRE2_SUFFIX(named_group_) - -#include "pcre2_intmodedep.h" - -/* Private "external" functions. These are internal functions that are called -from modules other than the one in which they are defined. They have to be -"external" in the C sense, but are not part of the PCRE public API. They are -not referenced from pcre2test, and must not be defined when no code unit width -is available. */ - -#define _pcre2_auto_possessify PCRE2_SUFFIX(_pcre2_auto_possessify_) -#define _pcre2_check_escape PCRE2_SUFFIX(_pcre2_check_escape_) -#define _pcre2_find_bracket PCRE2_SUFFIX(_pcre2_find_bracket_) -#define _pcre2_is_newline PCRE2_SUFFIX(_pcre2_is_newline_) -#define _pcre2_jit_free_rodata PCRE2_SUFFIX(_pcre2_jit_free_rodata_) -#define _pcre2_jit_free PCRE2_SUFFIX(_pcre2_jit_free_) -#define _pcre2_jit_get_size PCRE2_SUFFIX(_pcre2_jit_get_size_) -#define _pcre2_jit_get_target PCRE2_SUFFIX(_pcre2_jit_get_target_) -#define _pcre2_memctl_malloc PCRE2_SUFFIX(_pcre2_memctl_malloc_) -#define _pcre2_ord2utf PCRE2_SUFFIX(_pcre2_ord2utf_) -#define _pcre2_strcmp PCRE2_SUFFIX(_pcre2_strcmp_) -#define _pcre2_strcmp_c8 PCRE2_SUFFIX(_pcre2_strcmp_c8_) -#define _pcre2_strcpy_c8 PCRE2_SUFFIX(_pcre2_strcpy_c8_) -#define _pcre2_strlen PCRE2_SUFFIX(_pcre2_strlen_) -#define _pcre2_strncmp PCRE2_SUFFIX(_pcre2_strncmp_) -#define _pcre2_strncmp_c8 PCRE2_SUFFIX(_pcre2_strncmp_c8_) -#define _pcre2_study PCRE2_SUFFIX(_pcre2_study_) -#define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_) -#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_) -#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_) - -extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL, - const compile_block *); -extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, - int *, uint32_t, BOOL, compile_block *); -extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int); -extern BOOL _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, - uint32_t *, BOOL); -extern void _pcre2_jit_free_rodata(void *, void *); -extern void _pcre2_jit_free(void *, pcre2_memctl *); -extern size_t _pcre2_jit_get_size(void *); -const char * _pcre2_jit_get_target(void); -extern void * _pcre2_memctl_malloc(size_t, pcre2_memctl *); -extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *); -extern int _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR); -extern int _pcre2_strcmp_c8(PCRE2_SPTR, const char *); -extern PCRE2_SIZE _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *); -extern PCRE2_SIZE _pcre2_strlen(PCRE2_SPTR); -extern int _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t); -extern int _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t); -extern int _pcre2_study(pcre2_real_code *); -extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *); -extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, - uint32_t *, BOOL); -extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL); -#endif /* PCRE2_CODE_UNIT_WIDTH */ - -/* End of pcre2_internal.h */ diff --git a/pcre2/src/pcre2_intmodedep.h b/pcre2/src/pcre2_intmodedep.h deleted file mode 100644 index 90b7959e0..000000000 --- a/pcre2/src/pcre2_intmodedep.h +++ /dev/null @@ -1,852 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains mode-dependent macro and structure definitions. The -file is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined. -These mode-dependent items are kept in a separate file so that they can also be -#included multiple times for different code unit widths by pcre2test in order -to have access to the hidden structures at all supported widths. - -Some of the mode-dependent macros are required at different widths for -different parts of the pcre2test code (in particular, the included -pcre_printint.c file). We undefine them here so that they can be re-defined for -multiple inclusions. Not all of these are used in pcre2test, but it's easier -just to undefine them all. */ - -#undef ACROSSCHAR -#undef BACKCHAR -#undef BYTES2CU -#undef CU2BYTES -#undef FORWARDCHAR -#undef FORWARDCHARTEST -#undef GET -#undef GET2 -#undef GETCHAR -#undef GETCHARINC -#undef GETCHARINCTEST -#undef GETCHARLEN -#undef GETCHARLENTEST -#undef GETCHARTEST -#undef GET_EXTRALEN -#undef HAS_EXTRALEN -#undef IMM2_SIZE -#undef MAX_255 -#undef MAX_MARK -#undef MAX_PATTERN_SIZE -#undef MAX_UTF_SINGLE_CU -#undef NOT_FIRSTCU -#undef PUT -#undef PUT2 -#undef PUT2INC -#undef PUTCHAR -#undef PUTINC -#undef TABLE_GET - - - -/* -------------------------- MACROS ----------------------------- */ - -/* PCRE keeps offsets in its compiled code as at least 16-bit quantities -(always stored in big-endian order in 8-bit mode) by default. These are used, -for example, to link from the start of a subpattern to its alternatives and its -end. The use of 16 bits per offset limits the size of an 8-bit compiled regex -to around 64K, which is big enough for almost everybody. However, I received a -request for an even bigger limit. For this reason, and also to make the code -easier to maintain, the storing and loading of offsets from the compiled code -unit string is now handled by the macros that are defined here. - -The macros are controlled by the value of LINK_SIZE. This defaults to 2, but -values of 2 or 4 are also supported. */ - -/* ------------------- 8-bit support ------------------ */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 - -#if LINK_SIZE == 2 -#define PUT(a,n,d) \ - (a[n] = (d) >> 8), \ - (a[(n)+1] = (d) & 255) -#define GET(a,n) \ - (((a)[n] << 8) | (a)[(n)+1]) -#define MAX_PATTERN_SIZE (1 << 16) - -#elif LINK_SIZE == 3 -#define PUT(a,n,d) \ - (a[n] = (d) >> 16), \ - (a[(n)+1] = (d) >> 8), \ - (a[(n)+2] = (d) & 255) -#define GET(a,n) \ - (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) -#define MAX_PATTERN_SIZE (1 << 24) - -#elif LINK_SIZE == 4 -#define PUT(a,n,d) \ - (a[n] = (d) >> 24), \ - (a[(n)+1] = (d) >> 16), \ - (a[(n)+2] = (d) >> 8), \ - (a[(n)+3] = (d) & 255) -#define GET(a,n) \ - (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) -#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ - -#else -#error LINK_SIZE must be 2, 3, or 4 -#endif - - -/* ------------------- 16-bit support ------------------ */ - -#elif PCRE2_CODE_UNIT_WIDTH == 16 - -#if LINK_SIZE == 2 -#undef LINK_SIZE -#define LINK_SIZE 1 -#define PUT(a,n,d) \ - (a[n] = (d)) -#define GET(a,n) \ - (a[n]) -#define MAX_PATTERN_SIZE (1 << 16) - -#elif LINK_SIZE == 3 || LINK_SIZE == 4 -#undef LINK_SIZE -#define LINK_SIZE 2 -#define PUT(a,n,d) \ - (a[n] = (d) >> 16), \ - (a[(n)+1] = (d) & 65535) -#define GET(a,n) \ - (((a)[n] << 16) | (a)[(n)+1]) -#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ - -#else -#error LINK_SIZE must be 2, 3, or 4 -#endif - - -/* ------------------- 32-bit support ------------------ */ - -#elif PCRE2_CODE_UNIT_WIDTH == 32 -#undef LINK_SIZE -#define LINK_SIZE 1 -#define PUT(a,n,d) \ - (a[n] = (d)) -#define GET(a,n) \ - (a[n]) -#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ - -#else -#error Unsupported compiling mode -#endif - - -/* --------------- Other mode-specific macros ----------------- */ - -/* PCRE uses some other (at least) 16-bit quantities that do not change when -the size of offsets changes. There are used for repeat counts and for other -things such as capturing parenthesis numbers in back references. - -Define the number of code units required to hold a 16-bit count/offset, and -macros to load and store such a value. For reasons that I do not understand, -the expression in the 8-bit GET2 macro is treated by gcc as a signed -expression, even when a is declared as unsigned. It seems that any kind of -arithmetic results in a signed value. Hence the cast. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define IMM2_SIZE 2 -#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1]) -#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255 - -#else /* Code units are 16 or 32 bits */ -#define IMM2_SIZE 1 -#define GET2(a,n) a[n] -#define PUT2(a,n,d) a[n] = d -#endif - -/* Other macros that are different for 8-bit mode. The MAX_255 macro checks -whether its argument is less than 256. The maximum length of a MARK name must -fit in one code unit; currently it is set to 255 or 65535. The TABLE_GET macro -is used to access elements of tables containing exactly 256 items. When code -points can be greater than 255, a check is needed before accessing these -tables. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define MAX_255(c) TRUE -#define MAX_MARK ((1u << 8) - 1) -#ifdef SUPPORT_UNICODE -#define SUPPORT_WIDE_CHARS -#endif /* SUPPORT_UNICODE */ -#define TABLE_GET(c, table, default) ((table)[c]) - -#else /* Code units are 16 or 32 bits */ -#define MAX_255(c) ((c) <= 255u) -#define MAX_MARK ((1u << 16) - 1) -#define SUPPORT_WIDE_CHARS -#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) -#endif - - - -/* ----------------- Character-handling macros ----------------- */ - -/* There is a proposed future special "UTF-21" mode, in which only the lowest -21 bits of a 32-bit character are interpreted as UTF, with the remaining 11 -high-order bits available to the application for other uses. In preparation for -the future implementation of this mode, there are macros that load a data item -and, if in this special mode, mask it to 21 bits. These macros all have names -starting with UCHAR21. In all other modes, including the normal 32-bit -library, the macros all have the same simple definitions. When the new mode is -implemented, it is expected that these definitions will be varied appropriately -using #ifdef when compiling the library that supports the special mode. */ - -#define UCHAR21(eptr) (*(eptr)) -#define UCHAR21TEST(eptr) (*(eptr)) -#define UCHAR21INC(eptr) (*(eptr)++) -#define UCHAR21INCTEST(eptr) (*(eptr)++) - -/* When UTF encoding is being used, a character is no longer just a single -byte in 8-bit mode or a single short in 16-bit mode. The macros for character -handling generate simple sequences when used in the basic mode, and more -complicated ones for UTF characters. GETCHARLENTEST and other macros are not -used when UTF is not supported. To make sure they can never even appear when -UTF support is omitted, we don't even define them. */ - -#ifndef SUPPORT_UNICODE - -/* #define MAX_UTF_SINGLE_CU */ -/* #define HAS_EXTRALEN(c) */ -/* #define GET_EXTRALEN(c) */ -/* #define NOT_FIRSTCU(c) */ -#define GETCHAR(c, eptr) c = *eptr; -#define GETCHARTEST(c, eptr) c = *eptr; -#define GETCHARINC(c, eptr) c = *eptr++; -#define GETCHARINCTEST(c, eptr) c = *eptr++; -#define GETCHARLEN(c, eptr, len) c = *eptr; -#define PUTCHAR(c, p) (*p = c, 1) -/* #define GETCHARLENTEST(c, eptr, len) */ -/* #define BACKCHAR(eptr) */ -/* #define FORWARDCHAR(eptr) */ -/* #define FORWARCCHARTEST(eptr,end) */ -/* #define ACROSSCHAR(condition, eptr, action) */ - -#else /* SUPPORT_UNICODE */ - -/* ------------------- 8-bit support ------------------ */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */ - -/* The largest UTF code point that can be encoded as a single code unit. */ - -#define MAX_UTF_SINGLE_CU 127 - -/* Tests whether the code point needs extra characters to decode. */ - -#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c) - -/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. -Otherwise it has an undefined behaviour. */ - -#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) - -/* Returns TRUE, if the given value is not the first code unit of a UTF -sequence. */ - -#define NOT_FIRSTCU(c) (((c) & 0xc0) == 0x80) - -/* Get the next UTF-8 character, not advancing the pointer. This is called when -we know we are in UTF-8 mode. */ - -#define GETCHAR(c, eptr) \ - c = *eptr; \ - if (c >= 0xc0) GETUTF8(c, eptr); - -/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the -pointer. */ - -#define GETCHARTEST(c, eptr) \ - c = *eptr; \ - if (utf && c >= 0xc0) GETUTF8(c, eptr); - -/* Get the next UTF-8 character, advancing the pointer. This is called when we -know we are in UTF-8 mode. */ - -#define GETCHARINC(c, eptr) \ - c = *eptr++; \ - if (c >= 0xc0) GETUTF8INC(c, eptr); - -/* Get the next character, testing for UTF-8 mode, and advancing the pointer. -This is called when we don't know if we are in UTF-8 mode. */ - -#define GETCHARINCTEST(c, eptr) \ - c = *eptr++; \ - if (utf && c >= 0xc0) GETUTF8INC(c, eptr); - -/* Get the next UTF-8 character, not advancing the pointer, incrementing length -if there are extra bytes. This is called when we know we are in UTF-8 mode. */ - -#define GETCHARLEN(c, eptr, len) \ - c = *eptr; \ - if (c >= 0xc0) GETUTF8LEN(c, eptr, len); - -/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the -pointer, incrementing length if there are extra bytes. This is called when we -do not know if we are in UTF-8 mode. */ - -#define GETCHARLENTEST(c, eptr, len) \ - c = *eptr; \ - if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); - -/* If the pointer is not at the start of a character, move it back until -it is. This is called only in UTF-8 mode - we don't put a test within the macro -because almost all calls are already within a block of UTF-8 only code. */ - -#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- - -/* Same as above, just in the other direction. */ -#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ -#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0) == 0x80) eptr++ - -/* Same as above, but it allows a fully customizable form. */ -#define ACROSSCHAR(condition, eptr, action) \ - while((condition) && ((eptr) & 0xc0) == 0x80) action - -/* Deposit a character into memory, returning the number of code units. */ - -#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \ - PRIV(ord2utf)(c,p) : (*p = c, 1)) - - -/* ------------------- 16-bit support ------------------ */ - -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */ - -/* The largest UTF code point that can be encoded as a single code unit. */ - -#define MAX_UTF_SINGLE_CU 65535 - -/* Tests whether the code point needs extra characters to decode. */ - -#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) - -/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. -Otherwise it has an undefined behaviour. */ - -#define GET_EXTRALEN(c) 1 - -/* Returns TRUE, if the given value is not the first code unit of a UTF -sequence. */ - -#define NOT_FIRSTCU(c) (((c) & 0xfc00) == 0xdc00) - -/* Base macro to pick up the low surrogate of a UTF-16 character, not -advancing the pointer. */ - -#define GETUTF16(c, eptr) \ - { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } - -/* Get the next UTF-16 character, not advancing the pointer. This is called when -we know we are in UTF-16 mode. */ - -#define GETCHAR(c, eptr) \ - c = *eptr; \ - if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); - -/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the -pointer. */ - -#define GETCHARTEST(c, eptr) \ - c = *eptr; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); - -/* Base macro to pick up the low surrogate of a UTF-16 character, advancing -the pointer. */ - -#define GETUTF16INC(c, eptr) \ - { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } - -/* Get the next UTF-16 character, advancing the pointer. This is called when we -know we are in UTF-16 mode. */ - -#define GETCHARINC(c, eptr) \ - c = *eptr++; \ - if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); - -/* Get the next character, testing for UTF-16 mode, and advancing the pointer. -This is called when we don't know if we are in UTF-16 mode. */ - -#define GETCHARINCTEST(c, eptr) \ - c = *eptr++; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); - -/* Base macro to pick up the low surrogate of a UTF-16 character, not -advancing the pointer, incrementing the length. */ - -#define GETUTF16LEN(c, eptr, len) \ - { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } - -/* Get the next UTF-16 character, not advancing the pointer, incrementing -length if there is a low surrogate. This is called when we know we are in -UTF-16 mode. */ - -#define GETCHARLEN(c, eptr, len) \ - c = *eptr; \ - if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); - -/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the -pointer, incrementing length if there is a low surrogate. This is called when -we do not know if we are in UTF-16 mode. */ - -#define GETCHARLENTEST(c, eptr, len) \ - c = *eptr; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); - -/* If the pointer is not at the start of a character, move it back until -it is. This is called only in UTF-16 mode - we don't put a test within the -macro because almost all calls are already within a block of UTF-16 only -code. */ - -#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- - -/* Same as above, just in the other direction. */ -#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ -#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00) == 0xdc00) eptr++ - -/* Same as above, but it allows a fully customizable form. */ -#define ACROSSCHAR(condition, eptr, action) \ - if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action - -/* Deposit a character into memory, returning the number of code units. */ - -#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \ - PRIV(ord2utf)(c,p) : (*p = c, 1)) - - -/* ------------------- 32-bit support ------------------ */ - -#else - -/* These are trivial for the 32-bit library, since all UTF-32 characters fit -into one PCRE2_UCHAR unit. */ - -#define MAX_UTF_SINGLE_CU (0x10ffffu) -#define HAS_EXTRALEN(c) (0) -#define GET_EXTRALEN(c) (0) -#define NOT_FIRSTCU(c) (0) - -/* Get the next UTF-32 character, not advancing the pointer. This is called when -we know we are in UTF-32 mode. */ - -#define GETCHAR(c, eptr) \ - c = *(eptr); - -/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the -pointer. */ - -#define GETCHARTEST(c, eptr) \ - c = *(eptr); - -/* Get the next UTF-32 character, advancing the pointer. This is called when we -know we are in UTF-32 mode. */ - -#define GETCHARINC(c, eptr) \ - c = *((eptr)++); - -/* Get the next character, testing for UTF-32 mode, and advancing the pointer. -This is called when we don't know if we are in UTF-32 mode. */ - -#define GETCHARINCTEST(c, eptr) \ - c = *((eptr)++); - -/* Get the next UTF-32 character, not advancing the pointer, not incrementing -length (since all UTF-32 is of length 1). This is called when we know we are in -UTF-32 mode. */ - -#define GETCHARLEN(c, eptr, len) \ - GETCHAR(c, eptr) - -/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the -pointer, not incrementing the length (since all UTF-32 is of length 1). -This is called when we do not know if we are in UTF-32 mode. */ - -#define GETCHARLENTEST(c, eptr, len) \ - GETCHARTEST(c, eptr) - -/* If the pointer is not at the start of a character, move it back until -it is. This is called only in UTF-32 mode - we don't put a test within the -macro because almost all calls are already within a block of UTF-32 only -code. - -These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */ - -#define BACKCHAR(eptr) do { } while (0) - -/* Same as above, just in the other direction. */ - -#define FORWARDCHAR(eptr) do { } while (0) -#define FORWARDCHARTEST(eptr,end) do { } while (0) - -/* Same as above, but it allows a fully customizable form. */ - -#define ACROSSCHAR(condition, eptr, action) do { } while (0) - -/* Deposit a character into memory, returning the number of code units. */ - -#define PUTCHAR(c, p) (*p = c, 1) - -#endif /* UTF-32 character handling */ -#endif /* SUPPORT_UNICODE */ - - -/* Mode-dependent macros that have the same definition in all modes. */ - -#define CU2BYTES(x) ((x)*((PCRE2_CODE_UNIT_WIDTH/8))) -#define BYTES2CU(x) ((x)/((PCRE2_CODE_UNIT_WIDTH/8))) -#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE -#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE - - -/* ----------------------- HIDDEN STRUCTURES ----------------------------- */ - -/* NOTE: All these structures *must* start with a pcre2_memctl structure. The -code that uses them is simpler because it assumes this. */ - -/* The real general context structure. At present it holds only data for custom -memory control. */ - -typedef struct pcre2_real_general_context { - pcre2_memctl memctl; -} pcre2_real_general_context; - -/* The real compile context structure */ - -typedef struct pcre2_real_compile_context { - pcre2_memctl memctl; - int (*stack_guard)(uint32_t, void *); - void *stack_guard_data; - const uint8_t *tables; - PCRE2_SIZE max_pattern_length; - uint16_t bsr_convention; - uint16_t newline_convention; - uint32_t parens_nest_limit; -} pcre2_real_compile_context; - -/* The real match context structure. */ - -typedef struct pcre2_real_match_context { - pcre2_memctl memctl; -#ifdef HEAP_MATCH_RECURSE - pcre2_memctl stack_memctl; -#endif -#ifdef SUPPORT_JIT - pcre2_jit_callback jit_callback; - void *jit_callback_data; -#endif - int (*callout)(pcre2_callout_block *, void *); - void *callout_data; - PCRE2_SIZE offset_limit; - uint32_t match_limit; - uint32_t recursion_limit; -} pcre2_real_match_context; - -/* The real compiled code structure. The type for the blocksize field is -defined specially because it is required in pcre2_serialize_decode() when -copying the size from possibly unaligned memory into a variable of the same -type. Use a macro rather than a typedef to avoid compiler warnings when this -file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the -largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit -argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field -here.) */ - -#undef CODE_BLOCKSIZE_TYPE -#define CODE_BLOCKSIZE_TYPE size_t - -#undef LOOKBEHIND_MAX -#define LOOKBEHIND_MAX UINT16_MAX - -typedef struct pcre2_real_code { - pcre2_memctl memctl; /* Memory control fields */ - const uint8_t *tables; /* The character tables */ - void *executable_jit; /* Pointer to JIT code */ - uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */ - CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */ - uint32_t magic_number; /* Paranoid and endianness check */ - uint32_t compile_options; /* Options passed to pcre2_compile() */ - uint32_t overall_options; /* Options after processing the pattern */ - uint32_t flags; /* Various state flags */ - uint32_t limit_match; /* Limit set in the pattern */ - uint32_t limit_recursion; /* Limit set in the pattern */ - uint32_t first_codeunit; /* Starting code unit */ - uint32_t last_codeunit; /* This codeunit must be seen */ - uint16_t bsr_convention; /* What \R matches */ - uint16_t newline_convention; /* What is a newline? */ - uint16_t max_lookbehind; /* Longest lookbehind (characters) */ - uint16_t minlength; /* Minimum length of match */ - uint16_t top_bracket; /* Highest numbered group */ - uint16_t top_backref; /* Highest numbered back reference */ - uint16_t name_entry_size; /* Size (code units) of table entries */ - uint16_t name_count; /* Number of name entries in the table */ -} pcre2_real_code; - -/* The real match data structure. */ - -typedef struct pcre2_real_match_data { - pcre2_memctl memctl; - const pcre2_real_code *code; /* The pattern used for the match */ - PCRE2_SPTR subject; /* The subject that was matched */ - PCRE2_SPTR mark; /* Pointer to last mark */ - PCRE2_SIZE leftchar; /* Offset to leftmost code unit */ - PCRE2_SIZE rightchar; /* Offset to rightmost code unit */ - PCRE2_SIZE startchar; /* Offset to starting code unit */ - uint16_t matchedby; /* Type of match (normal, JIT, DFA) */ - uint16_t oveccount; /* Number of pairs */ - int rc; /* The return code from the match */ - PCRE2_SIZE ovector[1]; /* The first field */ -} pcre2_real_match_data; - - -/* ----------------------- PRIVATE STRUCTURES ----------------------------- */ - -/* These structures are not needed for pcre2test. */ - -#ifndef PCRE2_PCRE2TEST - -/* Structure for checking for mutual recursion when scanning compiled code. */ - -typedef struct recurse_check { - struct recurse_check *prev; - PCRE2_SPTR group; -} recurse_check; - -/* Structure for building a cache when filling in recursion offsets. */ - -typedef struct recurse_cache { - PCRE2_SPTR group; - int recno; -} recurse_cache; - -/* Structure for maintaining a chain of pointers to the currently incomplete -branches, for testing for left recursion while compiling. */ - -typedef struct branch_chain { - struct branch_chain *outer; - PCRE2_UCHAR *current_branch; -} branch_chain; - -/* Structure for building a list of named groups during the first pass of -compiling. */ - -typedef struct named_group { - PCRE2_SPTR name; /* Points to the name in the pattern */ - uint32_t number; /* Group number */ - uint16_t length; /* Length of the name */ - uint16_t isdup; /* TRUE if a duplicate */ -} named_group; - -/* Structure for passing "static" information around between the functions -doing the compiling, so that they are thread-safe. */ - -typedef struct compile_block { - pcre2_real_compile_context *cx; /* Points to the compile context */ - const uint8_t *lcc; /* Points to lower casing table */ - const uint8_t *fcc; /* Points to case-flipping table */ - const uint8_t *cbits; /* Points to character type table */ - const uint8_t *ctypes; /* Points to table of type maps */ - PCRE2_SPTR start_workspace; /* The start of working space */ - PCRE2_SPTR start_code; /* The start of the compiled code */ - PCRE2_SPTR start_pattern; /* The start of the pattern */ - PCRE2_SPTR end_pattern; /* The end of the pattern */ - PCRE2_SPTR nestptr[2]; /* Pointer(s) saved for string substitution */ - PCRE2_UCHAR *name_table; /* The name/number table */ - size_t workspace_size; /* Size of workspace */ - uint16_t names_found; /* Number of entries so far */ - uint16_t name_entry_size; /* Size of each entry */ - open_capitem *open_caps; /* Chain of open capture items */ - named_group *named_groups; /* Points to vector in pre-compile */ - uint32_t named_group_list_size; /* Number of entries in the list */ - uint32_t external_options; /* External (initial) options */ - uint32_t external_flags; /* External flag bits to be set */ - uint32_t bracount; /* Count of capturing parens as we compile */ - uint32_t final_bracount; /* Saved value after first pass */ - uint32_t *groupinfo; /* Group info vector */ - uint32_t top_backref; /* Maximum back reference */ - uint32_t backref_map; /* Bitmap of low back refs */ - uint32_t nltype; /* Newline type */ - uint32_t nllen; /* Newline string length */ - PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ - int max_lookbehind; /* Maximum lookbehind (characters) */ - int parens_depth; /* Depth of nested parentheses */ - int assert_depth; /* Depth of nested assertions */ - int req_varyopt; /* "After variable item" flag for reqbyte */ - BOOL had_accept; /* (*ACCEPT) encountered */ - BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ - BOOL had_recurse; /* Had a recursion or subroutine call */ - BOOL check_lookbehind; /* Lookbehinds need later checking */ - BOOL dupnames; /* Duplicate names exist */ - BOOL iscondassert; /* Next assert is a condition */ -} compile_block; - -/* Structure for keeping the properties of the in-memory stack used -by the JIT matcher. */ - -typedef struct pcre2_real_jit_stack { - pcre2_memctl memctl; - void* stack; -} pcre2_real_jit_stack; - -/* Structure for keeping a chain of heap blocks used for saving ovectors -during pattern recursion when the ovector is larger than can be saved on -the system stack. */ - -typedef struct ovecsave_frame { - struct ovecsave_frame *next; /* Next frame on free chain */ - PCRE2_SIZE saved_ovec[1]; /* First vector element */ -} ovecsave_frame; - -/* Structure for items in a linked list that represents an explicit recursive -call within the pattern; used by pcre_match(). */ - -typedef struct recursion_info { - struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ - unsigned int group_num; /* Number of group that was called */ - PCRE2_SIZE *ovec_save; /* Pointer to saved ovector frame */ - uint32_t saved_capture_last; /* Last capture number */ - PCRE2_SPTR subject_position; /* Position at start of recursion */ -} recursion_info; - -/* A similar structure for pcre_dfa_match(). */ - -typedef struct dfa_recursion_info { - struct dfa_recursion_info *prevrec; - PCRE2_SPTR subject_position; - uint32_t group_num; -} dfa_recursion_info; - -/* Structure for building a chain of data for holding the values of the subject -pointer at the start of each subpattern, so as to detect when an empty string -has been matched by a subpattern - to break infinite loops; used by -pcre2_match(). */ - -typedef struct eptrblock { - struct eptrblock *epb_prev; - PCRE2_SPTR epb_saved_eptr; -} eptrblock; - -/* Structure for passing "static" information around between the functions -doing traditional NFA matching (pcre2_match() and friends). */ - -typedef struct match_block { - pcre2_memctl memctl; /* For general use */ -#ifdef HEAP_MATCH_RECURSE - pcre2_memctl stack_memctl; /* For "stack" frames */ -#endif - uint32_t match_call_count; /* As it says */ - uint32_t match_limit; /* As it says */ - uint32_t match_limit_recursion; /* As it says */ - BOOL hitend; /* Hit the end of the subject at some point */ - BOOL hasthen; /* Pattern contains (*THEN) */ - const uint8_t *lcc; /* Points to lower casing table */ - const uint8_t *fcc; /* Points to case-flipping table */ - const uint8_t *ctypes; /* Points to table of type maps */ - PCRE2_SIZE *ovector; /* Pointer to the offset vector */ - PCRE2_SIZE offset_end; /* One past the end */ - PCRE2_SIZE offset_max; /* The maximum usable for return data */ - PCRE2_SIZE start_offset; /* The start offset value */ - PCRE2_SIZE end_offset_top; /* Highwater mark at end of match */ - uint16_t partial; /* PARTIAL options */ - uint16_t bsr_convention; /* \R interpretation */ - uint16_t name_count; /* Number of names in name table */ - uint16_t name_entry_size; /* Size of entry in names table */ - PCRE2_SPTR name_table; /* Table of group names */ - PCRE2_SPTR start_code; /* For use when recursing */ - PCRE2_SPTR start_subject; /* Start of the subject string */ - PCRE2_SPTR end_subject; /* End of the subject string */ - PCRE2_SPTR start_match_ptr; /* Start of matched string */ - PCRE2_SPTR end_match_ptr; /* Subject position at end match */ - PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ - PCRE2_SPTR last_used_ptr; /* Latest consulted character */ - PCRE2_SPTR mark; /* Mark pointer to pass back on success */ - PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */ - PCRE2_SPTR once_target; /* Where to back up to for atomic groups */ - uint32_t moptions; /* Match options */ - uint32_t poptions; /* Pattern options */ - uint32_t capture_last; /* Most recent capture number + overflow flag */ - uint32_t skip_arg_count; /* For counting SKIP_ARGs */ - uint32_t ignore_skip_arg; /* For re-run when SKIP arg name not found */ - uint32_t match_function_type; /* Set for certain special calls of match() */ - uint32_t nltype; /* Newline type */ - uint32_t nllen; /* Newline string length */ - PCRE2_UCHAR nl[4]; /* Newline string when fixed */ - eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ - recursion_info *recursive; /* Linked list of recursion data */ - ovecsave_frame *ovecsave_chain; /* Linked list of free ovecsave blocks */ - void *callout_data; /* To pass back to callouts */ - int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ -#ifdef HEAP_MATCH_RECURSE - void *match_frames_base; /* For remembering malloc'd frames */ -#endif -} match_block; - -/* A similar structure is used for the same purpose by the DFA matching -functions. */ - -typedef struct dfa_match_block { - pcre2_memctl memctl; /* For general use */ - PCRE2_SPTR start_code; /* Start of the compiled pattern */ - PCRE2_SPTR start_subject ; /* Start of the subject string */ - PCRE2_SPTR end_subject; /* End of subject string */ - PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ - PCRE2_SPTR last_used_ptr; /* Latest consulted character */ - const uint8_t *tables; /* Character tables */ - PCRE2_SIZE start_offset; /* The start offset value */ - uint32_t moptions; /* Match options */ - uint32_t poptions; /* Pattern options */ - uint32_t nltype; /* Newline type */ - uint32_t nllen; /* Newline string length */ - PCRE2_UCHAR nl[4]; /* Newline string when fixed */ - uint16_t bsr_convention; /* \R interpretation */ - void *callout_data; /* To pass back to callouts */ - int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ - dfa_recursion_info *recursive; /* Linked list of recursion data */ -} dfa_match_block; - -#endif /* PCRE2_PCRE2TEST */ - -/* End of pcre2_intmodedep.h */ diff --git a/pcre2/src/pcre2_jit_compile.c b/pcre2/src/pcre2_jit_compile.c deleted file mode 100644 index b46f4e394..000000000 --- a/pcre2/src/pcre2_jit_compile.c +++ /dev/null @@ -1,11503 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - -#ifdef SUPPORT_JIT - -/* All-in-one: Since we use the JIT compiler only from here, -we just include it. This way we don't need to touch the build -system files. */ - -#define SLJIT_CONFIG_AUTO 1 -#define SLJIT_CONFIG_STATIC 1 -#define SLJIT_VERBOSE 0 - -#ifdef PCRE2_DEBUG -#define SLJIT_DEBUG 1 -#else -#define SLJIT_DEBUG 0 -#endif - -#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data) -#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data) - -static void * pcre2_jit_malloc(size_t size, void *allocator_data) -{ -pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data); -return allocator->malloc(size, allocator->memory_data); -} - -static void pcre2_jit_free(void *ptr, void *allocator_data) -{ -pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data); -allocator->free(ptr, allocator->memory_data); -} - -#include "sljit/sljitLir.c" - -#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED -#error Unsupported architecture -#endif - -/* Defines for debugging purposes. */ - -/* 1 - Use unoptimized capturing brackets. - 2 - Enable capture_last_ptr (includes option 1). */ -/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */ - -/* 1 - Always have a control head. */ -/* #define DEBUG_FORCE_CONTROL_HEAD 1 */ - -/* Allocate memory for the regex stack on the real machine stack. -Fast, but limited size. */ -#define MACHINE_STACK_SIZE 32768 - -/* Growth rate for stack allocated by the OS. Should be the multiply -of page size. */ -#define STACK_GROWTH_RATE 8192 - -/* Enable to check that the allocation could destroy temporaries. */ -#if defined SLJIT_DEBUG && SLJIT_DEBUG -#define DESTROY_REGISTERS 1 -#endif - -/* -Short summary about the backtracking mechanism empolyed by the jit code generator: - -The code generator follows the recursive nature of the PERL compatible regular -expressions. The basic blocks of regular expressions are condition checkers -whose execute different commands depending on the result of the condition check. -The relationship between the operators can be horizontal (concatenation) and -vertical (sub-expression) (See struct backtrack_common for more details). - - 'ab' - 'a' and 'b' regexps are concatenated - 'a+' - 'a' is the sub-expression of the '+' operator - -The condition checkers are boolean (true/false) checkers. Machine code is generated -for the checker itself and for the actions depending on the result of the checker. -The 'true' case is called as the matching path (expected path), and the other is called as -the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken -branches on the matching path. - - Greedy star operator (*) : - Matching path: match happens. - Backtrack path: match failed. - Non-greedy star operator (*?) : - Matching path: no need to perform a match. - Backtrack path: match is required. - -The following example shows how the code generated for a capturing bracket -with two alternatives. Let A, B, C, D are arbirary regular expressions, and -we have the following regular expression: - - A(B|C)D - -The generated code will be the following: - - A matching path - '(' matching path (pushing arguments to the stack) - B matching path - ')' matching path (pushing arguments to the stack) - D matching path - return with successful match - - D backtrack path - ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") - B backtrack path - C expected path - jump to D matching path - C backtrack path - A backtrack path - - Notice, that the order of backtrack code paths are the opposite of the fast - code paths. In this way the topmost value on the stack is always belong - to the current backtrack code path. The backtrack path must check - whether there is a next alternative. If so, it needs to jump back to - the matching path eventually. Otherwise it needs to clear out its own stack - frame and continue the execution on the backtrack code paths. -*/ - -/* -Saved stack frames: - -Atomic blocks and asserts require reloading the values of private data -when the backtrack mechanism performed. Because of OP_RECURSE, the data -are not necessarly known in compile time, thus we need a dynamic restore -mechanism. - -The stack frames are stored in a chain list, and have the following format: -([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] - -Thus we can restore the private data to a particular point in the stack. -*/ - -typedef struct jit_arguments { - /* Pointers first. */ - struct sljit_stack *stack; - PCRE2_SPTR str; - PCRE2_SPTR begin; - PCRE2_SPTR end; - pcre2_match_data *match_data; - PCRE2_SPTR startchar_ptr; - PCRE2_UCHAR *mark_ptr; - int (*callout)(pcre2_callout_block *, void *); - void *callout_data; - /* Everything else after. */ - sljit_uw offset_limit; - sljit_ui limit_match; - uint32_t oveccount; - uint32_t options; -} jit_arguments; - -#define JIT_NUMBER_OF_COMPILE_MODES 3 - -typedef struct executable_functions { - void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; - void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES]; - sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; - sljit_ui top_bracket; - sljit_ui limit_match; -} executable_functions; - -typedef struct jump_list { - struct sljit_jump *jump; - struct jump_list *next; -} jump_list; - -typedef struct stub_list { - struct sljit_jump *start; - struct sljit_label *quit; - struct stub_list *next; -} stub_list; - -typedef struct label_addr_list { - struct sljit_label *label; - sljit_uw *update_addr; - struct label_addr_list *next; -} label_addr_list; - -enum frame_types { - no_frame = -1, - no_stack = -2 -}; - -enum control_types { - type_mark = 0, - type_then_trap = 1 -}; - -typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); - -/* The following structure is the key data type for the recursive -code generator. It is allocated by compile_matchingpath, and contains -the arguments for compile_backtrackingpath. Must be the first member -of its descendants. */ -typedef struct backtrack_common { - /* Concatenation stack. */ - struct backtrack_common *prev; - jump_list *nextbacktracks; - /* Internal stack (for component operators). */ - struct backtrack_common *top; - jump_list *topbacktracks; - /* Opcode pointer. */ - PCRE2_SPTR cc; -} backtrack_common; - -typedef struct assert_backtrack { - backtrack_common common; - jump_list *condfailed; - /* Less than 0 if a frame is not needed. */ - int framesize; - /* Points to our private memory word on the stack. */ - int private_data_ptr; - /* For iterators. */ - struct sljit_label *matchingpath; -} assert_backtrack; - -typedef struct bracket_backtrack { - backtrack_common common; - /* Where to coninue if an alternative is successfully matched. */ - struct sljit_label *alternative_matchingpath; - /* For rmin and rmax iterators. */ - struct sljit_label *recursive_matchingpath; - /* For greedy ? operator. */ - struct sljit_label *zero_matchingpath; - /* Contains the branches of a failed condition. */ - union { - /* Both for OP_COND, OP_SCOND. */ - jump_list *condfailed; - assert_backtrack *assert; - /* For OP_ONCE. Less than 0 if not needed. */ - int framesize; - } u; - /* Points to our private memory word on the stack. */ - int private_data_ptr; -} bracket_backtrack; - -typedef struct bracketpos_backtrack { - backtrack_common common; - /* Points to our private memory word on the stack. */ - int private_data_ptr; - /* Reverting stack is needed. */ - int framesize; - /* Allocated stack size. */ - int stacksize; -} bracketpos_backtrack; - -typedef struct braminzero_backtrack { - backtrack_common common; - struct sljit_label *matchingpath; -} braminzero_backtrack; - -typedef struct char_iterator_backtrack { - backtrack_common common; - /* Next iteration. */ - struct sljit_label *matchingpath; - union { - jump_list *backtracks; - struct { - unsigned int othercasebit; - PCRE2_UCHAR chr; - BOOL enabled; - } charpos; - } u; -} char_iterator_backtrack; - -typedef struct ref_iterator_backtrack { - backtrack_common common; - /* Next iteration. */ - struct sljit_label *matchingpath; -} ref_iterator_backtrack; - -typedef struct recurse_entry { - struct recurse_entry *next; - /* Contains the function entry. */ - struct sljit_label *entry; - /* Collects the calls until the function is not created. */ - jump_list *calls; - /* Points to the starting opcode. */ - sljit_sw start; -} recurse_entry; - -typedef struct recurse_backtrack { - backtrack_common common; - BOOL inlined_pattern; -} recurse_backtrack; - -#define OP_THEN_TRAP OP_TABLE_LENGTH - -typedef struct then_trap_backtrack { - backtrack_common common; - /* If then_trap is not NULL, this structure contains the real - then_trap for the backtracking path. */ - struct then_trap_backtrack *then_trap; - /* Points to the starting opcode. */ - sljit_sw start; - /* Exit point for the then opcodes of this alternative. */ - jump_list *quit; - /* Frame size of the current alternative. */ - int framesize; -} then_trap_backtrack; - -#define MAX_RANGE_SIZE 4 - -typedef struct compiler_common { - /* The sljit ceneric compiler. */ - struct sljit_compiler *compiler; - /* First byte code. */ - PCRE2_SPTR start; - /* Maps private data offset to each opcode. */ - sljit_si *private_data_ptrs; - /* Chain list of read-only data ptrs. */ - void *read_only_data_head; - /* Tells whether the capturing bracket is optimized. */ - sljit_ub *optimized_cbracket; - /* Tells whether the starting offset is a target of then. */ - sljit_ub *then_offsets; - /* Current position where a THEN must jump. */ - then_trap_backtrack *then_trap; - /* Starting offset of private data for capturing brackets. */ - sljit_si cbra_ptr; - /* Output vector starting point. Must be divisible by 2. */ - sljit_si ovector_start; - /* Points to the starting character of the current match. */ - sljit_si start_ptr; - /* Last known position of the requested byte. */ - sljit_si req_char_ptr; - /* Head of the last recursion. */ - sljit_si recursive_head_ptr; - /* First inspected character for partial matching. - (Needed for avoiding zero length partial matches.) */ - sljit_si start_used_ptr; - /* Starting pointer for partial soft matches. */ - sljit_si hit_start; - /* Pointer of the match end position. */ - sljit_si match_end_ptr; - /* Points to the marked string. */ - sljit_si mark_ptr; - /* Recursive control verb management chain. */ - sljit_si control_head_ptr; - /* Points to the last matched capture block index. */ - sljit_si capture_last_ptr; - /* Fast forward skipping byte code pointer. */ - PCRE2_SPTR fast_forward_bc_ptr; - /* Locals used by fast fail optimization. */ - sljit_si fast_fail_start_ptr; - sljit_si fast_fail_end_ptr; - - /* Flipped and lower case tables. */ - const sljit_ub *fcc; - sljit_sw lcc; - /* Mode can be PCRE2_JIT_COMPLETE and others. */ - int mode; - /* TRUE, when minlength is greater than 0. */ - BOOL might_be_empty; - /* \K is found in the pattern. */ - BOOL has_set_som; - /* (*SKIP:arg) is found in the pattern. */ - BOOL has_skip_arg; - /* (*THEN) is found in the pattern. */ - BOOL has_then; - /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */ - BOOL has_skip_in_assert_back; - /* Currently in recurse or negative assert. */ - BOOL local_exit; - /* Currently in a positive assert. */ - BOOL positive_assert; - /* Newline control. */ - int nltype; - sljit_ui nlmax; - sljit_ui nlmin; - int newline; - int bsr_nltype; - sljit_ui bsr_nlmax; - sljit_ui bsr_nlmin; - /* Dollar endonly. */ - int endonly; - /* Tables. */ - sljit_sw ctypes; - /* Named capturing brackets. */ - PCRE2_SPTR name_table; - sljit_sw name_count; - sljit_sw name_entry_size; - - /* Labels and jump lists. */ - struct sljit_label *partialmatchlabel; - struct sljit_label *quit_label; - struct sljit_label *forced_quit_label; - struct sljit_label *accept_label; - struct sljit_label *ff_newline_shortcut; - stub_list *stubs; - label_addr_list *label_addrs; - recurse_entry *entries; - recurse_entry *currententry; - jump_list *partialmatch; - jump_list *quit; - jump_list *positive_assert_quit; - jump_list *forced_quit; - jump_list *accept; - jump_list *calllimit; - jump_list *stackalloc; - jump_list *revertframes; - jump_list *wordboundary; - jump_list *anynewline; - jump_list *hspace; - jump_list *vspace; - jump_list *casefulcmp; - jump_list *caselesscmp; - jump_list *reset_match; - BOOL unset_backref; - BOOL alt_circumflex; -#ifdef SUPPORT_UNICODE - BOOL utf; - BOOL use_ucp; - jump_list *getucd; -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump_list *utfreadchar; - jump_list *utfreadchar16; - jump_list *utfreadtype8; -#endif -#endif /* SUPPORT_UNICODE */ -} compiler_common; - -/* For byte_sequence_compare. */ - -typedef struct compare_context { - int length; - int sourcereg; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - int ucharptr; - union { - sljit_si asint; - sljit_uh asushort; -#if PCRE2_CODE_UNIT_WIDTH == 8 - sljit_ub asbyte; - sljit_ub asuchars[4]; -#elif PCRE2_CODE_UNIT_WIDTH == 16 - sljit_uh asuchars[2]; -#elif PCRE2_CODE_UNIT_WIDTH == 32 - sljit_ui asuchars[1]; -#endif - } c; - union { - sljit_si asint; - sljit_uh asushort; -#if PCRE2_CODE_UNIT_WIDTH == 8 - sljit_ub asbyte; - sljit_ub asuchars[4]; -#elif PCRE2_CODE_UNIT_WIDTH == 16 - sljit_uh asuchars[2]; -#elif PCRE2_CODE_UNIT_WIDTH == 32 - sljit_ui asuchars[1]; -#endif - } oc; -#endif -} compare_context; - -/* Undefine sljit macros. */ -#undef CMP - -/* Used for accessing the elements of the stack. */ -#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw)) - -#define TMP1 SLJIT_R0 -#define TMP2 SLJIT_R2 -#define TMP3 SLJIT_R3 -#define STR_PTR SLJIT_S0 -#define STR_END SLJIT_S1 -#define STACK_TOP SLJIT_R1 -#define STACK_LIMIT SLJIT_S2 -#define COUNT_MATCH SLJIT_S3 -#define ARGUMENTS SLJIT_S4 -#define RETURN_ADDR SLJIT_R4 - -/* Local space layout. */ -/* These two locals can be used by the current opcode. */ -#define LOCALS0 (0 * sizeof(sljit_sw)) -#define LOCALS1 (1 * sizeof(sljit_sw)) -/* Two local variables for possessive quantifiers (char1 cannot use them). */ -#define POSSESSIVE0 (2 * sizeof(sljit_sw)) -#define POSSESSIVE1 (3 * sizeof(sljit_sw)) -/* Max limit of recursions. */ -#define LIMIT_MATCH (4 * sizeof(sljit_sw)) -/* The output vector is stored on the stack, and contains pointers -to characters. The vector data is divided into two groups: the first -group contains the start / end character pointers, and the second is -the start pointers when the end of the capturing group has not yet reached. */ -#define OVECTOR_START (common->ovector_start) -#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw)) -#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw)) -#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define MOV_UCHAR SLJIT_MOV_UB -#define MOVU_UCHAR SLJIT_MOVU_UB -#define IN_UCHARS(x) (x) -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#define MOV_UCHAR SLJIT_MOV_UH -#define MOVU_UCHAR SLJIT_MOVU_UH -#define UCHAR_SHIFT (1) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) -#elif PCRE2_CODE_UNIT_WIDTH == 32 -#define MOV_UCHAR SLJIT_MOV_UI -#define MOVU_UCHAR SLJIT_MOVU_UI -#define UCHAR_SHIFT (2) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) -#else -#error Unsupported compiling mode -#endif - -/* Shortcuts. */ -#define DEFINE_COMPILER \ - struct sljit_compiler *compiler = common->compiler -#define OP1(op, dst, dstw, src, srcw) \ - sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) -#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ - sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) -#define LABEL() \ - sljit_emit_label(compiler) -#define JUMP(type) \ - sljit_emit_jump(compiler, (type)) -#define JUMPTO(type, label) \ - sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) -#define JUMPHERE(jump) \ - sljit_set_label((jump), sljit_emit_label(compiler)) -#define SET_LABEL(jump, label) \ - sljit_set_label((jump), (label)) -#define CMP(type, src1, src1w, src2, src2w) \ - sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) -#define CMPTO(type, src1, src1w, src2, src2w, label) \ - sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) -#define OP_FLAGS(op, dst, dstw, src, srcw, type) \ - sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type)) -#define GET_LOCAL_BASE(dst, dstw, offset) \ - sljit_get_local_base(compiler, (dst), (dstw), (offset)) - -#define READ_CHAR_MAX 0x7fffffff - -static PCRE2_SPTR bracketend(PCRE2_SPTR cc) -{ -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); -do cc += GET(cc, 1); while (*cc == OP_ALT); -SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); -cc += 1 + LINK_SIZE; -return cc; -} - -static int no_alternatives(PCRE2_SPTR cc) -{ -int count = 0; -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); -do - { - cc += GET(cc, 1); - count++; - } -while (*cc == OP_ALT); -SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); -return count; -} - -/* Functions whose might need modification for all new supported opcodes: - next_opcode - check_opcode_types - set_private_data_ptrs - get_framesize - init_frame - get_private_data_copy_length - copy_private_data - compile_matchingpath - compile_backtrackingpath -*/ - -static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc) -{ -SLJIT_UNUSED_ARG(common); -switch(*cc) - { - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_NOTPROP: - case OP_PROP: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_EXTUNI: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - case OP_CRPOSRANGE: - case OP_CLASS: - case OP_NCLASS: - case OP_REF: - case OP_REFI: - case OP_DNREF: - case OP_DNREFI: - case OP_RECURSE: - case OP_CALLOUT: - case OP_ALT: - case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - case OP_REVERSE: - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRA: - case OP_BRAPOS: - case OP_CBRA: - case OP_CBRAPOS: - case OP_COND: - case OP_SBRA: - case OP_SBRAPOS: - case OP_SCBRA: - case OP_SCBRAPOS: - case OP_SCOND: - case OP_CREF: - case OP_DNCREF: - case OP_RREF: - case OP_DNRREF: - case OP_FALSE: - case OP_TRUE: - case OP_BRAZERO: - case OP_BRAMINZERO: - case OP_BRAPOSZERO: - case OP_PRUNE: - case OP_SKIP: - case OP_THEN: - case OP_COMMIT: - case OP_FAIL: - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - case OP_CLOSE: - case OP_SKIPZERO: - return cc + PRIV(OP_lengths)[*cc]; - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_UPTO: - case OP_MINUPTO: - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - cc += PRIV(OP_lengths)[*cc]; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - return cc; - - /* Special cases. */ - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSUPTO: - return cc + PRIV(OP_lengths)[*cc] - 1; - - case OP_ANYBYTE: -#ifdef SUPPORT_UNICODE - if (common->utf) return NULL; -#endif - return cc + 1; - - case OP_CALLOUT_STR: - return cc + GET(cc, 1 + 2*LINK_SIZE); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - return cc + GET(cc, 1); -#endif - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - return cc + 1 + 2 + cc[1]; - - default: - /* All opcodes are supported now! */ - SLJIT_ASSERT_STOP(); - return NULL; - } -} - -static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend) -{ -int count; -PCRE2_SPTR slot; -PCRE2_SPTR assert_back_end = cc - 1; - -/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ -while (cc < ccend) - { - switch(*cc) - { - case OP_SET_SOM: - common->has_set_som = TRUE; - common->might_be_empty = TRUE; - cc += 1; - break; - - case OP_REF: - case OP_REFI: - common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += 1 + IMM2_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_COND: - case OP_SCOND: - /* Only AUTO_CALLOUT can insert this opcode. We do - not intend to support this case. */ - if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR) - return FALSE; - cc += 1 + LINK_SIZE; - break; - - case OP_CREF: - common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += 1 + IMM2_SIZE; - break; - - case OP_DNREF: - case OP_DNREFI: - case OP_DNCREF: - count = GET2(cc, 1 + IMM2_SIZE); - slot = common->name_table + GET2(cc, 1) * common->name_entry_size; - while (count-- > 0) - { - common->optimized_cbracket[GET2(slot, 0)] = 0; - slot += common->name_entry_size; - } - cc += 1 + 2 * IMM2_SIZE; - break; - - case OP_RECURSE: - /* Set its value only once. */ - if (common->recursive_head_ptr == 0) - { - common->recursive_head_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - cc += 1 + LINK_SIZE; - break; - - case OP_CALLOUT: - case OP_CALLOUT_STR: - if (common->capture_last_ptr == 0) - { - common->capture_last_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE); - break; - - case OP_ASSERTBACK: - slot = bracketend(cc); - if (slot > assert_back_end) - assert_back_end = slot; - cc += 1 + LINK_SIZE; - break; - - case OP_THEN_ARG: - common->has_then = TRUE; - common->control_head_ptr = 1; - /* Fall through. */ - - case OP_PRUNE_ARG: - case OP_MARK: - if (common->mark_ptr == 0) - { - common->mark_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - cc += 1 + 2 + cc[1]; - break; - - case OP_THEN: - common->has_then = TRUE; - common->control_head_ptr = 1; - cc += 1; - break; - - case OP_SKIP: - if (cc < assert_back_end) - common->has_skip_in_assert_back = TRUE; - cc += 1; - break; - - case OP_SKIP_ARG: - common->control_head_ptr = 1; - common->has_skip_arg = TRUE; - if (cc < assert_back_end) - common->has_skip_in_assert_back = TRUE; - cc += 1 + 2 + cc[1]; - break; - - default: - cc = next_opcode(common, cc); - if (cc == NULL) - return FALSE; - break; - } - } -return TRUE; -} - -static BOOL is_accelerated_repeat(PCRE2_SPTR cc) -{ -switch(*cc) - { - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI); - - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSSTAR: - case OP_POSPLUS: - - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSSTARI: - case OP_POSPLUSI: - - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - return TRUE; - - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR))); -#else - cc += (1 + (32 / sizeof(PCRE2_UCHAR))); -#endif - - switch(*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - return TRUE; - } - break; - } -return FALSE; -} - -static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start) -{ -PCRE2_SPTR cc = common->start; -PCRE2_SPTR end; - -/* Skip not repeated brackets. */ -while (TRUE) - { - switch(*cc) - { - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; - continue; - } - - if (*cc != OP_BRA && *cc != OP_CBRA) - break; - - end = cc + GET(cc, 1); - if (*end != OP_KET || PRIVATE_DATA(end) != 0) - return FALSE; - if (*cc == OP_CBRA) - { - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - return FALSE; - cc += IMM2_SIZE; - } - cc += 1 + LINK_SIZE; - } - -if (is_accelerated_repeat(cc)) - { - common->fast_forward_bc_ptr = cc; - common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; - *private_data_start += sizeof(sljit_sw); - return TRUE; - } -return FALSE; -} - -static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_si depth) -{ - PCRE2_SPTR next_alt; - - SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA); - - if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - return; - - next_alt = bracketend(cc) - (1 + LINK_SIZE); - if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0) - return; - - do - { - next_alt = cc + GET(cc, 1); - - cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0); - - while (TRUE) - { - switch(*cc) - { - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; - continue; - } - break; - } - - if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA)) - detect_fast_fail(common, cc, private_data_start, depth - 1); - - if (is_accelerated_repeat(cc)) - { - common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; - - if (common->fast_fail_start_ptr == 0) - common->fast_fail_start_ptr = *private_data_start; - - *private_data_start += sizeof(sljit_sw); - common->fast_fail_end_ptr = *private_data_start; - - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return; - } - - cc = next_alt; - } - while (*cc == OP_ALT); -} - -static int get_class_iterator_size(PCRE2_SPTR cc) -{ -sljit_ui min; -sljit_ui max; -switch(*cc) - { - case OP_CRSTAR: - case OP_CRPLUS: - return 2; - - case OP_CRMINSTAR: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - return 1; - - case OP_CRRANGE: - case OP_CRMINRANGE: - min = GET2(cc, 1); - max = GET2(cc, 1 + IMM2_SIZE); - if (max == 0) - return (*cc == OP_CRRANGE) ? 2 : 1; - max -= min; - if (max > 2) - max = 2; - return max; - - default: - return 0; - } -} - -static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin) -{ -PCRE2_SPTR end = bracketend(begin); -PCRE2_SPTR next; -PCRE2_SPTR next_end; -PCRE2_SPTR max_end; -PCRE2_UCHAR type; -sljit_sw length = end - begin; -sljit_si min, max, i; - -/* Detect fixed iterations first. */ -if (end[-(1 + LINK_SIZE)] != OP_KET) - return FALSE; - -/* Already detected repeat. */ -if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0) - return TRUE; - -next = end; -min = 1; -while (1) - { - if (*next != *begin) - break; - next_end = bracketend(next); - if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0) - break; - next = next_end; - min++; - } - -if (min == 2) - return FALSE; - -max = 0; -max_end = next; -if (*next == OP_BRAZERO || *next == OP_BRAMINZERO) - { - type = *next; - while (1) - { - if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin) - break; - next_end = bracketend(next + 2 + LINK_SIZE); - if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0) - break; - next = next_end; - max++; - } - - if (next[0] == type && next[1] == *begin && max >= 1) - { - next_end = bracketend(next + 1); - if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0) - { - for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE) - if (*next_end != OP_KET) - break; - - if (i == max) - { - common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end; - common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO; - /* +2 the original and the last. */ - common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2; - if (min == 1) - return TRUE; - min--; - max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE); - } - } - } - } - -if (min >= 3) - { - common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end; - common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT; - common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min; - return TRUE; - } - -return FALSE; -} - -#define CASE_ITERATOR_PRIVATE_DATA_1 \ - case OP_MINSTAR: \ - case OP_MINPLUS: \ - case OP_QUERY: \ - case OP_MINQUERY: \ - case OP_MINSTARI: \ - case OP_MINPLUSI: \ - case OP_QUERYI: \ - case OP_MINQUERYI: \ - case OP_NOTMINSTAR: \ - case OP_NOTMINPLUS: \ - case OP_NOTQUERY: \ - case OP_NOTMINQUERY: \ - case OP_NOTMINSTARI: \ - case OP_NOTMINPLUSI: \ - case OP_NOTQUERYI: \ - case OP_NOTMINQUERYI: - -#define CASE_ITERATOR_PRIVATE_DATA_2A \ - case OP_STAR: \ - case OP_PLUS: \ - case OP_STARI: \ - case OP_PLUSI: \ - case OP_NOTSTAR: \ - case OP_NOTPLUS: \ - case OP_NOTSTARI: \ - case OP_NOTPLUSI: - -#define CASE_ITERATOR_PRIVATE_DATA_2B \ - case OP_UPTO: \ - case OP_MINUPTO: \ - case OP_UPTOI: \ - case OP_MINUPTOI: \ - case OP_NOTUPTO: \ - case OP_NOTMINUPTO: \ - case OP_NOTUPTOI: \ - case OP_NOTMINUPTOI: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ - case OP_TYPEMINSTAR: \ - case OP_TYPEMINPLUS: \ - case OP_TYPEQUERY: \ - case OP_TYPEMINQUERY: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ - case OP_TYPESTAR: \ - case OP_TYPEPLUS: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ - case OP_TYPEUPTO: \ - case OP_TYPEMINUPTO: - -static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend) -{ -PCRE2_SPTR cc = common->start; -PCRE2_SPTR alternative; -PCRE2_SPTR end = NULL; -int private_data_ptr = *private_data_start; -int space, size, bracketlen; -BOOL repeat_check = TRUE; - -while (cc < ccend) - { - space = 0; - size = 0; - bracketlen = 0; - if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) - break; - - if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)) - { - if (detect_repeat(common, cc)) - { - /* These brackets are converted to repeats, so no global - based single character repeat is allowed. */ - if (cc >= end) - end = bracketend(cc); - } - } - repeat_check = TRUE; - - switch(*cc) - { - case OP_KET: - if (common->private_data_ptrs[cc + 1 - common->start] != 0) - { - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - cc += common->private_data_ptrs[cc + 1 - common->start]; - } - cc += 1 + LINK_SIZE; - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRAPOS: - case OP_SBRA: - case OP_SBRAPOS: - case OP_SCOND: - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_COND: - /* Might be a hidden SCOND. */ - alternative = cc + GET(cc, 1); - if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - { - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - } - bracketlen = 1 + LINK_SIZE; - break; - - case OP_BRA: - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_BRAZERO: - case OP_BRAMINZERO: - case OP_BRAPOSZERO: - repeat_check = FALSE; - size = 1; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - space = 1; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - space = 2; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - space = 2; - size = -(2 + IMM2_SIZE); - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - space = 1; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) - space = 2; - size = 1; - break; - - case OP_TYPEUPTO: - if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) - space = 2; - size = 1 + IMM2_SIZE; - break; - - case OP_TYPEMINUPTO: - space = 2; - size = 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: - size = 1 + 32 / sizeof(PCRE2_UCHAR); - space = get_class_iterator_size(cc + size); - break; - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - size = GET(cc, 1); - space = get_class_iterator_size(cc + size); - break; -#endif - - default: - cc = next_opcode(common, cc); - SLJIT_ASSERT(cc != NULL); - break; - } - - /* Character iterators, which are not inside a repeated bracket, - gets a private slot instead of allocating it on the stack. */ - if (space > 0 && cc >= end) - { - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw) * space; - } - - if (size != 0) - { - if (size < 0) - { - cc += -size; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - } - else - cc += size; - } - - if (bracketlen > 0) - { - if (cc >= end) - { - end = bracketend(cc); - if (end[-1 - LINK_SIZE] == OP_KET) - end = NULL; - } - cc += bracketlen; - } - } -*private_data_start = private_data_ptr; -} - -/* Returns with a frame_types (always < 0) if no need for frame. */ -static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head) -{ -int length = 0; -int possessive = 0; -BOOL stack_restore = FALSE; -BOOL setsom_found = recursive; -BOOL setmark_found = recursive; -/* The last capture is a local variable even for recursions. */ -BOOL capture_last_found = FALSE; - -#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD -SLJIT_ASSERT(common->control_head_ptr != 0); -*needs_control_head = TRUE; -#else -*needs_control_head = FALSE; -#endif - -if (ccend == NULL) - { - ccend = bracketend(cc) - (1 + LINK_SIZE); - if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) - { - possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; - /* This is correct regardless of common->capture_last_ptr. */ - capture_last_found = TRUE; - } - cc = next_opcode(common, cc); - } - -SLJIT_ASSERT(cc != NULL); -while (cc < ccend) - switch(*cc) - { - case OP_SET_SOM: - SLJIT_ASSERT(common->has_set_som); - stack_restore = TRUE; - if (!setsom_found) - { - length += 2; - setsom_found = TRUE; - } - cc += 1; - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_THEN_ARG: - SLJIT_ASSERT(common->mark_ptr != 0); - stack_restore = TRUE; - if (!setmark_found) - { - length += 2; - setmark_found = TRUE; - } - if (common->control_head_ptr != 0) - *needs_control_head = TRUE; - cc += 1 + 2 + cc[1]; - break; - - case OP_RECURSE: - stack_restore = TRUE; - if (common->has_set_som && !setsom_found) - { - length += 2; - setsom_found = TRUE; - } - if (common->mark_ptr != 0 && !setmark_found) - { - length += 2; - setmark_found = TRUE; - } - if (common->capture_last_ptr != 0 && !capture_last_found) - { - length += 2; - capture_last_found = TRUE; - } - cc += 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_CBRAPOS: - case OP_SCBRA: - case OP_SCBRAPOS: - stack_restore = TRUE; - if (common->capture_last_ptr != 0 && !capture_last_found) - { - length += 2; - capture_last_found = TRUE; - } - length += 3; - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_THEN: - stack_restore = TRUE; - if (common->control_head_ptr != 0) - *needs_control_head = TRUE; - cc ++; - break; - - default: - stack_restore = TRUE; - /* Fall through. */ - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: - case OP_NOTPROP: - case OP_PROP: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_EXTUNI: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - - case OP_TYPEEXACT: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSUPTO: - - case OP_CLASS: - case OP_NCLASS: - case OP_XCLASS: - - case OP_CALLOUT: - case OP_CALLOUT_STR: - - cc = next_opcode(common, cc); - SLJIT_ASSERT(cc != NULL); - break; - } - -/* Possessive quantifiers can use a special case. */ -if (SLJIT_UNLIKELY(possessive == length)) - return stack_restore ? no_frame : no_stack; - -if (length > 0) - return length + 1; -return stack_restore ? no_frame : no_stack; -} - -static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop, BOOL recursive) -{ -DEFINE_COMPILER; -BOOL setsom_found = recursive; -BOOL setmark_found = recursive; -/* The last capture is a local variable even for recursions. */ -BOOL capture_last_found = FALSE; -int offset; - -/* >= 1 + shortest item size (2) */ -SLJIT_UNUSED_ARG(stacktop); -SLJIT_ASSERT(stackpos >= stacktop + 2); - -stackpos = STACK(stackpos); -if (ccend == NULL) - { - ccend = bracketend(cc) - (1 + LINK_SIZE); - if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) - cc = next_opcode(common, cc); - } - -SLJIT_ASSERT(cc != NULL); -while (cc < ccend) - switch(*cc) - { - case OP_SET_SOM: - SLJIT_ASSERT(common->has_set_som); - if (!setsom_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - setsom_found = TRUE; - } - cc += 1; - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_THEN_ARG: - SLJIT_ASSERT(common->mark_ptr != 0); - if (!setmark_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - setmark_found = TRUE; - } - cc += 1 + 2 + cc[1]; - break; - - case OP_RECURSE: - if (common->has_set_som && !setsom_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - setsom_found = TRUE; - } - if (common->mark_ptr != 0 && !setmark_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - setmark_found = TRUE; - } - if (common->capture_last_ptr != 0 && !capture_last_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - capture_last_found = TRUE; - } - cc += 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_CBRAPOS: - case OP_SCBRA: - case OP_SCBRAPOS: - if (common->capture_last_ptr != 0 && !capture_last_found) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - capture_last_found = TRUE; - } - offset = (GET2(cc, 1 + LINK_SIZE)) << 1; - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); - stackpos += (int)sizeof(sljit_sw); - - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - default: - cc = next_opcode(common, cc); - SLJIT_ASSERT(cc != NULL); - break; - } - -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0); -SLJIT_ASSERT(stackpos == STACK(stacktop)); -} - -static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL needs_control_head) -{ -int private_data_length = needs_control_head ? 3 : 2; -int size; -PCRE2_SPTR alternative; -/* Calculate the sum of the private machine words. */ -while (cc < ccend) - { - size = 0; - switch(*cc) - { - case OP_KET: - if (PRIVATE_DATA(cc) != 0) - { - private_data_length++; - SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); - cc += PRIVATE_DATA(cc + 1); - } - cc += 1 + LINK_SIZE; - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRAPOS: - case OP_SBRA: - case OP_SBRAPOS: - case OP_SCOND: - private_data_length++; - SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); - cc += 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - private_data_length++; - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - private_data_length += 2; - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_COND: - /* Might be a hidden SCOND. */ - alternative = cc + GET(cc, 1); - if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - private_data_length++; - cc += 1 + LINK_SIZE; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - private_data_length++; - cc += 2; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 2; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - private_data_length++; - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); -#else - size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); -#endif - if (PRIVATE_DATA(cc)) - private_data_length += get_class_iterator_size(cc + size); - cc += size; - break; - - default: - cc = next_opcode(common, cc); - SLJIT_ASSERT(cc != NULL); - break; - } - } -SLJIT_ASSERT(cc == ccend); -return private_data_length; -} - -static void copy_private_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, - BOOL save, int stackptr, int stacktop, BOOL needs_control_head) -{ -DEFINE_COMPILER; -int srcw[2]; -int count, size; -BOOL tmp1next = TRUE; -BOOL tmp1empty = TRUE; -BOOL tmp2empty = TRUE; -PCRE2_SPTR alternative; -enum { - start, - loop, - end -} status; - -status = save ? start : loop; -stackptr = STACK(stackptr - 2); -stacktop = STACK(stacktop - 1); - -if (!save) - { - stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw); - if (stackptr < stacktop) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); - tmp1empty = FALSE; - } - if (stackptr < stacktop) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); - tmp2empty = FALSE; - } - /* The tmp1next must be TRUE in either way. */ - } - -do - { - count = 0; - switch(status) - { - case start: - SLJIT_ASSERT(save && common->recursive_head_ptr != 0); - count = 1; - srcw[0] = common->recursive_head_ptr; - if (needs_control_head) - { - SLJIT_ASSERT(common->control_head_ptr != 0); - count = 2; - srcw[1] = common->control_head_ptr; - } - status = loop; - break; - - case loop: - if (cc >= ccend) - { - status = end; - break; - } - - switch(*cc) - { - case OP_KET: - if (PRIVATE_DATA(cc) != 0) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); - cc += PRIVATE_DATA(cc + 1); - } - cc += 1 + LINK_SIZE; - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRAPOS: - case OP_SBRA: - case OP_SBRAPOS: - case OP_SCOND: - count = 1; - srcw[0] = PRIVATE_DATA(cc); - SLJIT_ASSERT(srcw[0] != 0); - cc += 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - { - count = 1; - srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); - } - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); - SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0); - cc += 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_COND: - /* Might be a hidden SCOND. */ - alternative = cc + GET(cc, 1); - if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - SLJIT_ASSERT(srcw[0] != 0); - } - cc += 1 + LINK_SIZE; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - } - cc += 2; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); - } - cc += 2; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); - } - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - } - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - } - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - } - cc += 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); -#else - size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); -#endif - if (PRIVATE_DATA(cc)) - switch(get_class_iterator_size(cc + size)) - { - case 1: - count = 1; - srcw[0] = PRIVATE_DATA(cc); - break; - - case 2: - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - cc += size; - break; - - default: - cc = next_opcode(common, cc); - SLJIT_ASSERT(cc != NULL); - break; - } - break; - - case end: - SLJIT_ASSERT_STOP(); - break; - } - - while (count > 0) - { - count--; - if (save) - { - if (tmp1next) - { - if (!tmp1empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); - } - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); - tmp1empty = FALSE; - tmp1next = FALSE; - } - else - { - if (!tmp2empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); - } - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); - tmp2empty = FALSE; - tmp1next = TRUE; - } - } - else - { - if (tmp1next) - { - SLJIT_ASSERT(!tmp1empty); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0); - tmp1empty = stackptr >= stacktop; - if (!tmp1empty) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); - } - tmp1next = FALSE; - } - else - { - SLJIT_ASSERT(!tmp2empty); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0); - tmp2empty = stackptr >= stacktop; - if (!tmp2empty) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); - } - tmp1next = TRUE; - } - } - } - } -while (status != end); - -if (save) - { - if (tmp1next) - { - if (!tmp1empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); - } - if (!tmp2empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); - } - } - else - { - if (!tmp2empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); - } - if (!tmp1empty) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); - } - } - } -SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); -} - -static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_ub *current_offset) -{ -PCRE2_SPTR end = bracketend(cc); -BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; - -/* Assert captures then. */ -if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) - current_offset = NULL; -/* Conditional block does not. */ -if (*cc == OP_COND || *cc == OP_SCOND) - has_alternatives = FALSE; - -cc = next_opcode(common, cc); -if (has_alternatives) - current_offset = common->then_offsets + (cc - common->start); - -while (cc < end) - { - if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) - cc = set_then_offsets(common, cc, current_offset); - else - { - if (*cc == OP_ALT && has_alternatives) - current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); - if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) - *current_offset = 1; - cc = next_opcode(common, cc); - } - } - -return end; -} - -#undef CASE_ITERATOR_PRIVATE_DATA_1 -#undef CASE_ITERATOR_PRIVATE_DATA_2A -#undef CASE_ITERATOR_PRIVATE_DATA_2B -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1 -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - -static SLJIT_INLINE BOOL is_powerof2(unsigned int value) -{ -return (value & (value - 1)) == 0; -} - -static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) -{ -while (list) - { - /* sljit_set_label is clever enough to do nothing - if either the jump or the label is NULL. */ - SET_LABEL(list->jump, label); - list = list->next; - } -} - -static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump) -{ -jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); -if (list_item) - { - list_item->next = *list; - list_item->jump = jump; - *list = list_item; - } -} - -static void add_stub(compiler_common *common, struct sljit_jump *start) -{ -DEFINE_COMPILER; -stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); - -if (list_item) - { - list_item->start = start; - list_item->quit = LABEL(); - list_item->next = common->stubs; - common->stubs = list_item; - } -} - -static void flush_stubs(compiler_common *common) -{ -DEFINE_COMPILER; -stub_list *list_item = common->stubs; - -while (list_item) - { - JUMPHERE(list_item->start); - add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); - JUMPTO(SLJIT_JUMP, list_item->quit); - list_item = list_item->next; - } -common->stubs = NULL; -} - -static void add_label_addr(compiler_common *common, sljit_uw *update_addr) -{ -DEFINE_COMPILER; -label_addr_list *label_addr; - -label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list)); -if (label_addr == NULL) - return; -label_addr->label = LABEL(); -label_addr->update_addr = update_addr; -label_addr->next = common->label_addrs; -common->label_addrs = label_addr; -} - -static SLJIT_INLINE void count_match(compiler_common *common) -{ -DEFINE_COMPILER; - -OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); -add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO)); -} - -static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) -{ -/* May destroy all locals and registers except TMP2. */ -DEFINE_COMPILER; - -SLJIT_ASSERT(size > 0); -OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); -#ifdef DESTROY_REGISTERS -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); -OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); -OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); -#endif -add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); -} - -static SLJIT_INLINE void free_stack(compiler_common *common, int size) -{ -DEFINE_COMPILER; -SLJIT_ASSERT(size > 0); -OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); -} - -static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size) -{ -DEFINE_COMPILER; -sljit_uw *result; - -if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - -result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data); -if (SLJIT_UNLIKELY(result == NULL)) - { - sljit_set_compiler_memory_error(compiler); - return NULL; - } - -*(void**)result = common->read_only_data_head; -common->read_only_data_head = (void *)result; -return result + 1; -} - -static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) -{ -DEFINE_COMPILER; -struct sljit_label *loop; -sljit_si i; - -/* At this point we can freely use all temporary registers. */ -SLJIT_ASSERT(length > 1); -/* TMP1 returns with begin - 1. */ -OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); -if (length < 8) - { - for (i = 1; i < length; i++) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0); - } -else - { - GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START); - OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1); - loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, loop); - } -} - -static SLJIT_INLINE void reset_fast_fail(compiler_common *common) -{ -DEFINE_COMPILER; -sljit_si i; - -SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr); - -OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw)) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0); -} - -static SLJIT_INLINE void do_reset_match(compiler_common *common, int length) -{ -DEFINE_COMPILER; -struct sljit_label *loop; -int i; - -SLJIT_ASSERT(length > 1); -/* OVECTOR(1) contains the "string begin - 1" constant. */ -if (length > 2) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); -if (length < 8) - { - for (i = 2; i < length; i++) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0); - } -else - { - GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw)); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2); - loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); - OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, loop); - } - -OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); -if (common->control_head_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); -} - -static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg) -{ -while (current != NULL) - { - switch (current[-2]) - { - case type_then_trap: - break; - - case type_mark: - if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[-3]) == 0) - return current[-4]; - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - SLJIT_ASSERT(current > (sljit_sw*)current[-1]); - current = (sljit_sw*)current[-1]; - } -return -1; -} - -static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) -{ -DEFINE_COMPILER; -struct sljit_label *loop; - -/* At this point we can freely use all registers. */ -OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0); - -OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); -OP1(SLJIT_MOV_UI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); -OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data), - SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE)); - -GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START); -OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); - -loop = LABEL(); -OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); -OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); -/* Copy the integer value to the output buffer */ -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif -SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8); -if (sizeof(PCRE2_SIZE) == 4) - OP1(SLJIT_MOVU_UI, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); -else - OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); -JUMPTO(SLJIT_NOT_ZERO, loop); - -/* Calculate the return value, which is the maximum ovector value. */ -if (topbracket > 1) - { - GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1); - - /* OVECTOR(0) is never equal to SLJIT_S2. */ - loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))); - OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); - CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop); - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0); - } -else - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); -} - -static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) -{ -DEFINE_COMPILER; -sljit_si mov_opcode; - -SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2); -SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 - && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0)); - -OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), - common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr); -OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL); - -/* Store match begin and end. */ -OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0); -OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data)); - -mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; - -OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif -OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0); - -OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S0, 0); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif -OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0); - -JUMPTO(SLJIT_JUMP, quit); -} - -static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) -{ -/* May destroy TMP1. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -if (common->mode == PCRE2_JIT_PARTIAL_SOFT) - { - /* The value of -1 must be kept for start_used_ptr! */ - OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1); - /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting - is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ - jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); - JUMPHERE(jump); - } -else if (common->mode == PCRE2_JIT_PARTIAL_HARD) - { - jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); - JUMPHERE(jump); - } -} - -static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc) -{ -/* Detects if the character has an othercase. */ -unsigned int c; - -#ifdef SUPPORT_UNICODE -if (common->utf) - { - GETCHAR(c, cc); - if (c > 127) - { - return c != UCD_OTHERCASE(c); - } -#if PCRE2_CODE_UNIT_WIDTH != 8 - return common->fcc[c] != c; -#endif - } -else -#endif - c = *cc; -return MAX_255(c) ? common->fcc[c] != c : FALSE; -} - -static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) -{ -/* Returns with the othercase. */ -#ifdef SUPPORT_UNICODE -if (common->utf && c > 127) - { - return UCD_OTHERCASE(c); - } -#endif -return TABLE_GET(c, common->fcc, c); -} - -static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc) -{ -/* Detects if the character and its othercase has only 1 bit difference. */ -unsigned int c, oc, bit; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -int n; -#endif - -#ifdef SUPPORT_UNICODE -if (common->utf) - { - GETCHAR(c, cc); - if (c <= 127) - oc = common->fcc[c]; - else - { - oc = UCD_OTHERCASE(c); - } - } -else - { - c = *cc; - oc = TABLE_GET(c, common->fcc, c); - } -#else -c = *cc; -oc = TABLE_GET(c, common->fcc, c); -#endif - -SLJIT_ASSERT(c != oc); - -bit = c ^ oc; -/* Optimized for English alphabet. */ -if (c <= 127 && bit == 0x20) - return (0 << 8) | 0x20; - -/* Since c != oc, they must have at least 1 bit difference. */ -if (!is_powerof2(bit)) - return 0; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - -#ifdef SUPPORT_UNICODE -if (common->utf && c > 127) - { - n = GET_EXTRALEN(*cc); - while ((bit & 0x3f) == 0) - { - n--; - bit >>= 6; - } - return (n << 8) | bit; - } -#endif /* SUPPORT_UNICODE */ -return (0 << 8) | bit; - -#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - -#ifdef SUPPORT_UNICODE -if (common->utf && c > 65535) - { - if (bit >= (1 << 10)) - bit >>= 10; - else - return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); - } -#endif /* SUPPORT_UNICODE */ -return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); - -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ -} - -static void check_partial(compiler_common *common, BOOL force) -{ -/* Checks whether a partial matching is occurred. Does not modify registers. */ -DEFINE_COMPILER; -struct sljit_jump *jump = NULL; - -SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE); - -if (common->mode == PCRE2_JIT_COMPLETE) - return; - -if (!force) - jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); -else if (common->mode == PCRE2_JIT_PARTIAL_SOFT) - jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); - -if (common->mode == PCRE2_JIT_PARTIAL_SOFT) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); -else - { - if (common->partialmatchlabel != NULL) - JUMPTO(SLJIT_JUMP, common->partialmatchlabel); - else - add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); - } - -if (jump != NULL) - JUMPHERE(jump); -} - -static void check_str_end(compiler_common *common, jump_list **end_reached) -{ -/* Does not affect registers. Usually used in a tight spot. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -if (common->mode == PCRE2_JIT_COMPLETE) - { - add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - return; - } - -jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); -if (common->mode == PCRE2_JIT_PARTIAL_SOFT) - { - add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); - add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); - } -else - { - add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); - if (common->partialmatchlabel != NULL) - JUMPTO(SLJIT_JUMP, common->partialmatchlabel); - else - add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); - } -JUMPHERE(jump); -} - -static void detect_partial_match(compiler_common *common, jump_list **backtracks) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; - -if (common->mode == PCRE2_JIT_COMPLETE) - { - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - return; - } - -/* Partial matching mode. */ -jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); -add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); -if (common->mode == PCRE2_JIT_PARTIAL_SOFT) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - } -else - { - if (common->partialmatchlabel != NULL) - JUMPTO(SLJIT_JUMP, common->partialmatchlabel); - else - add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); - } -JUMPHERE(jump); -} - -static void peek_char(compiler_common *common, sljit_ui max) -{ -/* Reads the character into TMP1, keeps STR_PTR. -Does not check STR_END. TMP2 Destroyed. */ -DEFINE_COMPILER; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_jump *jump; -#endif - -SLJIT_UNUSED_ARG(max); - -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { - if (max < 128) return; - - jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - JUMPHERE(jump); - } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) - { - if (max < 0xd800) return; - - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - /* TMP2 contains the high surrogate. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - JUMPHERE(jump); - } -#endif -} - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - -static BOOL is_char7_bitset(const sljit_ub *bitset, BOOL nclass) -{ -/* Tells whether the character codes below 128 are enough -to determine a match. */ -const sljit_ub value = nclass ? 0xff : 0; -const sljit_ub *end = bitset + 32; - -bitset += 16; -do - { - if (*bitset++ != value) - return FALSE; - } -while (bitset < end); -return TRUE; -} - -static void read_char7_type(compiler_common *common, BOOL full_read) -{ -/* Reads the precise character type of a character into TMP1, if the character -is less than 128. Otherwise it returns with zero. Does not check STR_END. The -full_read argument tells whether characters above max are accepted or not. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -SLJIT_ASSERT(common->utf); - -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); - -if (full_read) - { - jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - JUMPHERE(jump); - } -} - -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - -static void read_char_range(compiler_common *common, sljit_ui min, sljit_ui max, BOOL update_str_ptr) -{ -/* Reads the precise value of a character into TMP1, if the character is -between min and max (c >= min && c <= max). Otherwise it returns with a value -outside the range. Does not check STR_END. */ -DEFINE_COMPILER; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_jump *jump; -#endif -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -struct sljit_jump *jump2; -#endif - -SLJIT_UNUSED_ARG(update_str_ptr); -SLJIT_UNUSED_ARG(min); -SLJIT_UNUSED_ARG(max); -SLJIT_ASSERT(min <= max); - -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { - if (max < 128 && !update_str_ptr) return; - - jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - if (min >= 0x10000) - { - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); - if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); - if (!update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - JUMPHERE(jump2); - if (update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); - } - else if (min >= 0x800 && max <= 0xffff) - { - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); - if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - if (!update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - JUMPHERE(jump2); - if (update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); - } - else if (max >= 0x800) - add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); - else if (max < 128) - { - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - } - else - { - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (!update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - else - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - if (update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); - } - JUMPHERE(jump); - } -#endif - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) - { - if (max >= 0x10000) - { - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - /* TMP2 contains the high surrogate. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - JUMPHERE(jump); - return; - } - - if (max < 0xd800 && !update_str_ptr) return; - - /* Skip low surrogate if necessary. */ - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - if (update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - if (max >= 0xd800) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); - JUMPHERE(jump); - } -#endif -} - -static SLJIT_INLINE void read_char(compiler_common *common) -{ -read_char_range(common, 0, READ_CHAR_MAX, TRUE); -} - -static void read_char8_type(compiler_common *common, BOOL update_str_ptr) -{ -/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ -DEFINE_COMPILER; -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 -struct sljit_jump *jump; -#endif -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -struct sljit_jump *jump2; -#endif - -SLJIT_UNUSED_ARG(update_str_ptr); - -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { - /* This can be an extra read in some situations, but hopefully - it is needed in most cases. */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); - jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - if (!update_str_ptr) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); - jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); - JUMPHERE(jump2); - } - else - add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); - JUMPHERE(jump); - return; - } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 -/* The ctypes array contains only 256 values. */ -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); -#endif -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); -#if PCRE2_CODE_UNIT_WIDTH != 8 -JUMPHERE(jump); -#endif - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf && update_str_ptr) - { - /* Skip low surrogate if necessary. */ - OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - JUMPHERE(jump); - } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */ -} - -static void skip_char_back(compiler_common *common) -{ -/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ -DEFINE_COMPILER; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -#if PCRE2_CODE_UNIT_WIDTH == 8 -struct sljit_label *label; - -if (common->utf) - { - label = LABEL(); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); - return; - } -#elif PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - /* Skip low surrogate if necessary. */ - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - return; - } -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -} - -static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch) -{ -/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -if (nltype == NLTYPE_ANY) - { - add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - } -else if (nltype == NLTYPE_ANYCRLF) - { - if (jumpifmatch) - { - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - } - else - { - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - JUMPHERE(jump); - } - } -else - { - SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); - add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); - } -} - -#ifdef SUPPORT_UNICODE - -#if PCRE2_CODE_UNIT_WIDTH == 8 -static void do_utfreadchar(compiler_common *common) -{ -/* Fast decoding a UTF-8 character. TMP1 contains the first byte -of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - -/* Searching for the first zero. */ -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); -jump = JUMP(SLJIT_NOT_ZERO); -/* Two byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -JUMPHERE(jump); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); -jump = JUMP(SLJIT_NOT_ZERO); -/* Three byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -/* Four byte sequence. */ -JUMPHERE(jump); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -static void do_utfreadchar16(compiler_common *common) -{ -/* Fast decoding a UTF-8 character. TMP1 contains the first byte -of the character (>= 0xc0). Return value in TMP1. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - -/* Searching for the first zero. */ -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); -jump = JUMP(SLJIT_NOT_ZERO); -/* Two byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -JUMPHERE(jump); -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO); -/* This code runs only in 8 bit mode. No need to shift the value. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -/* Three byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -static void do_utfreadtype8(compiler_common *common) -{ -/* Fast decoding a UTF-8 character type. TMP2 contains the first byte -of the character (>= 0xc0). Return value in TMP1. */ -DEFINE_COMPILER; -struct sljit_jump *jump; -struct sljit_jump *compare; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); - -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); -jump = JUMP(SLJIT_NOT_ZERO); -/* Two byte sequence. */ -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); -/* The upper 5 bits are known at this point. */ -compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3); -OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -JUMPHERE(compare); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -/* We only have types for characters less than 256. */ -JUMPHERE(jump); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - -/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ -#define UCD_BLOCK_MASK 127 -#define UCD_BLOCK_SHIFT 7 - -static void do_getucd(compiler_common *common) -{ -/* Search the UCD record for the character comes in TMP1. -Returns chartype in TMP1 and UCD offset in TMP2. */ -DEFINE_COMPILER; - -SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); -OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); -OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -#endif /* SUPPORT_UNICODE */ - -static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, uint32_t overall_options) -{ -DEFINE_COMPILER; -struct sljit_label *mainloop; -struct sljit_label *newlinelabel = NULL; -struct sljit_jump *start; -struct sljit_jump *end = NULL; -struct sljit_jump *end2 = NULL; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_jump *singlechar; -#endif -jump_list *newline = NULL; -BOOL newlinecheck = FALSE; -BOOL readuchar = FALSE; - -if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0) - && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) - newlinecheck = TRUE; - -SLJIT_ASSERT(common->forced_quit_label == NULL); - -if ((overall_options & PCRE2_FIRSTLINE) != 0) - { - /* Search for the end of the first line. */ - SLJIT_ASSERT(common->match_end_ptr != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - mainloop = LABEL(); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); - JUMPHERE(end); - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } - else - { - end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - mainloop = LABEL(); - /* Continual stores does not cause data dependency. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - check_newlinechar(common, common->nltype, &newline, TRUE); - CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop); - JUMPHERE(end); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); - set_jumps(newline, LABEL()); - } - - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - } -else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0) - { - /* Check whether offset limit is set and valid. */ - SLJIT_ASSERT(common->match_end_ptr != 0); - - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit)); - OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); - end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); -#if PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); -#endif - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); - JUMPHERE(end2); - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); - add_jump(compiler, &common->forced_quit, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0)); - JUMPHERE(end); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0); - } - -start = JUMP(SLJIT_JUMP); - -if (newlinecheck) - { - newlinelabel = LABEL(); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - end2 = JUMP(SLJIT_JUMP); - } - -mainloop = LABEL(); - -/* Increasing the STR_PTR here requires one less jump in the most common case. */ -#ifdef SUPPORT_UNICODE -if (common->utf) readuchar = TRUE; -#endif -if (newlinecheck) readuchar = TRUE; - -if (readuchar) - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - -if (newlinecheck) - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { - singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(singlechar); - } -#elif PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) - { - singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(singlechar); - } -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ -JUMPHERE(start); - -if (newlinecheck) - { - JUMPHERE(end); - JUMPHERE(end2); - } - -return mainloop; -} - -#define MAX_N_CHARS 16 -#define MAX_DIFF_CHARS 6 - -static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, PCRE2_UCHAR *chars) -{ -PCRE2_UCHAR i, len; - -len = chars[0]; -if (len == 255) - return; - -if (len == 0) - { - chars[0] = 1; - chars[1] = chr; - return; - } - -for (i = len; i > 0; i--) - if (chars[i] == chr) - return; - -if (len >= MAX_DIFF_CHARS - 1) - { - chars[0] = 255; - return; - } - -len++; -chars[len] = chr; -chars[0] = len; -} - -static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, uint32_t *rec_count) -{ -/* Recursive function, which scans prefix literals. */ -BOOL last, any, class, caseless; -int len, repeat, len_save, consumed = 0; -sljit_ui chr; /* Any unicode character. */ -sljit_ub *bytes, *bytes_end, byte; -PCRE2_SPTR alternative, cc_save, oc; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -PCRE2_UCHAR othercase[8]; -#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 -PCRE2_UCHAR othercase[2]; -#else -PCRE2_UCHAR othercase[1]; -#endif - -repeat = 1; -while (TRUE) - { - if (*rec_count == 0) - return 0; - (*rec_count)--; - - last = TRUE; - any = FALSE; - class = FALSE; - caseless = FALSE; - - switch (*cc) - { - case OP_CHARI: - caseless = TRUE; - case OP_CHAR: - last = FALSE; - cc++; - break; - - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; - continue; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - cc = bracketend(cc); - continue; - - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - caseless = TRUE; - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - cc++; - break; - - case OP_EXACTI: - caseless = TRUE; - case OP_EXACT: - repeat = GET2(cc, 1); - last = FALSE; - cc += 1 + IMM2_SIZE; - break; - - case OP_QUERYI: - case OP_MINQUERYI: - case OP_POSQUERYI: - caseless = TRUE; - case OP_QUERY: - case OP_MINQUERY: - case OP_POSQUERY: - len = 1; - cc++; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); -#endif - max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; - last = FALSE; - break; - - case OP_KET: - cc += 1 + LINK_SIZE; - continue; - - case OP_ALT: - cc += GET(cc, 1); - continue; - - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRA: - case OP_BRAPOS: - case OP_CBRA: - case OP_CBRAPOS: - alternative = cc + GET(cc, 1); - while (*alternative == OP_ALT) - { - max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; - alternative += GET(alternative, 1); - } - - if (*cc == OP_CBRA || *cc == OP_CBRAPOS) - cc += IMM2_SIZE; - cc += 1 + LINK_SIZE; - continue; - - case OP_CLASS: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)(cc + 1), FALSE)) return consumed; -#endif - class = TRUE; - break; - - case OP_NCLASS: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; -#endif - class = TRUE; - break; - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; -#endif - any = TRUE; - cc += GET(cc, 1); - break; -#endif - - case OP_DIGIT: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_digit, FALSE)) - return consumed; -#endif - any = TRUE; - cc++; - break; - - case OP_WHITESPACE: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_space, FALSE)) - return consumed; -#endif - any = TRUE; - cc++; - break; - - case OP_WORDCHAR: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_word, FALSE)) - return consumed; -#endif - any = TRUE; - cc++; - break; - - case OP_NOT: - case OP_NOTI: - cc++; - /* Fall through. */ - case OP_NOT_DIGIT: - case OP_NOT_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_ANY: - case OP_ALLANY: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; -#endif - any = TRUE; - cc++; - break; - -#ifdef SUPPORT_UNICODE - case OP_NOTPROP: - case OP_PROP: -#if PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; -#endif - any = TRUE; - cc += 1 + 2; - break; -#endif - - case OP_TYPEEXACT: - repeat = GET2(cc, 1); - cc += 1 + IMM2_SIZE; - continue; - - case OP_NOTEXACT: - case OP_NOTEXACTI: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; -#endif - any = TRUE; - repeat = GET2(cc, 1); - cc += 1 + IMM2_SIZE + 1; - break; - - default: - return consumed; - } - - if (any) - { - do - { - chars[0] = 255; - - consumed++; - if (--max_chars == 0) - return consumed; - chars += MAX_DIFF_CHARS; - } - while (--repeat > 0); - - repeat = 1; - continue; - } - - if (class) - { - bytes = (sljit_ub*) (cc + 1); - cc += 1 + 32 / sizeof(PCRE2_UCHAR); - - switch (*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPOSSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSQUERY: - max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; - break; - - default: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - repeat = GET2(cc, 1); - if (repeat <= 0) - return consumed; - break; - } - - do - { - if (bytes[31] & 0x80) - chars[0] = 255; - else if (chars[0] != 255) - { - bytes_end = bytes + 32; - chr = 0; - do - { - byte = *bytes++; - SLJIT_ASSERT((chr & 0x7) == 0); - if (byte == 0) - chr += 8; - else - { - do - { - if ((byte & 0x1) != 0) - add_prefix_char(chr, chars); - byte >>= 1; - chr++; - } - while (byte != 0); - chr = (chr + 7) & ~7; - } - } - while (chars[0] != 255 && bytes < bytes_end); - bytes = bytes_end - 32; - } - - consumed++; - if (--max_chars == 0) - return consumed; - chars += MAX_DIFF_CHARS; - } - while (--repeat > 0); - - switch (*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPOSSTAR: - return consumed; - - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSQUERY: - cc++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE)) - return consumed; - cc += 1 + 2 * IMM2_SIZE; - break; - } - - repeat = 1; - continue; - } - - len = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); -#endif - - if (caseless && char_has_othercase(common, cc)) - { -#ifdef SUPPORT_UNICODE - if (common->utf) - { - GETCHAR(chr, cc); - if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) - return consumed; - } - else -#endif - { - chr = *cc; - othercase[0] = TABLE_GET(chr, common->fcc, chr); - } - } - else - { - caseless = FALSE; - othercase[0] = 0; /* Stops compiler warning - PH */ - } - - len_save = len; - cc_save = cc; - while (TRUE) - { - oc = othercase; - do - { - chr = *cc; - add_prefix_char(*cc, chars); - - if (caseless) - add_prefix_char(*oc, chars); - - len--; - consumed++; - if (--max_chars == 0) - return consumed; - chars += MAX_DIFF_CHARS; - cc++; - oc++; - } - while (len > 0); - - if (--repeat == 0) - break; - - len = len_save; - cc = cc_save; - } - - repeat = 1; - if (last) - return consumed; - } -} - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - -static sljit_si character_to_int32(PCRE2_UCHAR chr) -{ -sljit_si value = (sljit_si)chr; -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define SSE2_COMPARE_TYPE_INDEX 0 -return (value << 24) | (value << 16) | (value << 8) | value; -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#define SSE2_COMPARE_TYPE_INDEX 1 -return (value << 16) | value; -#elif PCRE2_CODE_UNIT_WIDTH == 32 -#define SSE2_COMPARE_TYPE_INDEX 2 -return value; -#else -#error "Unsupported unit width" -#endif -} - -static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit[3]; -struct sljit_jump *nomatch; -sljit_ub instruction[8]; -sljit_si tmp1_ind = sljit_get_register_index(TMP1); -sljit_si tmp2_ind = sljit_get_register_index(TMP2); -sljit_si str_ptr_ind = sljit_get_register_index(STR_PTR); -BOOL load_twice = FALSE; -PCRE2_UCHAR bit; - -bit = char1 ^ char2; -if (!is_powerof2(bit)) - bit = 0; - -if ((char1 != char2) && bit == 0) - load_twice = TRUE; - -quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - -/* First part (unaligned start) */ - -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); - -SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (2 << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -if (char1 != char2) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); - - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (3 << 3) | tmp1_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PSHUFD xmm1, xmm2/m128, imm8 */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (2 << 3) | 2; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); - -if (char1 != char2) - { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (3 << 3) | 3; - instruction[4] = 0; - sljit_emit_op_custom(compiler, instruction, 5); - } - -OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); - -/* MOVDQA xmm1, xmm2/m128 */ -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - -if (str_ptr_ind < 8) - { - instruction[2] = 0x6f; - instruction[3] = (0 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - - if (load_twice) - { - instruction[3] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - } -else - { - instruction[1] = 0x41; - instruction[2] = 0x0f; - instruction[3] = 0x6f; - instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); - sljit_emit_op_custom(compiler, instruction, 5); - - if (load_twice) - { - instruction[4] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - instruction[1] = 0x0f; - } - -#else - -instruction[2] = 0x6f; -instruction[3] = (0 << 3) | str_ptr_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - instruction[3] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -#endif - -if (bit != 0) - { - /* POR xmm1, xmm2/m128 */ - instruction[2] = 0xeb; - instruction[3] = 0xc0 | (0 << 3) | 3; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PCMPEQB/W/D xmm1, xmm2/m128 */ -instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; -instruction[3] = 0xc0 | (0 << 3) | 2; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - instruction[3] = 0xc0 | (1 << 3) | 3; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PMOVMSKB reg, xmm */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); - instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; - sljit_emit_op_custom(compiler, instruction, 4); - - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); - } - -OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0); - -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); - -nomatch = JUMP(SLJIT_ZERO); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -quit[1] = JUMP(SLJIT_JUMP); - -JUMPHERE(nomatch); - -start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); -quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - -/* Second part (aligned) */ - -instruction[0] = 0x66; -instruction[1] = 0x0f; - -/* MOVDQA xmm1, xmm2/m128 */ -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - -if (str_ptr_ind < 8) - { - instruction[2] = 0x6f; - instruction[3] = (0 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - - if (load_twice) - { - instruction[3] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - } -else - { - instruction[1] = 0x41; - instruction[2] = 0x0f; - instruction[3] = 0x6f; - instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); - sljit_emit_op_custom(compiler, instruction, 5); - - if (load_twice) - { - instruction[4] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - instruction[1] = 0x0f; - } - -#else - -instruction[2] = 0x6f; -instruction[3] = (0 << 3) | str_ptr_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - instruction[3] = (1 << 3) | str_ptr_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -#endif - -if (bit != 0) - { - /* POR xmm1, xmm2/m128 */ - instruction[2] = 0xeb; - instruction[3] = 0xc0 | (0 << 3) | 3; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PCMPEQB/W/D xmm1, xmm2/m128 */ -instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; -instruction[3] = 0xc0 | (0 << 3) | 2; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - instruction[3] = 0xc0 | (1 << 3) | 3; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PMOVMSKB reg, xmm */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -if (load_twice) - { - instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; - sljit_emit_op_custom(compiler, instruction, 4); - - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - } - -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); - -JUMPTO(SLJIT_ZERO, start); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - -start = LABEL(); -SET_LABEL(quit[0], start); -SET_LABEL(quit[1], start); -SET_LABEL(quit[2], start); -} - -#undef SSE2_COMPARE_TYPE_INDEX - -#endif - -static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_si offset) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -struct sljit_jump *found; -PCRE2_UCHAR mask; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_label *utf_start = NULL; -struct sljit_jump *utf_quit = NULL; -#endif -BOOL has_match_end = (common->match_end_ptr != 0); - -if (offset > 0) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); - -if (has_match_end) - { - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - - OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1)); -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - if (sljit_x86_is_cmov_available()) - { - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0); - sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0); - } -#endif - { - quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0); - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - JUMPHERE(quit); - } - } - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf && offset > 0) - utf_start = LABEL(); -#endif - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - -/* SSE2 accelerated first character search. */ - -if (sljit_x86_is_sse2_available()) - { - fast_forward_first_char2_sse2(common, char1, char2); - - SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0); - if (common->mode == PCRE2_JIT_COMPLETE) - { - /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */ - SLJIT_ASSERT(common->forced_quit_label == NULL); - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); - add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf && offset > 0) - { - SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); -#else -#error "Unknown code width" -#endif - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } -#endif - - if (offset > 0) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); - } - else if (sljit_x86_is_cmov_available()) - { - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); - sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); - } - else - { - quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); - JUMPHERE(quit); - } - - if (has_match_end) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - return; - } - -#endif - -quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - -start = LABEL(); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - -if (char1 == char2) - found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1); -else - { - mask = char1 ^ char2; - if (is_powerof2(mask)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); - found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask); - } - else - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - found = JUMP(SLJIT_NOT_ZERO); - } - } - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf && offset > 0) - utf_quit = JUMP(SLJIT_JUMP); -#endif - -JUMPHERE(found); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf && offset > 0) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); -#else -#error "Unknown code width" -#endif - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - JUMPHERE(utf_quit); - } -#endif - -JUMPHERE(quit); - -if (has_match_end) - { - quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - if (offset > 0) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); - JUMPHERE(quit); - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - } - -if (offset > 0) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); -} - -static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -struct sljit_jump *match; -/* bytes[0] represent the number of characters between 0 -and MAX_N_BYTES - 1, 255 represents any character. */ -PCRE2_UCHAR chars[MAX_N_CHARS * MAX_DIFF_CHARS]; -sljit_si offset; -PCRE2_UCHAR mask; -PCRE2_UCHAR *char_set, *char_set_end; -int i, max, from; -int range_right = -1, range_len; -sljit_ub *update_table = NULL; -BOOL in_range; -uint32_t rec_count; - -for (i = 0; i < MAX_N_CHARS; i++) - chars[i * MAX_DIFF_CHARS] = 0; - -rec_count = 10000; -max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count); - -if (max < 1) - return FALSE; - -in_range = FALSE; -/* Prevent compiler "uninitialized" warning */ -from = 0; -range_len = 4 /* minimum length */ - 1; -for (i = 0; i <= max; i++) - { - if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255)) - { - range_len = i - from; - range_right = i - 1; - } - - if (i < max && chars[i * MAX_DIFF_CHARS] < 255) - { - SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0); - if (!in_range) - { - in_range = TRUE; - from = i; - } - } - else - in_range = FALSE; - } - -if (range_right >= 0) - { - update_table = (sljit_ub *)allocate_read_only_data(common, 256); - if (update_table == NULL) - return TRUE; - memset(update_table, IN_UCHARS(range_len), 256); - - for (i = 0; i < range_len; i++) - { - char_set = chars + ((range_right - i) * MAX_DIFF_CHARS); - SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255); - char_set_end = char_set + char_set[0]; - char_set++; - while (char_set <= char_set_end) - { - if (update_table[(*char_set) & 0xff] > IN_UCHARS(i)) - update_table[(*char_set) & 0xff] = IN_UCHARS(i); - char_set++; - } - } - } - -offset = -1; -/* Scan forward. */ -for (i = 0; i < max; i++) - { - if (offset == -1) - { - if (chars[i * MAX_DIFF_CHARS] <= 2) - offset = i; - } - else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2) - { - if (chars[i * MAX_DIFF_CHARS] == 1) - offset = i; - else - { - mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; - if (!is_powerof2(mask)) - { - mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2]; - if (is_powerof2(mask)) - offset = i; - } - } - } - } - -if (range_right < 0) - { - if (offset < 0) - return FALSE; - SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2); - /* Works regardless the value is 1 or 2. */ - mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]]; - fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset); - return TRUE; - } - -if (range_right == offset) - offset = -1; - -SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2)); - -max -= 1; -SLJIT_ASSERT(max > 0); -if (common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); - quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0); - OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); - JUMPHERE(quit); - } -else - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); - -SLJIT_ASSERT(range_right >= 0); - -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); -#endif - -start = LABEL(); -quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - -#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); -#else -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); -#endif - -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); -#else -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); -#endif -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); - -if (offset >= 0) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset)); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - - if (chars[offset * MAX_DIFF_CHARS] == 1) - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start); - else - { - mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; - if (is_powerof2(mask)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start); - } - else - { - match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start); - JUMPHERE(match); - } - } - } - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf && offset != 0) - { - if (offset < 0) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } - else - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start); -#else -#error "Unknown code width" -#endif - if (offset < 0) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } -#endif - -if (offset >= 0) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -JUMPHERE(quit); - -if (common->match_end_ptr != 0) - { - if (range_right >= 0) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - if (range_right >= 0) - { - quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); - OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); - JUMPHERE(quit); - } - } -else - OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); -return TRUE; -} - -#undef MAX_N_CHARS -#undef MAX_N_BYTES - -static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, PCRE2_UCHAR first_char, BOOL caseless) -{ -PCRE2_UCHAR oc; - -oc = first_char; -if (caseless) - { - oc = TABLE_GET(first_char, common->fcc, first_char); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (first_char > 127 && common->utf) - oc = UCD_OTHERCASE(first_char); -#endif - } - -fast_forward_first_char2(common, first_char, oc, 0); -} - -static SLJIT_INLINE void fast_forward_newline(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_label *loop; -struct sljit_jump *lastchar; -struct sljit_jump *firstchar; -struct sljit_jump *quit; -struct sljit_jump *foundcr = NULL; -struct sljit_jump *notfoundnl; -jump_list *newline = NULL; - -if (common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - } - -if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); - - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - - loop = LABEL(); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); - - JUMPHERE(quit); - JUMPHERE(firstchar); - JUMPHERE(lastchar); - - if (common->match_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - return; - } - -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); -firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); -skip_char_back(common); - -loop = LABEL(); -common->ff_newline_shortcut = loop; - -read_char_range(common, common->nlmin, common->nlmax, TRUE); -lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) - foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); -check_newlinechar(common, common->nltype, &newline, FALSE); -set_jumps(newline, loop); - -if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) - { - quit = JUMP(SLJIT_JUMP); - JUMPHERE(foundcr); - notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(notfoundnl); - JUMPHERE(quit); - } -JUMPHERE(lastchar); -JUMPHERE(firstchar); - -if (common->match_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); -} - -static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks); - -static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_ub *start_bits) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -struct sljit_jump *found = NULL; -jump_list *matches = NULL; -#if PCRE2_CODE_UNIT_WIDTH != 8 -struct sljit_jump *jump; -#endif - -if (common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - } - -start = LABEL(); -quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#ifdef SUPPORT_UNICODE -if (common->utf) - OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); -#endif - -if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) - { -#if PCRE2_CODE_UNIT_WIDTH != 8 - jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); - JUMPHERE(jump); -#endif - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - found = JUMP(SLJIT_NOT_ZERO); - } - -#ifdef SUPPORT_UNICODE -if (common->utf) - OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); -#endif -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#ifdef SUPPORT_UNICODE -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - } -#elif PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) - { - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - } -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ -#endif /* SUPPORT_UNICODE */ -JUMPTO(SLJIT_JUMP, start); -if (found != NULL) - JUMPHERE(found); -if (matches != NULL) - set_jumps(matches, LABEL()); -JUMPHERE(quit); - -if (common->match_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); -} - -static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar) -{ -DEFINE_COMPILER; -struct sljit_label *loop; -struct sljit_jump *toolong; -struct sljit_jump *alreadyfound; -struct sljit_jump *found; -struct sljit_jump *foundoc = NULL; -struct sljit_jump *notfound; -sljit_ui oc, bit; - -SLJIT_ASSERT(common->req_char_ptr != 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); -OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX); -toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0); -alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); - -if (has_firstchar) - OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -else - OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); - -loop = LABEL(); -notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0); - -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); -oc = req_char; -if (caseless) - { - oc = TABLE_GET(req_char, common->fcc, req_char); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (req_char > 127 && common->utf) - oc = UCD_OTHERCASE(req_char); -#endif - } -if (req_char == oc) - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); -else - { - bit = req_char ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); - } - else - { - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); - foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc); - } - } -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); -JUMPTO(SLJIT_JUMP, loop); - -JUMPHERE(found); -if (foundoc) - JUMPHERE(foundoc); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0); -JUMPHERE(alreadyfound); -JUMPHERE(toolong); -return notfound; -} - -static void do_revertframes(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; -struct sljit_label *mainloop; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); -GET_LOCAL_BASE(TMP3, 0, 0); - -/* Drop frames until we reach STACK_TOP. */ -mainloop = LABEL(); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); -OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); -jump = JUMP(SLJIT_SIG_LESS_EQUAL); - -OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); -JUMPTO(SLJIT_JUMP, mainloop); - -JUMPHERE(jump); -jump = JUMP(SLJIT_SIG_LESS); -/* End of dropping frames. */ -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -JUMPHERE(jump); -OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); -OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); -JUMPTO(SLJIT_JUMP, mainloop); -} - -static void check_wordboundary(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_jump *skipread; -jump_list *skipread_list = NULL; -#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE -struct sljit_jump *jump; -#endif - -SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); - -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); -/* Get type of the previous char, and put it to LOCALS1. */ -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); -skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); -skip_char_back(common); -check_start_used_ptr(common); -read_char(common); - -/* Testing char type. */ -#ifdef SUPPORT_UNICODE -if (common->use_ucp) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); - } -else -#endif - { -#if PCRE2_CODE_UNIT_WIDTH != 8 - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); -#elif defined SUPPORT_UNICODE - /* Here LOCALS1 has already been zeroed. */ - jump = NULL; - if (common->utf) - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); -#if PCRE2_CODE_UNIT_WIDTH != 8 - JUMPHERE(jump); -#elif defined SUPPORT_UNICODE - if (jump != NULL) - JUMPHERE(jump); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - } -JUMPHERE(skipread); - -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); -check_str_end(common, &skipread_list); -peek_char(common, READ_CHAR_MAX); - -/* Testing char type. This is a code duplication. */ -#ifdef SUPPORT_UNICODE -if (common->use_ucp) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); - } -else -#endif - { -#if PCRE2_CODE_UNIT_WIDTH != 8 - /* TMP2 may be destroyed by peek_char. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); -#elif defined SUPPORT_UNICODE - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); - jump = NULL; - if (common->utf) - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); -#endif - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); - OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); - OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); -#if PCRE2_CODE_UNIT_WIDTH != 8 - JUMPHERE(jump); -#elif defined SUPPORT_UNICODE - if (jump != NULL) - JUMPHERE(jump); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - } -set_jumps(skipread_list, LABEL()); - -OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); -} - -static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks) -{ -/* May destroy TMP1. */ -DEFINE_COMPILER; -int ranges[MAX_RANGE_SIZE]; -sljit_ub bit, cbit, all; -int i, byte, length = 0; - -bit = bits[0] & 0x1; -/* All bits will be zero or one (since bit is zero or one). */ -all = -bit; - -for (i = 0; i < 256; ) - { - byte = i >> 3; - if ((i & 0x7) == 0 && bits[byte] == all) - i += 8; - else - { - cbit = (bits[byte] >> (i & 0x7)) & 0x1; - if (cbit != bit) - { - if (length >= MAX_RANGE_SIZE) - return FALSE; - ranges[length] = i; - length++; - bit = cbit; - all = -cbit; - } - i++; - } - } - -if (((bit == 0) && nclass) || ((bit == 1) && !nclass)) - { - if (length >= MAX_RANGE_SIZE) - return FALSE; - ranges[length] = 256; - length++; - } - -if (length < 0 || length > 4) - return FALSE; - -bit = bits[0] & 0x1; -if (invert) bit ^= 0x1; - -/* No character is accepted. */ -if (length == 0 && bit == 0) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - -switch(length) - { - case 0: - /* When bit != 0, all characters are accepted. */ - return TRUE; - - case 1: - add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); - return TRUE; - - case 2: - if (ranges[0] + 1 != ranges[1]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); - add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); - } - else - add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); - return TRUE; - - case 3: - if (bit != 0) - { - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - if (ranges[0] + 1 != ranges[1]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); - return TRUE; - } - - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); - if (ranges[1] + 1 != ranges[2]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); - return TRUE; - - case 4: - if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) - && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] - && (ranges[1] & (ranges[2] - ranges[0])) == 0 - && is_powerof2(ranges[2] - ranges[0])) - { - SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); - if (ranges[2] + 1 != ranges[3]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); - add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); - } - else - add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - return TRUE; - } - - if (bit != 0) - { - i = 0; - if (ranges[0] + 1 != ranges[1]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); - i = ranges[0]; - } - else - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); - - if (ranges[2] + 1 != ranges[3]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); - return TRUE; - } - - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); - if (ranges[1] + 1 != ranges[2]) - { - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); - return TRUE; - - default: - SLJIT_ASSERT_STOP(); - return FALSE; - } -} - -static void check_anynewline(compiler_common *common) -{ -/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ -DEFINE_COMPILER; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); - -OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); -OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { -#endif - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); -#if PCRE2_CODE_UNIT_WIDTH == 8 - } -#endif -#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -static void check_hspace(compiler_common *common) -{ -/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ -DEFINE_COMPILER; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); - -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); -OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { -#endif - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); -#if PCRE2_CODE_UNIT_WIDTH == 8 - } -#endif -#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -static void check_vspace(compiler_common *common) -{ -/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ -DEFINE_COMPILER; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); - -OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); -OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) - { -#endif - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); -#if PCRE2_CODE_UNIT_WIDTH == 8 - } -#endif -#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -#define CHAR1 STR_END -#define CHAR2 STACK_TOP - -static void do_casefulcmp(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; -struct sljit_label *label; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0); -OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -label = LABEL(); -OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); -OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); -OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); -JUMPTO(SLJIT_NOT_ZERO, label); - -JUMPHERE(jump); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); -OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -#define LCC_TABLE STACK_LIMIT - -static void do_caselesscmp(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; -struct sljit_label *label; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - -OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0); -OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); -OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -label = LABEL(); -OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); -OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH != 8 -jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255); -#endif -OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); -#if PCRE2_CODE_UNIT_WIDTH != 8 -JUMPHERE(jump); -jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255); -#endif -OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); -#if PCRE2_CODE_UNIT_WIDTH != 8 -JUMPHERE(jump); -#endif -jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); -OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); -JUMPTO(SLJIT_NOT_ZERO, label); - -JUMPHERE(jump); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); -OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); -OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -#undef LCC_TABLE -#undef CHAR1 -#undef CHAR2 - -#if defined SUPPORT_UNICODE - -static PCRE2_SPTR SLJIT_CALL do_utf_caselesscmp(PCRE2_SPTR src1, jit_arguments *args, PCRE2_SPTR end1) -{ -/* This function would be ineffective to do in JIT level. */ -sljit_ui c1, c2; -PCRE2_SPTR src2 = args->startchar_ptr; -PCRE2_SPTR end2 = args->end; -const ucd_record *ur; -const sljit_ui *pp; - -while (src1 < end1) - { - if (src2 >= end2) - return (PCRE2_SPTR)1; - GETCHARINC(c1, src1); - GETCHARINC(c2, src2); - ur = GET_UCD(c2); - if (c1 != c2 && c1 != c2 + ur->other_case) - { - pp = PRIV(ucd_caseless_sets) + ur->caseset; - for (;;) - { - if (c1 < *pp) return NULL; - if (c1 == *pp++) break; - } - } - } -return src2; -} - -#endif /* SUPPORT_UNICODE */ - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); - -static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, - compare_context *context, jump_list **backtracks) -{ -DEFINE_COMPILER; -unsigned int othercasebit = 0; -PCRE2_SPTR othercasechar = NULL; -#ifdef SUPPORT_UNICODE -int utflength; -#endif - -if (caseless && char_has_othercase(common, cc)) - { - othercasebit = char_get_othercase_bit(common, cc); - SLJIT_ASSERT(othercasebit); - /* Extracting bit difference info. */ -#if PCRE2_CODE_UNIT_WIDTH == 8 - othercasechar = cc + (othercasebit >> 8); - othercasebit &= 0xff; -#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - /* Note that this code only handles characters in the BMP. If there - ever are characters outside the BMP whose othercase differs in only one - bit from itself (there currently are none), this code will need to be - revised for PCRE2_CODE_UNIT_WIDTH == 32. */ - othercasechar = cc + (othercasebit >> 9); - if ((othercasebit & 0x100) != 0) - othercasebit = (othercasebit & 0xff) << 8; - else - othercasebit &= 0xff; -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - } - -if (context->sourcereg == -1) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - context->sourcereg = TMP2; - } - -#ifdef SUPPORT_UNICODE -utflength = 1; -if (common->utf && HAS_EXTRALEN(*cc)) - utflength += GET_EXTRALEN(*cc); - -do - { -#endif - - context->length -= IN_UCHARS(1); -#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) - - /* Unaligned read is supported. */ - if (othercasebit != 0 && othercasechar == cc) - { - context->c.asuchars[context->ucharptr] = *cc | othercasebit; - context->oc.asuchars[context->ucharptr] = othercasebit; - } - else - { - context->c.asuchars[context->ucharptr] = *cc; - context->oc.asuchars[context->ucharptr] = 0; - } - context->ucharptr++; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) -#else - if (context->ucharptr >= 2 || context->length == 0) -#endif - { - if (context->length >= 4) - OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#if PCRE2_CODE_UNIT_WIDTH == 8 - else if (context->length >= 1) - OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - switch(context->ucharptr) - { - case 4 / sizeof(PCRE2_UCHAR): - if (context->oc.asint != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); - break; - - case 2 / sizeof(PCRE2_UCHAR): - if (context->oc.asushort != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); - break; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - case 1: - if (context->oc.asbyte != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); - break; -#endif - - default: - SLJIT_ASSERT_STOP(); - break; - } - context->ucharptr = 0; - } - -#else - - /* Unaligned read is unsupported or in 32 bit mode. */ - if (context->length >= 1) - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - if (othercasebit != 0 && othercasechar == cc) - { - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); - -#endif - - cc++; -#ifdef SUPPORT_UNICODE - utflength--; - } -while (utflength > 0); -#endif - -return cc; -} - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - -#define SET_TYPE_OFFSET(value) \ - if ((value) != typeoffset) \ - { \ - if ((value) < typeoffset) \ - OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ - else \ - OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ - } \ - typeoffset = (value); - -#define SET_CHAR_OFFSET(value) \ - if ((value) != charoffset) \ - { \ - if ((value) < charoffset) \ - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ - else \ - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ - } \ - charoffset = (value); - -static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -jump_list *found = NULL; -jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; -sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; -struct sljit_jump *jump = NULL; -PCRE2_SPTR ccbegin; -int compares, invertcmp, numberofcmps; -#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) -BOOL utf = common->utf; -#endif - -#ifdef SUPPORT_UNICODE -BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; -BOOL charsaved = FALSE; -int typereg = TMP1; -const sljit_ui *other_cases; -sljit_uw typeoffset; -#endif - -/* Scanning the necessary info. */ -cc++; -ccbegin = cc; -compares = 0; - -if (cc[-1] & XCL_MAP) - { - min = 0; - cc += 32 / sizeof(PCRE2_UCHAR); - } - -while (*cc != XCL_END) - { - compares++; - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - if (c > max) max = c; - if (c < min) min = c; -#ifdef SUPPORT_UNICODE - needschar = TRUE; -#endif - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - if (c < min) min = c; - GETCHARINCTEST(c, cc); - if (c > max) max = c; -#ifdef SUPPORT_UNICODE - needschar = TRUE; -#endif - } -#ifdef SUPPORT_UNICODE - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - if (*cc == PT_CLIST) - { - other_cases = PRIV(ucd_caseless_sets) + cc[1]; - while (*other_cases != NOTACHAR) - { - if (*other_cases > max) max = *other_cases; - if (*other_cases < min) min = *other_cases; - other_cases++; - } - } - else - { - max = READ_CHAR_MAX; - min = 0; - } - - switch(*cc) - { - case PT_ANY: - /* Any either accepts everything or ignored. */ - if (cc[-1] == XCL_PROP) - { - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list == backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } - break; - - case PT_LAMP: - case PT_GC: - case PT_PC: - case PT_ALNUM: - needstype = TRUE; - break; - - case PT_SC: - needsscript = TRUE; - break; - - case PT_SPACE: - case PT_PXSPACE: - case PT_WORD: - case PT_PXGRAPH: - case PT_PXPRINT: - case PT_PXPUNCT: - needstype = TRUE; - needschar = TRUE; - break; - - case PT_CLIST: - case PT_UCNC: - needschar = TRUE; - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - cc += 2; - } -#endif - } -SLJIT_ASSERT(compares > 0); - -/* We are not necessary in utf mode even in 8 bit mode. */ -cc = ccbegin; -read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); - -if ((cc[-1] & XCL_HASPROP) == 0) - { - if ((cc[-1] & XCL_MAP) != 0) - { - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (!check_class_ranges(common, (const sljit_ub *)cc, (((const sljit_ub *)cc)[31] & 0x80) != 0, TRUE, &found)) - { - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); - } - - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump); - - cc += 32 / sizeof(PCRE2_UCHAR); - } - else - { - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); - add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min)); - } - } -else if ((cc[-1] & XCL_MAP) != 0) - { - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); -#ifdef SUPPORT_UNICODE - charsaved = TRUE; -#endif - if (!check_class_ranges(common, (const sljit_ub *)cc, FALSE, TRUE, list)) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump = NULL; - if (common->utf) -#endif - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf) -#endif - JUMPHERE(jump); - } - - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); - cc += 32 / sizeof(PCRE2_UCHAR); - } - -#ifdef SUPPORT_UNICODE -if (needstype || needsscript) - { - if (needschar && !charsaved) - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); - - OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); - OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); - - /* Before anything else, we deal with scripts. */ - if (needsscript) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - ccbegin = cc; - - while (*cc != XCL_END) - { - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - GETCHARINCTEST(c, cc); - } - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - if (*cc == PT_SC) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - cc += 2; - } - } - - cc = ccbegin; - } - - if (needschar) - { - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); - } - - if (needstype) - { - if (!needschar) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); - } - else - { - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - typereg = RETURN_ADDR; - } - } - } -#endif - -/* Generating code. */ -charoffset = 0; -numberofcmps = 0; -#ifdef SUPPORT_UNICODE -typeoffset = 0; -#endif - -while (*cc != XCL_END) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - jump = NULL; - - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - - if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL); - numberofcmps++; - } - else if (numberofcmps > 0) - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - numberofcmps = 0; - } - else - { - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - numberofcmps = 0; - } - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - SET_CHAR_OFFSET(c); - GETCHARINCTEST(c, cc); - - if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) - { - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); - numberofcmps++; - } - else if (numberofcmps > 0) - { - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - numberofcmps = 0; - } - else - { - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - numberofcmps = 0; - } - } -#ifdef SUPPORT_UNICODE - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - if (*cc == XCL_NOTPROP) - invertcmp ^= 0x1; - cc++; - switch(*cc) - { - case PT_ANY: - if (!invertcmp) - jump = JUMP(SLJIT_JUMP); - break; - - case PT_LAMP: - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_GC: - c = PRIV(ucp_typerange)[(int)cc[1] * 2]; - SET_TYPE_OFFSET(c); - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); - break; - - case PT_PC: - jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); - break; - - case PT_SC: - compares++; - /* Do nothing. */ - break; - - case PT_SPACE: - case PT_PXSPACE: - SET_CHAR_OFFSET(9); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - SET_TYPE_OFFSET(ucp_Zl); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_WORD: - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - /* Fall through. */ - - case PT_ALNUM: - SET_TYPE_OFFSET(ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); - SET_TYPE_OFFSET(ucp_Nd); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_CLIST: - other_cases = PRIV(ucd_caseless_sets) + cc[1]; - - /* At least three characters are required. - Otherwise this case would be handled by the normal code path. */ - SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); - SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); - - /* Optimizing character pairs, if their difference is power of 2. */ - if (is_powerof2(other_cases[1] ^ other_cases[0])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - other_cases += 2; - } - else if (is_powerof2(other_cases[2] ^ other_cases[1])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); - OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - other_cases += 3; - } - else - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - } - - while (*other_cases != NOTACHAR) - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); - OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); - } - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_UCNC: - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - SET_CHAR_OFFSET(0xa0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - SET_CHAR_OFFSET(0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_PXGRAPH: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); - - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); - - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPRINT: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); - OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); - - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); - - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPUNCT: - SET_TYPE_OFFSET(ucp_Sc); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f); - OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_TYPE_OFFSET(ucp_Pc); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - cc += 2; - } -#endif - - if (jump != NULL) - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - -if (found != NULL) - set_jumps(found, LABEL()); -} - -#undef SET_TYPE_OFFSET -#undef SET_CHAR_OFFSET - -#endif - -static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -int length; -struct sljit_jump *jump[4]; -#ifdef SUPPORT_UNICODE -struct sljit_label *label; -#endif /* SUPPORT_UNICODE */ - -switch(type) - { - case OP_SOD: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_SOM: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - - case OP_EODN: - /* Requires rather complex checks. */ - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else if (common->nltype == NLTYPE_FIXED) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); - } - else - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); - jump[2] = JUMP(SLJIT_GREATER); - add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); - /* Equal. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - - JUMPHERE(jump[1]); - if (common->nltype == NLTYPE_ANYCRLF) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - } - else - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); - add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); - } - JUMPHERE(jump[2]); - JUMPHERE(jump[3]); - } - JUMPHERE(jump[0]); - check_partial(common, FALSE); - return cc; - - case OP_EOD: - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); - return cc; - - case OP_CIRC: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - return cc; - - case OP_CIRCM: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); - - if (!common->alt_circumflex) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - skip_char_back(common); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } - JUMPHERE(jump[0]); - return cc; - - case OP_DOLL: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - - if (!common->endonly) - compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); - else - { - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); - } - return cc; - - case OP_DOLLM: - jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - check_partial(common, FALSE); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); - /* STR_PTR = STR_END - IN_UCHARS(1) */ - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - peek_char(common, common->nlmax); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } - JUMPHERE(jump[0]); - return cc; - - case OP_REVERSE: - length = GET(cc, 0); - if (length == 0) - return cc + LINK_SIZE; - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -#ifdef SUPPORT_UNICODE - if (common->utf) - { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); - label = LABEL(); - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); - skip_char_back(common); - OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else -#endif - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); - } - check_start_used_ptr(common); - return cc + LINK_SIZE; - } -SLJIT_ASSERT_STOP(); -return cc; -} - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) -{ -DEFINE_COMPILER; -int length; -unsigned int c, oc, bit; -compare_context context; -struct sljit_jump *jump[3]; -jump_list *end_list; -#ifdef SUPPORT_UNICODE -struct sljit_label *label; -PCRE2_UCHAR propdata[5]; -#endif /* SUPPORT_UNICODE */ - -switch(type) - { - case OP_NOT_DIGIT: - case OP_DIGIT: - /* Digits are usually 0-9, so it is worth to optimize them. */ - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_digit, FALSE)) - read_char7_type(common, type == OP_NOT_DIGIT); - else -#endif - read_char8_type(common, type == OP_NOT_DIGIT); - /* Flip the starting bit in the negative case. */ - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); - add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_space, FALSE)) - read_char7_type(common, type == OP_NOT_WHITESPACE); - else -#endif - read_char8_type(common, type == OP_NOT_WHITESPACE); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); - add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_word, FALSE)) - read_char7_type(common, type == OP_NOT_WORDCHAR); - else -#endif - read_char8_type(common, type == OP_NOT_WORDCHAR); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); - add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_ANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[0]); - } - else - check_newlinechar(common, common->nltype, backtracks, TRUE); - return cc; - - case OP_ALLANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#endif - JUMPHERE(jump[0]); -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ - return cc; - } -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - - case OP_ANYBYTE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - -#ifdef SUPPORT_UNICODE - case OP_NOTPROP: - case OP_PROP: - propdata[0] = XCL_HASPROP; - propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; - propdata[2] = cc[0]; - propdata[3] = cc[1]; - propdata[4] = XCL_END; - if (check_str_ptr) - detect_partial_match(common, backtracks); - compile_xclass_matchingpath(common, propdata, backtracks); - return cc + 2; -#endif - - case OP_ANYNL: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - /* We don't need to handle soft partial matching case. */ - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[2] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[0]); - check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[1]); - JUMPHERE(jump[2]); - return cc; - - case OP_NOT_HSPACE: - case OP_HSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); - add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - - case OP_NOT_VSPACE: - case OP_VSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); - add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - -#ifdef SUPPORT_UNICODE - case OP_EXTUNI: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char(common); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - /* Optimize register allocation: use a real register. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - label = LABEL(); - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - read_char(common); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); - OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); - OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - JUMPTO(SLJIT_NOT_ZERO, label); - - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - JUMPHERE(jump[0]); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); - - if (common->mode == PCRE2_JIT_PARTIAL_HARD) - { - jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - /* Since we successfully read a char above, partial matching must occure. */ - check_partial(common, TRUE); - JUMPHERE(jump[0]); - } - return cc; -#endif - - case OP_CHAR: - case OP_CHARI: - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); -#endif - if (common->mode == PCRE2_JIT_COMPLETE && check_str_ptr - && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) - { - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.length = IN_UCHARS(length); - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); - } - - if (check_str_ptr) - detect_partial_match(common, backtracks); -#ifdef SUPPORT_UNICODE - if (common->utf) - { - GETCHAR(c, cc); - } - else -#endif - c = *cc; - - if (type == OP_CHAR || !char_has_othercase(common, cc)) - { - read_char_range(common, c, c, FALSE); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - return cc + length; - } - oc = char_othercase(common, c); - read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE); - bit = c ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); - return cc + length; - } - jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - JUMPHERE(jump[0]); - return cc + length; - - case OP_NOT: - case OP_NOTI: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - c = *cc; - if (c < 128) - { - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - if (type == OP_NOT || !char_has_othercase(common, cc)) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - else - { - /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); - } - /* Skip the variable-length character. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(jump[0]); - return cc + 1; - } - else -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - { - GETCHARLEN(c, cc, length); - } - } - else -#endif /* SUPPORT_UNICODE */ - c = *cc; - - if (type == OP_NOT || !char_has_othercase(common, cc)) - { - read_char_range(common, c, c, TRUE); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - } - else - { - oc = char_othercase(common, c); - read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE); - bit = c ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); - } - else - { - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - } - } - return cc + length; - - case OP_CLASS: - case OP_NCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - bit = (common->utf && is_char7_bitset((const sljit_ub *)cc, type == OP_NCLASS)) ? 127 : 255; - read_char_range(common, 0, bit, type == OP_NCLASS); -#else - read_char_range(common, 0, 255, type == OP_NCLASS); -#endif - - if (check_class_ranges(common, (const sljit_ub *)cc, type == OP_NCLASS, FALSE, backtracks)) - return cc + 32 / sizeof(PCRE2_UCHAR); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = NULL; - if (common->utf) - { - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); - if (type == OP_CLASS) - { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; - } - } -#elif PCRE2_CODE_UNIT_WIDTH != 8 - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (type == OP_CLASS) - { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; - } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - if (jump[0] != NULL) - JUMPHERE(jump[0]); -#endif - return cc + 32 / sizeof(PCRE2_UCHAR); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - case OP_XCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); - return cc + GET(cc, 0) - 1; -#endif - } -SLJIT_ASSERT_STOP(); -return cc; -} - -static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) -{ -/* This function consumes at least one input character. */ -/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ -DEFINE_COMPILER; -PCRE2_SPTR ccbegin = cc; -compare_context context; -int size; - -context.length = 0; -do - { - if (cc >= ccend) - break; - - if (*cc == OP_CHAR) - { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); -#endif - } - else if (*cc == OP_CHARI) - { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) - { - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; - else if (HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); - } - else -#endif - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; - } - else - size = 0; - - cc += 1 + size; - context.length += IN_UCHARS(size); - } -while (size > 0 && context.length <= 128); - -cc = ccbegin; -if (context.length > 0) - { - /* We have a fixed-length byte sequence. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); - return cc; - } - -/* A non-fixed length character will be checked if length == 0. */ -return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); -} - -/* Forward definitions. */ -static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *); -static void compile_backtrackingpath(compiler_common *, struct backtrack_common *); - -#define PUSH_BACKTRACK(size, ccstart, error) \ - do \ - { \ - backtrack = sljit_alloc_memory(compiler, (size)); \ - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ - return error; \ - memset(backtrack, 0, size); \ - backtrack->prev = parent->top; \ - backtrack->cc = (ccstart); \ - parent->top = backtrack; \ - } \ - while (0) - -#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ - do \ - { \ - backtrack = sljit_alloc_memory(compiler, (size)); \ - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ - return; \ - memset(backtrack, 0, size); \ - backtrack->prev = parent->top; \ - backtrack->cc = (ccstart); \ - parent->top = backtrack; \ - } \ - while (0) - -#define BACKTRACK_AS(type) ((type *)backtrack) - -static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) -{ -/* The OVECTOR offset goes to TMP2. */ -DEFINE_COMPILER; -int count = GET2(cc, 1 + IMM2_SIZE); -PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size; -unsigned int offset; -jump_list *found = NULL; - -SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI); - -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); - -count--; -while (count-- > 0) - { - offset = GET2(slot, 0) << 1; - GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); - add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); - slot += common->name_entry_size; - } - -offset = GET2(slot, 0) << 1; -GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); -if (backtracks != NULL && !common->unset_backref) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); - -set_jumps(found, LABEL()); -} - -static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) -{ -DEFINE_COMPILER; -BOOL ref = (*cc == OP_REF || *cc == OP_REFI); -int offset = 0; -struct sljit_jump *jump = NULL; -struct sljit_jump *partial; -struct sljit_jump *nopartial; - -if (ref) - { - offset = GET2(cc, 1) << 1; - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - /* OVECTOR(1) contains the "string begin - 1" constant. */ - if (withchecks && !common->unset_backref) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); - } -else - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - -#if defined SUPPORT_UNICODE -if (common->utf && *cc == OP_REFI) - { - SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2); - if (ref) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - else - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - - if (withchecks) - jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0); - - /* Needed to save important temporary registers. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), STR_PTR, 0); - sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); - else - { - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); - nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); - check_partial(common, FALSE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(nopartial); - } - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); - } -else -#endif /* SUPPORT_UNICODE */ - { - if (ref) - OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); - else - OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); - - if (withchecks) - jump = JUMP(SLJIT_ZERO); - - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, partial); - - add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); - - if (common->mode != PCRE2_JIT_COMPLETE) - { - nopartial = JUMP(SLJIT_JUMP); - JUMPHERE(partial); - /* TMP2 -= STR_END - STR_PTR */ - OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); - partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); - add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); - JUMPHERE(partial); - check_partial(common, FALSE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(nopartial); - } - } - -if (jump != NULL) - { - if (emptyfail) - add_jump(compiler, backtracks, jump); - else - JUMPHERE(jump); - } -} - -static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -BOOL ref = (*cc == OP_REF || *cc == OP_REFI); -backtrack_common *backtrack; -PCRE2_UCHAR type; -int offset = 0; -struct sljit_label *label; -struct sljit_jump *zerolength; -struct sljit_jump *jump = NULL; -PCRE2_SPTR ccbegin = cc; -int min = 0, max = 0; -BOOL minimize; - -PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL); - -if (ref) - offset = GET2(cc, 1) << 1; -else - cc += IMM2_SIZE; -type = cc[1 + IMM2_SIZE]; - -SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); -minimize = (type & 0x1) != 0; -switch(type) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - min = 0; - max = 0; - cc += 1 + IMM2_SIZE + 1; - break; - case OP_CRPLUS: - case OP_CRMINPLUS: - min = 1; - max = 0; - cc += 1 + IMM2_SIZE + 1; - break; - case OP_CRQUERY: - case OP_CRMINQUERY: - min = 0; - max = 1; - cc += 1 + IMM2_SIZE + 1; - break; - case OP_CRRANGE: - case OP_CRMINRANGE: - min = GET2(cc, 1 + IMM2_SIZE + 1); - max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); - cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; - break; - default: - SLJIT_ASSERT_STOP(); - break; - } - -if (!minimize) - { - if (min == 0) - { - allocate_stack(common, 2); - if (ref) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); - /* Temporary release of STR_PTR. */ - OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - /* Handles both invalid and empty cases. Since the minimum repeat, - is zero the invalid case is basically the same as an empty case. */ - if (ref) - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - else - { - compile_dnref_search(common, ccbegin, NULL); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - } - /* Restore if not zero length. */ - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - } - else - { - allocate_stack(common, 1); - if (ref) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - if (ref) - { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - } - else - { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - } - } - - if (min > 1 || max > 1) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); - - label = LABEL(); - if (!ref) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); - compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); - - if (min > 1 || max > 1) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); - if (min > 1) - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); - if (max > 1) - { - jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); - JUMPHERE(jump); - } - } - - if (max == 0) - { - /* Includes min > 1 case as well. */ - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); - } - - JUMPHERE(zerolength); - BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); - - count_match(common); - return cc; - } - -allocate_stack(common, ref ? 2 : 3); -if (ref) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); -if (type != OP_CRMINSTAR) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); - -if (min == 0) - { - /* Handles both invalid and empty cases. Since the minimum repeat, - is zero the invalid case is basically the same as an empty case. */ - if (ref) - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - else - { - compile_dnref_search(common, ccbegin, NULL); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - } - /* Length is non-zero, we can match real repeats. */ - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - jump = JUMP(SLJIT_JUMP); - } -else - { - if (ref) - { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - } - else - { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); - zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - } - } - -BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); -if (max > 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); - -if (!ref) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); -compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - -if (min > 1) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath); - } -else if (max > 0) - OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); - -if (jump != NULL) - JUMPHERE(jump); -JUMPHERE(zerolength); - -count_match(common); -return cc; -} - -static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -recurse_entry *entry = common->entries; -recurse_entry *prev = NULL; -sljit_sw start = GET(cc, 1); -PCRE2_SPTR start_cc; -BOOL needs_control_head; - -PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); - -/* Inlining simple patterns. */ -if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) - { - start_cc = common->start + start; - compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); - BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE; - return cc + 1 + LINK_SIZE; - } - -while (entry != NULL) - { - if (entry->start == start) - break; - prev = entry; - entry = entry->next; - } - -if (entry == NULL) - { - entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - entry->next = NULL; - entry->entry = NULL; - entry->calls = NULL; - entry->start = start; - - if (prev != NULL) - prev->next = entry; - else - common->entries = entry; - } - -if (common->has_set_som && common->mark_ptr != 0) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); - allocate_stack(common, 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - } -else if (common->has_set_som || common->mark_ptr != 0) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - } - -if (entry->entry == NULL) - add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); -else - JUMPTO(SLJIT_FAST_CALL, entry->entry); -/* Leave if the match is failed. */ -add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); -return cc + 1 + LINK_SIZE; -} - -static int SLJIT_CALL do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) -{ -PCRE2_SPTR begin = arguments->begin; -PCRE2_SIZE *ovector = arguments->match_data->ovector; -uint32_t oveccount = arguments->oveccount; -uint32_t i; - -if (arguments->callout == NULL) - return 0; - -callout_block->version = 1; - -/* Offsets in subject. */ -callout_block->subject_length = arguments->end - arguments->begin; -callout_block->start_match = (PCRE2_SPTR)callout_block->subject - arguments->begin; -callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - arguments->begin; -callout_block->subject = begin; - -/* Convert and copy the JIT offset vector to the ovector array. */ -callout_block->capture_top = 0; -callout_block->offset_vector = ovector; -for (i = 2; i < oveccount; i += 2) - { - ovector[i] = jit_ovector[i] - begin; - ovector[i + 1] = jit_ovector[i + 1] - begin; - if (jit_ovector[i] >= begin) - callout_block->capture_top = i; - } - -callout_block->capture_top = (callout_block->capture_top >> 1) + 1; -ovector[0] = PCRE2_UNSET; -ovector[1] = PCRE2_UNSET; -return (arguments->callout)(callout_block, arguments->callout_data); -} - -/* Aligning to 8 byte. */ -#define CALLOUT_ARG_SIZE \ - (((int)sizeof(pcre2_callout_block) + 7) & ~7) - -#define CALLOUT_ARG_OFFSET(arg) \ - (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(pcre2_callout_block, arg)) - -static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -sljit_si mov_opcode; -unsigned int callout_length = (*cc == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE); -sljit_sw value1; -sljit_sw value2; -sljit_sw value3; - -PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); - -allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); - -SLJIT_ASSERT(common->capture_last_ptr != 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0; -OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1); -OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); - -/* These pointer sized fields temporarly stores internal variables. */ -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); - -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); -mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; -OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1)); -OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE)); - -if (*cc == OP_CALLOUT) - { - value1 = 0; - value2 = 0; - value3 = 0; - } -else - { - value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1); - value2 = (callout_length - (1 + 4*LINK_SIZE + 2)); - value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE)); - } - -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1); -OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2); -OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0); - -/* Needed to save important temporary registers. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); -OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); -GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); -sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); -OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); -free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); - -/* Check return value. */ -OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER)); -if (common->forced_quit_label == NULL) - add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS)); -else - JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label); -return cc + callout_length; -} - -#undef CALLOUT_ARG_SIZE -#undef CALLOUT_ARG_OFFSET - -static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc) -{ -while (TRUE) - { - switch (*cc) - { - case OP_CALLOUT_STR: - cc += GET(cc, 1 + 2*LINK_SIZE); - break; - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_CALLOUT: - case OP_ALT: - cc += PRIV(OP_lengths)[*cc]; - break; - - case OP_KET: - return FALSE; - - default: - return TRUE; - } - } -} - -static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional) -{ -DEFINE_COMPILER; -int framesize; -int extrasize; -BOOL needs_control_head; -int private_data_ptr; -backtrack_common altbacktrack; -PCRE2_SPTR ccbegin; -PCRE2_UCHAR opcode; -PCRE2_UCHAR bra = OP_BRA; -jump_list *tmp = NULL; -jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; -jump_list **found; -/* Saving previous accept variables. */ -BOOL save_local_exit = common->local_exit; -BOOL save_positive_assert = common->positive_assert; -then_trap_backtrack *save_then_trap = common->then_trap; -struct sljit_label *save_quit_label = common->quit_label; -struct sljit_label *save_accept_label = common->accept_label; -jump_list *save_quit = common->quit; -jump_list *save_positive_assert_quit = common->positive_assert_quit; -jump_list *save_accept = common->accept; -struct sljit_jump *jump; -struct sljit_jump *brajump = NULL; - -/* Assert captures then. */ -common->then_trap = NULL; - -if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) - { - SLJIT_ASSERT(!conditional); - bra = *cc; - cc++; - } -private_data_ptr = PRIVATE_DATA(cc); -SLJIT_ASSERT(private_data_ptr != 0); -framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); -backtrack->framesize = framesize; -backtrack->private_data_ptr = private_data_ptr; -opcode = *cc; -SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); -found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; -ccbegin = cc; -cc += GET(cc, 1); - -if (bra == OP_BRAMINZERO) - { - /* This is a braminzero backtrack path. */ - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - } - -if (framesize < 0) - { - extrasize = 1; - if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) - extrasize = 0; - - if (needs_control_head) - extrasize++; - - if (framesize == no_frame) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); - - if (extrasize > 0) - allocate_stack(common, extrasize); - - if (needs_control_head) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - - if (extrasize > 0) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - - if (needs_control_head) - { - SLJIT_ASSERT(extrasize == 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - } - } -else - { - extrasize = needs_control_head ? 3 : 2; - allocate_stack(common, framesize + extrasize); - - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); - if (needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - - if (needs_control_head) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); - } - else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - - init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); - } - -memset(&altbacktrack, 0, sizeof(backtrack_common)); -if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - /* Negative assert is stronger than positive assert. */ - common->local_exit = TRUE; - common->quit_label = NULL; - common->quit = NULL; - common->positive_assert = FALSE; - } -else - common->positive_assert = TRUE; -common->positive_assert_quit = NULL; - -while (1) - { - common->accept_label = NULL; - common->accept = NULL; - altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; - - if (*ccbegin == OP_ALT && extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - - altbacktrack.cc = ccbegin; - compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - common->local_exit = save_local_exit; - common->quit_label = save_quit_label; - common->quit = save_quit; - } - common->positive_assert = save_positive_assert; - common->then_trap = save_then_trap; - common->accept_label = save_accept_label; - common->positive_assert_quit = save_positive_assert_quit; - common->accept = save_accept; - return NULL; - } - common->accept_label = LABEL(); - if (common->accept != NULL) - set_jumps(common->accept, common->accept_label); - - /* Reset stack. */ - if (framesize < 0) - { - if (framesize == no_frame) - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - else if (extrasize > 0) - free_stack(common, extrasize); - - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); - } - else - { - if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) - { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); - } - else - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - } - } - - if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - /* We know that STR_PTR was stored on the top of the stack. */ - if (conditional) - { - if (extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); - } - else if (bra == OP_BRAZERO) - { - if (framesize < 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - } - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else if (framesize >= 0) - { - /* For OP_BRA and OP_BRAMINZERO. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); - } - } - add_jump(compiler, found, JUMP(SLJIT_JUMP)); - - compile_backtrackingpath(common, altbacktrack.top); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - common->local_exit = save_local_exit; - common->quit_label = save_quit_label; - common->quit = save_quit; - } - common->positive_assert = save_positive_assert; - common->then_trap = save_then_trap; - common->accept_label = save_accept_label; - common->positive_assert_quit = save_positive_assert_quit; - common->accept = save_accept; - return NULL; - } - set_jumps(altbacktrack.topbacktracks, LABEL()); - - if (*cc != OP_ALT) - break; - - ccbegin = cc; - cc += GET(cc, 1); - } - -if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - SLJIT_ASSERT(common->positive_assert_quit == NULL); - /* Makes the check less complicated below. */ - common->positive_assert_quit = common->quit; - } - -/* None of them matched. */ -if (common->positive_assert_quit != NULL) - { - jump = JUMP(SLJIT_JUMP); - set_jumps(common->positive_assert_quit, LABEL()); - SLJIT_ASSERT(framesize != no_stack); - if (framesize < 0) - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); - else - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); - } - JUMPHERE(jump); - } - -if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); - -if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) - { - /* Assert is failed. */ - if ((conditional && extrasize > 0) || bra == OP_BRAZERO) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - - if (framesize < 0) - { - /* The topmost item should be 0. */ - if (bra == OP_BRAZERO) - { - if (extrasize == 2) - free_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else if (extrasize > 0) - free_stack(common, extrasize); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); - /* The topmost item should be 0. */ - if (bra == OP_BRAZERO) - { - free_stack(common, framesize + extrasize - 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else - free_stack(common, framesize + extrasize); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - } - jump = JUMP(SLJIT_JUMP); - if (bra != OP_BRAZERO) - add_jump(compiler, target, jump); - - /* Assert is successful. */ - set_jumps(tmp, LABEL()); - if (framesize < 0) - { - /* We know that STR_PTR was stored on the top of the stack. */ - if (extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); - - /* Keep the STR_PTR on the top of the stack. */ - if (bra == OP_BRAZERO) - { - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - if (extrasize == 2) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - } - else if (bra == OP_BRAMINZERO) - { - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - } - else - { - if (bra == OP_BRA) - { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw)); - } - else - { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); - if (extrasize == 2) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - if (bra == OP_BRAMINZERO) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); - } - } - } - - if (bra == OP_BRAZERO) - { - backtrack->matchingpath = LABEL(); - SET_LABEL(jump, backtrack->matchingpath); - } - else if (bra == OP_BRAMINZERO) - { - JUMPTO(SLJIT_JUMP, backtrack->matchingpath); - JUMPHERE(brajump); - if (framesize >= 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); - } - set_jumps(backtrack->common.topbacktracks, LABEL()); - } - } -else - { - /* AssertNot is successful. */ - if (framesize < 0) - { - if (extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - - if (bra != OP_BRA) - { - if (extrasize == 2) - free_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else if (extrasize > 0) - free_stack(common, extrasize); - } - else - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); - /* The topmost item should be 0. */ - if (bra != OP_BRA) - { - free_stack(common, framesize + extrasize - 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else - free_stack(common, framesize + extrasize); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - } - - if (bra == OP_BRAZERO) - backtrack->matchingpath = LABEL(); - else if (bra == OP_BRAMINZERO) - { - JUMPTO(SLJIT_JUMP, backtrack->matchingpath); - JUMPHERE(brajump); - } - - if (bra != OP_BRA) - { - SLJIT_ASSERT(found == &backtrack->common.topbacktracks); - set_jumps(backtrack->common.topbacktracks, LABEL()); - backtrack->common.topbacktracks = NULL; - } - } - -if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) - { - common->local_exit = save_local_exit; - common->quit_label = save_quit_label; - common->quit = save_quit; - } -common->positive_assert = save_positive_assert; -common->then_trap = save_then_trap; -common->accept_label = save_accept_label; -common->positive_assert_quit = save_positive_assert_quit; -common->accept = save_accept; -return cc + 1 + LINK_SIZE; -} - -static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head) -{ -DEFINE_COMPILER; -int stacksize; - -if (framesize < 0) - { - if (framesize == no_frame) - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - else - { - stacksize = needs_control_head ? 1 : 0; - if (ket != OP_KET || has_alternatives) - stacksize++; - - if (stacksize > 0) - free_stack(common, stacksize); - } - - if (needs_control_head) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0); - - /* TMP2 which is set here used by OP_KETRMAX below. */ - if (ket == OP_KETRMAX) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); - else if (ket == OP_KETRMIN) - { - /* Move the STR_PTR to the private_data_ptr. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); - } - } -else - { - stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1; - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw)); - if (needs_control_head) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0); - - if (ket == OP_KETRMAX) - { - /* TMP2 which is set here used by OP_KETRMAX below. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - } - } -if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); -} - -static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr) -{ -DEFINE_COMPILER; - -if (common->capture_last_ptr != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); - stacksize++; - } -if (common->optimized_cbracket[offset >> 1] == 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - stacksize += 2; - } -return stacksize; -} - -/* - Handling bracketed expressions is probably the most complex part. - - Stack layout naming characters: - S - Push the current STR_PTR - 0 - Push a 0 (NULL) - A - Push the current STR_PTR. Needed for restoring the STR_PTR - before the next alternative. Not pushed if there are no alternatives. - M - Any values pushed by the current alternative. Can be empty, or anything. - C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. - L - Push the previous local (pointed by localptr) to the stack - () - opional values stored on the stack - ()* - optonal, can be stored multiple times - - The following list shows the regular expression templates, their PCRE byte codes - and stack layout supported by pcre-sljit. - - (?:) OP_BRA | OP_KET A M - () OP_CBRA | OP_KET C M - (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* - OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* - (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* - OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* - ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* - OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* - ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* - OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* - (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) - (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) - ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) - ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) - (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* - OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* - (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* - OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* - ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* - OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* - ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* - OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* - - - Stack layout naming characters: - A - Push the alternative index (starting from 0) on the stack. - Not pushed if there is no alternatives. - M - Any values pushed by the current alternative. Can be empty, or anything. - - The next list shows the possible content of a bracket: - (|) OP_*BRA | OP_ALT ... M A - (?()|) OP_*COND | OP_ALT M A - (?>|) OP_ONCE | OP_ALT ... [stack trace] M A - (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A - Or nothing, if trace is unnecessary -*/ - -static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -PCRE2_UCHAR opcode; -int private_data_ptr = 0; -int offset = 0; -int i, stacksize; -int repeat_ptr = 0, repeat_length = 0; -int repeat_type = 0, repeat_count = 0; -PCRE2_SPTR ccbegin; -PCRE2_SPTR matchingpath; -PCRE2_SPTR slot; -PCRE2_UCHAR bra = OP_BRA; -PCRE2_UCHAR ket; -assert_backtrack *assert; -BOOL has_alternatives; -BOOL needs_control_head = FALSE; -struct sljit_jump *jump; -struct sljit_jump *skip; -struct sljit_label *rmax_label = NULL; -struct sljit_jump *braminzero = NULL; - -PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); - -if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) - { - bra = *cc; - cc++; - opcode = *cc; - } - -opcode = *cc; -ccbegin = cc; -matchingpath = bracketend(cc) - 1 - LINK_SIZE; -ket = *matchingpath; -if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0) - { - repeat_ptr = PRIVATE_DATA(matchingpath); - repeat_length = PRIVATE_DATA(matchingpath + 1); - repeat_type = PRIVATE_DATA(matchingpath + 2); - repeat_count = PRIVATE_DATA(matchingpath + 3); - SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0); - if (repeat_type == OP_UPTO) - ket = OP_KETRMAX; - if (repeat_type == OP_MINUPTO) - ket = OP_KETRMIN; - } - -matchingpath = ccbegin + 1 + LINK_SIZE; -SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); -SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); -cc += GET(cc, 1); - -has_alternatives = *cc == OP_ALT; -if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) - { - SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3, - compile_time_checks_must_be_grouped_together); - has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE; - } - -if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) - opcode = OP_SCOND; -if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) - opcode = OP_ONCE; - -if (opcode == OP_CBRA || opcode == OP_SCBRA) - { - /* Capturing brackets has a pre-allocated space. */ - offset = GET2(ccbegin, 1 + LINK_SIZE); - if (common->optimized_cbracket[offset] == 0) - { - private_data_ptr = OVECTOR_PRIV(offset); - offset <<= 1; - } - else - { - offset <<= 1; - private_data_ptr = OVECTOR(offset); - } - BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; - matchingpath += IMM2_SIZE; - } -else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) - { - /* Other brackets simply allocate the next entry. */ - private_data_ptr = PRIVATE_DATA(ccbegin); - SLJIT_ASSERT(private_data_ptr != 0); - BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; - if (opcode == OP_ONCE) - BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); - } - -/* Instructions before the first alternative. */ -stacksize = 0; -if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) - stacksize++; -if (bra == OP_BRAZERO) - stacksize++; - -if (stacksize > 0) - allocate_stack(common, stacksize); - -stacksize = 0; -if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); - stacksize++; - } - -if (bra == OP_BRAZERO) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - -if (bra == OP_BRAMINZERO) - { - /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - if (ket != OP_KETRMIN) - { - free_stack(common, 1); - braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - } - else - { - if (opcode == OP_ONCE || opcode >= OP_SBRA) - { - jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - /* Nothing stored during the first run. */ - skip = JUMP(SLJIT_JUMP); - JUMPHERE(jump); - /* Checking zero-length iteration. */ - if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) - { - /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ - braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - } - else - { - /* Except when the whole stack frame must be saved. */ - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); - } - JUMPHERE(skip); - } - else - { - jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - JUMPHERE(jump); - } - } - } - -if (repeat_type != 0) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count); - if (repeat_type == OP_EXACT) - rmax_label = LABEL(); - } - -if (ket == OP_KETRMIN) - BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); - -if (ket == OP_KETRMAX) - { - rmax_label = LABEL(); - if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; - } - -/* Handling capturing brackets and alternatives. */ -if (opcode == OP_ONCE) - { - stacksize = 0; - if (needs_control_head) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - stacksize++; - } - - if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) - { - /* Neither capturing brackets nor recursions are found in the block. */ - if (ket == OP_KETRMIN) - { - stacksize += 2; - if (!needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - } - else - { - if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); - if (ket == OP_KETRMAX || has_alternatives) - stacksize++; - } - - if (stacksize > 0) - allocate_stack(common, stacksize); - - stacksize = 0; - if (needs_control_head) - { - stacksize++; - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - } - - if (ket == OP_KETRMIN) - { - if (needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); - } - else if (ket == OP_KETRMAX || has_alternatives) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - } - else - { - if (ket != OP_KET || has_alternatives) - stacksize++; - - stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1; - allocate_stack(common, stacksize); - - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); - - stacksize = needs_control_head ? 1 : 0; - if (ket != OP_KET || has_alternatives) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); - stacksize++; - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); - } - else - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); - } - init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); - } - } -else if (opcode == OP_CBRA || opcode == OP_SCBRA) - { - /* Saving the previous values. */ - if (common->optimized_cbracket[offset >> 1] != 0) - { - SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); - allocate_stack(common, 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - } - else - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - } - } -else if (opcode == OP_SBRA || opcode == OP_SCOND) - { - /* Saving the previous value. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - } -else if (has_alternatives) - { - /* Pushing the starting string pointer. */ - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - } - -/* Generating code for the first alternative. */ -if (opcode == OP_COND || opcode == OP_SCOND) - { - if (*matchingpath == OP_CREF) - { - SLJIT_ASSERT(has_alternatives); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), - CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); - matchingpath += 1 + IMM2_SIZE; - } - else if (*matchingpath == OP_DNCREF) - { - SLJIT_ASSERT(has_alternatives); - - i = GET2(matchingpath, 1 + IMM2_SIZE); - slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); - OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); - slot += common->name_entry_size; - i--; - while (i-- > 0) - { - OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); - OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0); - slot += common->name_entry_size; - } - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); - matchingpath += 1 + 2 * IMM2_SIZE; - } - else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) - { - /* Never has other case. */ - BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; - SLJIT_ASSERT(!has_alternatives); - - if (*matchingpath == OP_TRUE) - { - stacksize = 1; - matchingpath++; - } - else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL) - stacksize = 0; - else if (*matchingpath == OP_RREF) - { - stacksize = GET2(matchingpath, 1); - if (common->currententry == NULL) - stacksize = 0; - else if (stacksize == RREF_ANY) - stacksize = 1; - else if (common->currententry->start == 0) - stacksize = stacksize == 0; - else - stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); - - if (stacksize != 0) - matchingpath += 1 + IMM2_SIZE; - } - else - { - if (common->currententry == NULL || common->currententry->start == 0) - stacksize = 0; - else - { - stacksize = GET2(matchingpath, 1 + IMM2_SIZE); - slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; - i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); - while (stacksize > 0) - { - if ((int)GET2(slot, 0) == i) - break; - slot += common->name_entry_size; - stacksize--; - } - } - - if (stacksize != 0) - matchingpath += 1 + 2 * IMM2_SIZE; - } - - /* The stacksize == 0 is a common "else" case. */ - if (stacksize == 0) - { - if (*cc == OP_ALT) - { - matchingpath = cc + 1 + LINK_SIZE; - cc += GET(cc, 1); - } - else - matchingpath = cc; - } - } - else - { - SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT); - /* Similar code as PUSH_BACKTRACK macro. */ - assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - memset(assert, 0, sizeof(assert_backtrack)); - assert->common.cc = matchingpath; - BACKTRACK_AS(bracket_backtrack)->u.assert = assert; - matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE); - } - } - -compile_matchingpath(common, matchingpath, cc, backtrack); -if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - -if (opcode == OP_ONCE) - match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); - -stacksize = 0; -if (repeat_type == OP_MINUPTO) - { - /* We need to preserve the counter. TMP2 will be used below. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); - stacksize++; - } -if (ket != OP_KET || bra != OP_BRA) - stacksize++; -if (offset != 0) - { - if (common->capture_last_ptr != 0) - stacksize++; - if (common->optimized_cbracket[offset >> 1] == 0) - stacksize += 2; - } -if (has_alternatives && opcode != OP_ONCE) - stacksize++; - -if (stacksize > 0) - allocate_stack(common, stacksize); - -stacksize = 0; -if (repeat_type == OP_MINUPTO) - { - /* TMP2 was set above. */ - OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); - stacksize++; - } - -if (ket != OP_KET || bra != OP_BRA) - { - if (ket != OP_KET) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); - stacksize++; - } - -if (offset != 0) - stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); - -if (has_alternatives) - { - if (opcode != OP_ONCE) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); - if (ket != OP_KETRMAX) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); - } - -/* Must be after the matchingpath label. */ -if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) - { - SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); - } - -if (ket == OP_KETRMAX) - { - if (repeat_type != 0) - { - if (has_alternatives) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, rmax_label); - /* Drop STR_PTR for greedy plus quantifier. */ - if (opcode != OP_ONCE) - free_stack(common, 1); - } - else if (opcode == OP_ONCE || opcode >= OP_SBRA) - { - if (has_alternatives) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); - /* Checking zero-length iteration. */ - if (opcode != OP_ONCE) - { - CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); - /* Drop STR_PTR for greedy plus quantifier. */ - if (bra != OP_BRAZERO) - free_stack(common, 1); - } - else - /* TMP2 must contain the starting STR_PTR. */ - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); - } - else - JUMPTO(SLJIT_JUMP, rmax_label); - BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); - } - -if (repeat_type == OP_EXACT) - { - count_match(common); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, rmax_label); - } -else if (repeat_type == OP_UPTO) - { - /* We need to preserve the counter. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - } - -if (bra == OP_BRAZERO) - BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); - -if (bra == OP_BRAMINZERO) - { - /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ - JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); - if (braminzero != NULL) - { - JUMPHERE(braminzero); - /* We need to release the end pointer to perform the - backtrack for the zero-length iteration. When - framesize is < 0, OP_ONCE will do the release itself. */ - if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - } - else if (ket == OP_KETRMIN && opcode != OP_ONCE) - free_stack(common, 1); - } - /* Continue to the normal backtrack. */ - } - -if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) - count_match(common); - -/* Skip the other alternatives. */ -while (*cc == OP_ALT) - cc += GET(cc, 1); -cc += 1 + LINK_SIZE; - -if (opcode == OP_ONCE) - { - /* We temporarily encode the needs_control_head in the lowest bit. - Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns - the same value for small signed numbers (including negative numbers). */ - BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); - } -return cc + repeat_length; -} - -static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -PCRE2_UCHAR opcode; -int private_data_ptr; -int cbraprivptr = 0; -BOOL needs_control_head; -int framesize; -int stacksize; -int offset = 0; -BOOL zero = FALSE; -PCRE2_SPTR ccbegin = NULL; -int stack; /* Also contains the offset of control head. */ -struct sljit_label *loop = NULL; -struct jump_list *emptymatch = NULL; - -PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); -if (*cc == OP_BRAPOSZERO) - { - zero = TRUE; - cc++; - } - -opcode = *cc; -private_data_ptr = PRIVATE_DATA(cc); -SLJIT_ASSERT(private_data_ptr != 0); -BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr; -switch(opcode) - { - case OP_BRAPOS: - case OP_SBRAPOS: - ccbegin = cc + 1 + LINK_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - offset = GET2(cc, 1 + LINK_SIZE); - /* This case cannot be optimized in the same was as - normal capturing brackets. */ - SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); - cbraprivptr = OVECTOR_PRIV(offset); - offset <<= 1; - ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - -framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); -BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; -if (framesize < 0) - { - if (offset != 0) - { - stacksize = 2; - if (common->capture_last_ptr != 0) - stacksize++; - } - else - stacksize = 1; - - if (needs_control_head) - stacksize++; - if (!zero) - stacksize++; - - BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; - allocate_stack(common, stacksize); - if (framesize == no_frame) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); - - stack = 0; - if (offset != 0) - { - stack = 2; - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - if (needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - if (common->capture_last_ptr != 0) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - stack = 3; - } - } - else - { - if (needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - stack = 1; - } - - if (needs_control_head) - stack++; - if (!zero) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1); - if (needs_control_head) - { - stack--; - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); - } - } -else - { - stacksize = framesize + 1; - if (!zero) - stacksize++; - if (needs_control_head) - stacksize++; - if (offset == 0) - stacksize++; - BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; - - allocate_stack(common, stacksize); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - if (needs_control_head) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); - - stack = 0; - if (!zero) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); - stack = 1; - } - if (needs_control_head) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); - stack++; - } - if (offset == 0) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); - stack++; - } - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); - init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); - stack -= 1 + (offset == 0); - } - -if (offset != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); - -loop = LABEL(); -while (*cc != OP_KETRPOS) - { - backtrack->top = NULL; - backtrack->topbacktracks = NULL; - cc += GET(cc, 1); - - compile_matchingpath(common, ccbegin, cc, backtrack); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - - if (framesize < 0) - { - if (framesize == no_frame) - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - - if (offset != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); - if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - } - else - { - if (opcode == OP_SBRAPOS) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - } - - /* Even if the match is empty, we need to reset the control head. */ - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); - - if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) - add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); - - if (!zero) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); - } - else - { - if (offset != 0) - { - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); - if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - } - else - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); - if (opcode == OP_SBRAPOS) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); - } - - /* Even if the match is empty, we need to reset the control head. */ - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); - - if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) - add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); - - if (!zero) - { - if (framesize < 0) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); - else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - } - - JUMPTO(SLJIT_JUMP, loop); - flush_stubs(common); - - compile_backtrackingpath(common, backtrack->top); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return NULL; - set_jumps(backtrack->topbacktracks, LABEL()); - - if (framesize < 0) - { - if (offset != 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); - else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - } - else - { - if (offset != 0) - { - /* Last alternative. */ - if (*cc == OP_KETRPOS) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); - } - else - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); - } - } - - if (*cc == OP_KETRPOS) - break; - ccbegin = cc + 1 + LINK_SIZE; - } - -/* We don't have to restore the control head in case of a failed match. */ - -backtrack->topbacktracks = NULL; -if (!zero) - { - if (framesize < 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); - else /* TMP2 is set to [private_data_ptr] above. */ - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); - } - -/* None of them matched. */ -set_jumps(emptymatch, LABEL()); -count_match(common); -return cc + 1 + LINK_SIZE; -} - -static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_ui *max, sljit_ui *exact, PCRE2_SPTR *end) -{ -int class_len; - -*opcode = *cc; -*exact = 0; - -if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) - { - cc++; - *type = OP_CHAR; - } -else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) - { - cc++; - *type = OP_CHARI; - *opcode -= OP_STARI - OP_STAR; - } -else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) - { - cc++; - *type = OP_NOT; - *opcode -= OP_NOTSTAR - OP_STAR; - } -else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) - { - cc++; - *type = OP_NOTI; - *opcode -= OP_NOTSTARI - OP_STAR; - } -else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) - { - cc++; - *opcode -= OP_TYPESTAR - OP_STAR; - *type = OP_END; - } -else - { - SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); - *type = *opcode; - cc++; - class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0); - *opcode = cc[class_len - 1]; - - if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) - { - *opcode -= OP_CRSTAR - OP_STAR; - *end = cc + class_len; - - if (*opcode == OP_PLUS || *opcode == OP_MINPLUS) - { - *exact = 1; - *opcode -= OP_PLUS - OP_STAR; - } - } - else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) - { - *opcode -= OP_CRPOSSTAR - OP_POSSTAR; - *end = cc + class_len; - - if (*opcode == OP_POSPLUS) - { - *exact = 1; - *opcode = OP_POSSTAR; - } - } - else - { - SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); - *max = GET2(cc, (class_len + IMM2_SIZE)); - *exact = GET2(cc, class_len); - - if (*max == 0) - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSSTAR; - else - *opcode -= OP_CRRANGE - OP_STAR; - } - else - { - *max -= *exact; - if (*max == 0) - *opcode = OP_EXACT; - else if (*max == 1) - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSQUERY; - else - *opcode -= OP_CRRANGE - OP_QUERY; - } - else - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSUPTO; - else - *opcode -= OP_CRRANGE - OP_UPTO; - } - } - *end = cc + class_len + 2 * IMM2_SIZE; - } - return cc; - } - -switch(*opcode) - { - case OP_EXACT: - *exact = GET2(cc, 0); - cc += IMM2_SIZE; - break; - - case OP_PLUS: - case OP_MINPLUS: - *exact = 1; - *opcode -= OP_PLUS - OP_STAR; - break; - - case OP_POSPLUS: - *exact = 1; - *opcode = OP_POSSTAR; - break; - - case OP_UPTO: - case OP_MINUPTO: - case OP_POSUPTO: - *max = GET2(cc, 0); - cc += IMM2_SIZE; - break; - } - -if (*type == OP_END) - { - *type = *cc; - *end = next_opcode(common, cc); - cc++; - return cc; - } - -*end = cc + 1; -#ifdef SUPPORT_UNICODE -if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); -#endif -return cc; -} - -static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -PCRE2_UCHAR opcode; -PCRE2_UCHAR type; -sljit_ui max = 0, exact; -BOOL fast_fail; -sljit_si fast_str_ptr; -BOOL charpos_enabled; -PCRE2_UCHAR charpos_char; -unsigned int charpos_othercasebit; -PCRE2_SPTR end; -jump_list *no_match = NULL; -jump_list *no_char1_match = NULL; -struct sljit_jump *jump = NULL; -struct sljit_label *label; -int private_data_ptr = PRIVATE_DATA(cc); -int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); -int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; -int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); -int tmp_base, tmp_offset; - -PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); - -fast_str_ptr = PRIVATE_DATA(cc + 1); -fast_fail = TRUE; - -SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr); - -if (cc == common->fast_forward_bc_ptr) - fast_fail = FALSE; -else if (common->fast_fail_start_ptr == 0) - fast_str_ptr = 0; - -SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0 - || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr)); - -cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); - -if (type != OP_EXTUNI) - { - tmp_base = TMP3; - tmp_offset = 0; - } -else - { - tmp_base = SLJIT_MEM1(SLJIT_SP); - tmp_offset = POSSESSIVE0; - } - -if (fast_fail && fast_str_ptr != 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr)); - -/* Handle fixed part first. */ -if (exact > 1) - { - SLJIT_ASSERT(fast_str_ptr == 0); - if (common->mode == PCRE2_JIT_COMPLETE -#ifdef SUPPORT_UNICODE - && !common->utf -#endif - ) - { - OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else - { - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - } -else if (exact == 1) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); - -switch(opcode) - { - case OP_STAR: - case OP_UPTO: - SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR); - - if (type == OP_ANYNL || type == OP_EXTUNI) - { - SLJIT_ASSERT(private_data_ptr == 0); - SLJIT_ASSERT(fast_str_ptr == 0); - - allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); - - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max); - - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); - if (opcode == OP_UPTO) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); - OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - jump = JUMP(SLJIT_ZERO); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); - } - - /* We cannot use TMP3 because of this allocate_stack. */ - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); - if (jump != NULL) - JUMPHERE(jump); - } - else - { - charpos_enabled = FALSE; - charpos_char = 0; - charpos_othercasebit = 0; - - if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) - { - charpos_enabled = TRUE; -#ifdef SUPPORT_UNICODE - charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]); -#endif - if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1)) - { - charpos_othercasebit = char_get_othercase_bit(common, end + 1); - if (charpos_othercasebit == 0) - charpos_enabled = FALSE; - } - - if (charpos_enabled) - { - charpos_char = end[1]; - /* Consumpe the OP_CHAR opcode. */ - end += 2; -#if PCRE2_CODE_UNIT_WIDTH == 8 - SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); -#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); - if ((charpos_othercasebit & 0x100) != 0) - { - charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; - } -#endif - if (charpos_othercasebit != 0) - charpos_char |= charpos_othercasebit; - - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; - } - } - - if (charpos_enabled) - { - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); - - /* Search the first instance of charpos_char. */ - jump = JUMP(SLJIT_JUMP); - label = LABEL(); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); - } - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - JUMPHERE(jump); - - detect_partial_match(common, &backtrack->topbacktracks); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - } - - /* Search the last instance of charpos_char. */ - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - detect_partial_match(common, &no_match); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - if (opcode == OP_STAR) - { - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } - else - { - jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPHERE(jump); - } - - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else - JUMPTO(SLJIT_JUMP, label); - - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - else if (common->utf) - { - if (private_data_ptr == 0) - allocate_stack(common, 2); - - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else - JUMPTO(SLJIT_JUMP, label); - - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - } -#endif - else - { - if (private_data_ptr == 0) - allocate_stack(common, 2); - - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - - label = LABEL(); - detect_partial_match(common, &no_match); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } - else - JUMPTO(SLJIT_JUMP, label); - - set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - } - } - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - - case OP_MINSTAR: - if (private_data_ptr == 0) - allocate_stack(common, 1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - break; - - case OP_MINUPTO: - SLJIT_ASSERT(fast_str_ptr == 0); - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - - case OP_QUERY: - case OP_MINQUERY: - SLJIT_ASSERT(fast_str_ptr == 0); - if (private_data_ptr == 0) - allocate_stack(common, 1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode == OP_QUERY) - compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - - case OP_EXACT: - break; - - case OP_POSSTAR: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - break; - } -#endif - label = LABEL(); - detect_partial_match(common, &no_match); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - JUMPTO(SLJIT_JUMP, label); - set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - break; - - case OP_POSUPTO: - SLJIT_ASSERT(fast_str_ptr == 0); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); - break; - } -#endif - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - label = LABEL(); - detect_partial_match(common, &no_match); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - break; - - case OP_POSQUERY: - SLJIT_ASSERT(fast_str_ptr == 0); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - -count_match(common); -return end; -} - -static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; - -PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); - -if (*cc == OP_FAIL) - { - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); - return cc + 1; - } - -if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) - { - /* No need to check notempty conditions. */ - if (common->accept_label == NULL) - add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); - else - JUMPTO(SLJIT_JUMP, common->accept_label); - return cc + 1; - } - -if (common->accept_label == NULL) - add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); -else - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); -OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); -if (common->accept_label == NULL) - add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO)); -else - JUMPTO(SLJIT_ZERO, common->accept_label); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); -if (common->accept_label == NULL) - add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); -else - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); -return cc + 1; -} - -static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc) -{ -DEFINE_COMPILER; -int offset = GET2(cc, 1); -BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0; - -/* Data will be discarded anyway... */ -if (common->currententry != NULL) - return cc + 1 + IMM2_SIZE; - -if (!optimized_cbracket) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset)); -offset <<= 1; -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); -if (!optimized_cbracket) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); -return cc + 1 + IMM2_SIZE; -} - -static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -PCRE2_UCHAR opcode = *cc; -PCRE2_SPTR ccend = cc + 1; - -if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) - ccend += 2 + cc[1]; - -PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); - -if (opcode == OP_SKIP) - { - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - return ccend; - } - -if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); - } - -return ccend; -} - -static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP }; - -static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -BOOL needs_control_head; -int size; - -PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); -common->then_trap = BACKTRACK_AS(then_trap_backtrack); -BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; -BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start); -BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); - -size = BACKTRACK_AS(then_trap_backtrack)->framesize; -size = 3 + (size < 0 ? 0 : size); - -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); -allocate_stack(common, size); -if (size > 3) - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw)); -else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0); - -size = BACKTRACK_AS(then_trap_backtrack)->framesize; -if (size >= 0) - init_frame(common, cc, ccend, size - 1, 0, FALSE); -} - -static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent) -{ -DEFINE_COMPILER; -backtrack_common *backtrack; -BOOL has_then_trap = FALSE; -then_trap_backtrack *save_then_trap = NULL; - -SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); - -if (common->has_then && common->then_offsets[cc - common->start] != 0) - { - SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); - has_then_trap = TRUE; - save_then_trap = common->then_trap; - /* Tail item on backtrack. */ - compile_then_trap_matchingpath(common, cc, ccend, parent); - } - -while (cc < ccend) - { - switch(*cc) - { - case OP_SOD: - case OP_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - case OP_REVERSE: - cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); - break; - - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: - case OP_NOTPROP: - case OP_PROP: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_EXTUNI: - case OP_NOT: - case OP_NOTI: - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); - break; - - case OP_SET_SOM: - PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - cc++; - break; - - case OP_CHAR: - case OP_CHARI: - if (common->mode == PCRE2_JIT_COMPLETE) - cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); - else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); - break; - - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_UPTO: - case OP_MINUPTO: - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSUPTO: - cc = compile_iterator_matchingpath(common, cc, parent); - break; - - case OP_CLASS: - case OP_NCLASS: - if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); - else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); - break; - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - case OP_XCLASS: - if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); - else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); - break; -#endif - - case OP_REF: - case OP_REFI: - if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) - cc = compile_ref_iterator_matchingpath(common, cc, parent); - else - { - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); - cc += 1 + IMM2_SIZE; - } - break; - - case OP_DNREF: - case OP_DNREFI: - if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) - cc = compile_ref_iterator_matchingpath(common, cc, parent); - else - { - compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); - cc += 1 + 2 * IMM2_SIZE; - } - break; - - case OP_RECURSE: - cc = compile_recurse_matchingpath(common, cc, parent); - break; - - case OP_CALLOUT: - case OP_CALLOUT_STR: - cc = compile_callout_matchingpath(common, cc, parent); - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); - cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); - break; - - case OP_BRAMINZERO: - PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); - cc = bracketend(cc + 1); - if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) - { - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - } - else - { - allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); - } - BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); - count_match(common); - break; - - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRA: - case OP_CBRA: - case OP_COND: - case OP_SBRA: - case OP_SCBRA: - case OP_SCOND: - cc = compile_bracket_matchingpath(common, cc, parent); - break; - - case OP_BRAZERO: - if (cc[1] > OP_ASSERTBACK_NOT) - cc = compile_bracket_matchingpath(common, cc, parent); - else - { - PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); - cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); - } - break; - - case OP_BRAPOS: - case OP_CBRAPOS: - case OP_SBRAPOS: - case OP_SCBRAPOS: - case OP_BRAPOSZERO: - cc = compile_bracketpos_matchingpath(common, cc, parent); - break; - - case OP_MARK: - PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); - SLJIT_ASSERT(common->mark_ptr != 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); - allocate_stack(common, common->has_skip_arg ? 5 : 1); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); - if (common->has_skip_arg) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - } - cc += 1 + 2 + cc[1]; - break; - - case OP_PRUNE: - case OP_PRUNE_ARG: - case OP_SKIP: - case OP_SKIP_ARG: - case OP_THEN: - case OP_THEN_ARG: - case OP_COMMIT: - cc = compile_control_verb_matchingpath(common, cc, parent); - break; - - case OP_FAIL: - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - cc = compile_fail_accept_matchingpath(common, cc, parent); - break; - - case OP_CLOSE: - cc = compile_close_matchingpath(common, cc); - break; - - case OP_SKIPZERO: - cc = bracketend(cc + 1); - break; - - default: - SLJIT_ASSERT_STOP(); - return; - } - if (cc == NULL) - return; - } - -if (has_then_trap) - { - /* Head item on backtrack. */ - PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); - BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; - BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; - common->then_trap = save_then_trap; - } -SLJIT_ASSERT(cc == ccend); -} - -#undef PUSH_BACKTRACK -#undef PUSH_BACKTRACK_NOVALUE -#undef BACKTRACK_AS - -#define COMPILE_BACKTRACKINGPATH(current) \ - do \ - { \ - compile_backtrackingpath(common, (current)); \ - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ - return; \ - } \ - while (0) - -#define CURRENT_AS(type) ((type *)current) - -static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -PCRE2_SPTR cc = current->cc; -PCRE2_UCHAR opcode; -PCRE2_UCHAR type; -sljit_ui max = 0, exact; -struct sljit_label *label = NULL; -struct sljit_jump *jump = NULL; -jump_list *jumplist = NULL; -PCRE2_SPTR end; -int private_data_ptr = PRIVATE_DATA(cc); -int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); -int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; -int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); - -cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); - -switch(opcode) - { - case OP_STAR: - case OP_UPTO: - if (type == OP_ANYNL || type == OP_EXTUNI) - { - SLJIT_ASSERT(private_data_ptr == 0); - set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); - } - else - { - if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled) - { - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, TMP2, 0, base, offset1); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); - label = LABEL(); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); - skip_char_back(common); - CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); - } - else - { - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); - skip_char_back(common); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - } - JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 2); - } - break; - - case OP_MINSTAR: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(jumplist, LABEL()); - if (private_data_ptr == 0) - free_stack(common, 1); - break; - - case OP_MINUPTO: - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - - OP1(SLJIT_MOV, base, offset1, TMP1, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - - set_jumps(jumplist, LABEL()); - if (private_data_ptr == 0) - free_stack(common, 2); - break; - - case OP_QUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); - jump = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 1); - break; - - case OP_MINQUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(jumplist, LABEL()); - JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 1); - break; - - case OP_EXACT: - case OP_POSSTAR: - case OP_POSQUERY: - case OP_POSUPTO: - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - - set_jumps(current->topbacktracks, LABEL()); -} - -static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -PCRE2_SPTR cc = current->cc; -BOOL ref = (*cc == OP_REF || *cc == OP_REFI); -PCRE2_UCHAR type; - -type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; - -if ((type & 0x1) == 0) - { - /* Maximize case. */ - set_jumps(current->topbacktracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); - return; - } - -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); -CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); -set_jumps(current->topbacktracks, LABEL()); -free_stack(common, ref ? 2 : 3); -} - -static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; - -if (CURRENT_AS(recurse_backtrack)->inlined_pattern) - compile_backtrackingpath(common, current->top); -set_jumps(current->topbacktracks, LABEL()); -if (CURRENT_AS(recurse_backtrack)->inlined_pattern) - return; - -if (common->has_set_som && common->mark_ptr != 0) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); - } -else if (common->has_set_som || common->mark_ptr != 0) - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); - } -} - -static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -PCRE2_SPTR cc = current->cc; -PCRE2_UCHAR bra = OP_BRA; -struct sljit_jump *brajump = NULL; - -SLJIT_ASSERT(*cc != OP_BRAMINZERO); -if (*cc == OP_BRAZERO) - { - bra = *cc; - cc++; - } - -if (bra == OP_BRAZERO) - { - SLJIT_ASSERT(current->topbacktracks == NULL); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - } - -if (CURRENT_AS(assert_backtrack)->framesize < 0) - { - set_jumps(current->topbacktracks, LABEL()); - - if (bra == OP_BRAZERO) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); - free_stack(common, 1); - } - return; - } - -if (bra == OP_BRAZERO) - { - if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) - { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); - free_stack(common, 1); - return; - } - free_stack(common, 1); - brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - } - -if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw)); - - set_jumps(current->topbacktracks, LABEL()); - } -else - set_jumps(current->topbacktracks, LABEL()); - -if (bra == OP_BRAZERO) - { - /* We know there is enough place on the stack. */ - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath); - JUMPHERE(brajump); - } -} - -static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -int opcode, stacksize, alt_count, alt_max; -int offset = 0; -int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; -int repeat_ptr = 0, repeat_type = 0, repeat_count = 0; -PCRE2_SPTR cc = current->cc; -PCRE2_SPTR ccbegin; -PCRE2_SPTR ccprev; -PCRE2_UCHAR bra = OP_BRA; -PCRE2_UCHAR ket; -assert_backtrack *assert; -sljit_uw *next_update_addr = NULL; -BOOL has_alternatives; -BOOL needs_control_head = FALSE; -struct sljit_jump *brazero = NULL; -struct sljit_jump *alt1 = NULL; -struct sljit_jump *alt2 = NULL; -struct sljit_jump *once = NULL; -struct sljit_jump *cond = NULL; -struct sljit_label *rmin_label = NULL; -struct sljit_label *exact_label = NULL; - -if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) - { - bra = *cc; - cc++; - } - -opcode = *cc; -ccbegin = bracketend(cc) - 1 - LINK_SIZE; -ket = *ccbegin; -if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0) - { - repeat_ptr = PRIVATE_DATA(ccbegin); - repeat_type = PRIVATE_DATA(ccbegin + 2); - repeat_count = PRIVATE_DATA(ccbegin + 3); - SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0); - if (repeat_type == OP_UPTO) - ket = OP_KETRMAX; - if (repeat_type == OP_MINUPTO) - ket = OP_KETRMIN; - } -ccbegin = cc; -cc += GET(cc, 1); -has_alternatives = *cc == OP_ALT; -if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) - has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; -if (opcode == OP_CBRA || opcode == OP_SCBRA) - offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; -if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) - opcode = OP_SCOND; -if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) - opcode = OP_ONCE; - -alt_max = has_alternatives ? no_alternatives(ccbegin) : 0; - -/* Decoding the needs_control_head in framesize. */ -if (opcode == OP_ONCE) - { - needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0; - CURRENT_AS(bracket_backtrack)->u.framesize >>= 1; - } - -if (ket != OP_KET && repeat_type != 0) - { - /* TMP1 is used in OP_KETRMIN below. */ - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - if (repeat_type == OP_UPTO) - OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1); - else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); - } - -if (ket == OP_KETRMAX) - { - if (bra == OP_BRAZERO) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0); - } - } -else if (ket == OP_KETRMIN) - { - if (bra != OP_BRAMINZERO) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - if (repeat_type != 0) - { - /* TMP1 was set a few lines above. */ - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); - /* Drop STR_PTR for non-greedy plus quantifier. */ - if (opcode != OP_ONCE) - free_stack(common, 1); - } - else if (opcode >= OP_SBRA || opcode == OP_ONCE) - { - /* Checking zero-length iteration. */ - if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); - } - /* Drop STR_PTR for non-greedy plus quantifier. */ - if (opcode != OP_ONCE) - free_stack(common, 1); - } - else - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); - } - rmin_label = LABEL(); - if (repeat_type != 0) - OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); - } -else if (bra == OP_BRAZERO) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); - } -else if (repeat_type == OP_EXACT) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); - exact_label = LABEL(); - } - -if (offset != 0) - { - if (common->capture_last_ptr != 0) - { - SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); - free_stack(common, 3); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); - } - else if (common->optimized_cbracket[offset >> 1] == 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); - } - } - -if (SLJIT_UNLIKELY(opcode == OP_ONCE)) - { - if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - } - once = JUMP(SLJIT_JUMP); - } -else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) - { - if (has_alternatives) - { - /* Always exactly one alternative. */ - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - - alt_max = 2; - alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); - } - } -else if (has_alternatives) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - - if (alt_max > 4) - { - /* Table jump if alt_max is greater than 4. */ - next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw)); - if (SLJIT_UNLIKELY(next_update_addr == NULL)) - return; - sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr); - add_label_addr(common, next_update_addr++); - } - else - { - if (alt_max == 4) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); - } - } - -COMPILE_BACKTRACKINGPATH(current->top); -if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); - -if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) - { - /* Conditional block always has at most one alternative. */ - if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) - { - SLJIT_ASSERT(has_alternatives); - assert = CURRENT_AS(bracket_backtrack)->u.assert; - if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); - } - cond = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); - } - else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) - { - SLJIT_ASSERT(has_alternatives); - cond = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); - } - else - SLJIT_ASSERT(!has_alternatives); - } - -if (has_alternatives) - { - alt_count = sizeof(sljit_uw); - do - { - current->top = NULL; - current->topbacktracks = NULL; - current->nextbacktracks = NULL; - /* Conditional blocks always have an additional alternative, even if it is empty. */ - if (*cc == OP_ALT) - { - ccprev = cc + 1 + LINK_SIZE; - cc += GET(cc, 1); - if (opcode != OP_COND && opcode != OP_SCOND) - { - if (opcode != OP_ONCE) - { - if (private_data_ptr != 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - } - else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); - } - compile_matchingpath(common, ccprev, cc, current); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return; - } - - /* Instructions after the current alternative is successfully matched. */ - /* There is a similar code in compile_bracket_matchingpath. */ - if (opcode == OP_ONCE) - match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); - - stacksize = 0; - if (repeat_type == OP_MINUPTO) - { - /* We need to preserve the counter. TMP2 will be used below. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); - stacksize++; - } - if (ket != OP_KET || bra != OP_BRA) - stacksize++; - if (offset != 0) - { - if (common->capture_last_ptr != 0) - stacksize++; - if (common->optimized_cbracket[offset >> 1] == 0) - stacksize += 2; - } - if (opcode != OP_ONCE) - stacksize++; - - if (stacksize > 0) - allocate_stack(common, stacksize); - - stacksize = 0; - if (repeat_type == OP_MINUPTO) - { - /* TMP2 was set above. */ - OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); - stacksize++; - } - - if (ket != OP_KET || bra != OP_BRA) - { - if (ket != OP_KET) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); - else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); - stacksize++; - } - - if (offset != 0) - stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); - - if (opcode != OP_ONCE) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); - - if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0) - { - /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */ - SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); - } - - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath); - - if (opcode != OP_ONCE) - { - if (alt_max > 4) - add_label_addr(common, next_update_addr++); - else - { - if (alt_count != 2 * sizeof(sljit_uw)) - { - JUMPHERE(alt1); - if (alt_max == 3 && alt_count == sizeof(sljit_uw)) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - } - else - { - JUMPHERE(alt2); - if (alt_max == 4) - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); - } - } - alt_count += sizeof(sljit_uw); - } - - COMPILE_BACKTRACKINGPATH(current->top); - if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); - SLJIT_ASSERT(!current->nextbacktracks); - } - while (*cc == OP_ALT); - - if (cond != NULL) - { - SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); - assert = CURRENT_AS(bracket_backtrack)->u.assert; - if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); - } - JUMPHERE(cond); - } - - /* Free the STR_PTR. */ - if (private_data_ptr == 0) - free_stack(common, 1); - } - -if (offset != 0) - { - /* Using both tmp register is better for instruction scheduling. */ - if (common->optimized_cbracket[offset >> 1] != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - } - } -else if (opcode == OP_SBRA || opcode == OP_SCOND) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - } -else if (opcode == OP_ONCE) - { - cc = ccbegin + GET(ccbegin, 1); - stacksize = needs_control_head ? 1 : 0; - - if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) - { - /* Reset head and drop saved frame. */ - stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1); - } - else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) - { - /* The STR_PTR must be released. */ - stacksize++; - } - - if (stacksize > 0) - free_stack(common, stacksize); - - JUMPHERE(once); - /* Restore previous private_data_ptr */ - if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw)); - else if (ket == OP_KETRMIN) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - /* See the comment below. */ - free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - } - } - -if (repeat_type == OP_EXACT) - { - OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); - CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label); - } -else if (ket == OP_KETRMAX) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - if (bra != OP_BRAZERO) - free_stack(common, 1); - - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); - if (bra == OP_BRAZERO) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); - JUMPHERE(brazero); - free_stack(common, 1); - } - } -else if (ket == OP_KETRMIN) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - - /* OP_ONCE removes everything in case of a backtrack, so we don't - need to explicitly release the STR_PTR. The extra release would - affect badly the free_stack(2) above. */ - if (opcode != OP_ONCE) - free_stack(common, 1); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label); - if (opcode == OP_ONCE) - free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); - else if (bra == OP_BRAMINZERO) - free_stack(common, 1); - } -else if (bra == OP_BRAZERO) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); - JUMPHERE(brazero); - } -} - -static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -int offset; -struct sljit_jump *jump; - -if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) - { - if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) - { - offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); - if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); - if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); - } - set_jumps(current->topbacktracks, LABEL()); - free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); - return; - } - -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr); -add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - -if (current->topbacktracks) - { - jump = JUMP(SLJIT_JUMP); - set_jumps(current->topbacktracks, LABEL()); - /* Drop the stack frame. */ - free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); - JUMPHERE(jump); - } -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); -} - -static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -assert_backtrack backtrack; - -current->top = NULL; -current->topbacktracks = NULL; -current->nextbacktracks = NULL; -if (current->cc[1] > OP_ASSERTBACK_NOT) - { - /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ - compile_bracket_matchingpath(common, current->cc, current); - compile_bracket_backtrackingpath(common, current->top); - } -else - { - memset(&backtrack, 0, sizeof(backtrack)); - backtrack.common.cc = current->cc; - backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath; - /* Manual call of compile_assert_matchingpath. */ - compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); - } -SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); -} - -static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -PCRE2_UCHAR opcode = *current->cc; -struct sljit_label *loop; -struct sljit_jump *jump; - -if (opcode == OP_THEN || opcode == OP_THEN_ARG) - { - if (common->then_trap != NULL) - { - SLJIT_ASSERT(common->control_head_ptr != 0); - - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start); - jump = JUMP(SLJIT_JUMP); - - loop = LABEL(); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw)); - JUMPHERE(jump); - CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop); - CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop); - add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); - return; - } - else if (common->positive_assert) - { - add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP)); - return; - } - } - -if (common->local_exit) - { - if (common->quit_label == NULL) - add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); - else - JUMPTO(SLJIT_JUMP, common->quit_label); - return; - } - -if (opcode == OP_SKIP_ARG) - { - SLJIT_ASSERT(common->control_head_ptr != 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); - sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark)); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); - - OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); - add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); - return; - } - -if (opcode == OP_SKIP) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); -else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0); -add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); -} - -static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; -int size; - -if (CURRENT_AS(then_trap_backtrack)->then_trap) - { - common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; - return; - } - -size = CURRENT_AS(then_trap_backtrack)->framesize; -size = 3 + (size < 0 ? 0 : size); - -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3)); -free_stack(common, size); -jump = JUMP(SLJIT_JUMP); - -set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); -/* STACK_TOP is set by THEN. */ -if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); -free_stack(common, 3); - -JUMPHERE(jump); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); -} - -static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) -{ -DEFINE_COMPILER; -then_trap_backtrack *save_then_trap = common->then_trap; - -while (current) - { - if (current->nextbacktracks != NULL) - set_jumps(current->nextbacktracks, LABEL()); - switch(*current->cc) - { - case OP_SET_SOM: - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0); - break; - - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_UPTO: - case OP_MINUPTO: - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSUPTO: - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: -#endif - compile_iterator_backtrackingpath(common, current); - break; - - case OP_REF: - case OP_REFI: - case OP_DNREF: - case OP_DNREFI: - compile_ref_iterator_backtrackingpath(common, current); - break; - - case OP_RECURSE: - compile_recurse_backtrackingpath(common, current); - break; - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - compile_assert_backtrackingpath(common, current); - break; - - case OP_ONCE: - case OP_ONCE_NC: - case OP_BRA: - case OP_CBRA: - case OP_COND: - case OP_SBRA: - case OP_SCBRA: - case OP_SCOND: - compile_bracket_backtrackingpath(common, current); - break; - - case OP_BRAZERO: - if (current->cc[1] > OP_ASSERTBACK_NOT) - compile_bracket_backtrackingpath(common, current); - else - compile_assert_backtrackingpath(common, current); - break; - - case OP_BRAPOS: - case OP_CBRAPOS: - case OP_SBRAPOS: - case OP_SCBRAPOS: - case OP_BRAPOSZERO: - compile_bracketpos_backtrackingpath(common, current); - break; - - case OP_BRAMINZERO: - compile_braminzero_backtrackingpath(common, current); - break; - - case OP_MARK: - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0)); - if (common->has_skip_arg) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, common->has_skip_arg ? 5 : 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); - if (common->has_skip_arg) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); - break; - - case OP_THEN: - case OP_THEN_ARG: - case OP_PRUNE: - case OP_PRUNE_ARG: - case OP_SKIP: - case OP_SKIP_ARG: - compile_control_verb_backtrackingpath(common, current); - break; - - case OP_COMMIT: - if (!common->local_exit) - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); - if (common->quit_label == NULL) - add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); - else - JUMPTO(SLJIT_JUMP, common->quit_label); - break; - - case OP_CALLOUT: - case OP_CALLOUT_STR: - case OP_FAIL: - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - set_jumps(current->topbacktracks, LABEL()); - break; - - case OP_THEN_TRAP: - /* A virtual opcode for then traps. */ - compile_then_trap_backtrackingpath(common, current); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - current = current->prev; - } -common->then_trap = save_then_trap; -} - -static SLJIT_INLINE void compile_recurse(compiler_common *common) -{ -DEFINE_COMPILER; -PCRE2_SPTR cc = common->start + common->currententry->start; -PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); -PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE); -BOOL needs_control_head; -int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); -int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); -int alternativesize; -BOOL needs_frame; -backtrack_common altbacktrack; -struct sljit_jump *jump; - -/* Recurse captures then. */ -common->then_trap = NULL; - -SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); -needs_frame = framesize >= 0; -if (!needs_frame) - framesize = 0; -alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; - -SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0); -common->currententry->entry = LABEL(); -set_jumps(common->currententry->calls, common->currententry->entry); - -sljit_emit_fast_enter(compiler, TMP2, 0); -count_match(common); -allocate_stack(common, private_data_size + framesize + alternativesize); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); -copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); -if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0); -if (needs_frame) - init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE); - -if (alternativesize > 0) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - -memset(&altbacktrack, 0, sizeof(backtrack_common)); -common->quit_label = NULL; -common->accept_label = NULL; -common->quit = NULL; -common->accept = NULL; -altbacktrack.cc = ccbegin; -cc += GET(cc, 1); -while (1) - { - altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; - - if (altbacktrack.cc != ccbegin) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - - compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return; - - add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); - - compile_backtrackingpath(common, altbacktrack.top); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - return; - set_jumps(altbacktrack.topbacktracks, LABEL()); - - if (*cc != OP_ALT) - break; - - altbacktrack.cc = cc + 1 + LINK_SIZE; - cc += GET(cc, 1); - } - -/* None of them matched. */ -OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); -jump = JUMP(SLJIT_JUMP); - -if (common->quit != NULL) - { - set_jumps(common->quit, LABEL()); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); - if (needs_frame) - { - OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); - } - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); - common->quit = NULL; - add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); - } - -set_jumps(common->accept, LABEL()); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); -if (needs_frame) - { - OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); - } -OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); - -JUMPHERE(jump); -if (common->quit != NULL) - set_jumps(common->quit, LABEL()); -copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); -free_stack(common, private_data_size + framesize + alternativesize); -if (needs_control_head) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); - } -else - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); - OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0); - } -sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); -} - -#undef COMPILE_BACKTRACKINGPATH -#undef CURRENT_AS - -static int jit_compile(pcre2_code *code, uint32_t mode) -{ -pcre2_real_code *re = (pcre2_real_code *)code; -struct sljit_compiler *compiler; -backtrack_common rootbacktrack; -compiler_common common_data; -compiler_common *common = &common_data; -const sljit_ub *tables = re->tables; -void *allocator_data = &re->memctl; -int private_data_size; -PCRE2_SPTR ccend; -executable_functions *functions; -void *executable_func; -sljit_uw executable_size; -sljit_uw total_length; -label_addr_list *label_addr; -struct sljit_label *mainloop_label = NULL; -struct sljit_label *continue_match_label; -struct sljit_label *empty_match_found_label = NULL; -struct sljit_label *empty_match_backtrack_label = NULL; -struct sljit_label *reset_match_label; -struct sljit_label *quit_label; -struct sljit_jump *jump; -struct sljit_jump *minlength_check_failed = NULL; -struct sljit_jump *reqbyte_notfound = NULL; -struct sljit_jump *empty_match = NULL; - -SLJIT_ASSERT(tables); - -memset(&rootbacktrack, 0, sizeof(backtrack_common)); -memset(common, 0, sizeof(compiler_common)); -common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size; - -common->start = rootbacktrack.cc; -common->read_only_data_head = NULL; -common->fcc = tables + fcc_offset; -common->lcc = (sljit_sw)(tables + lcc_offset); -common->mode = mode; -common->might_be_empty = re->minlength == 0; -common->nltype = NLTYPE_FIXED; -switch(re->newline_convention) - { - case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break; - case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break; - case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; - case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; - case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; - default: return PCRE2_ERROR_INTERNAL; - } -common->nlmax = READ_CHAR_MAX; -common->nlmin = 0; -if (re->bsr_convention == PCRE2_BSR_UNICODE) - common->bsr_nltype = NLTYPE_ANY; -else if (re->bsr_convention == PCRE2_BSR_ANYCRLF) - common->bsr_nltype = NLTYPE_ANYCRLF; -else - { -#ifdef BSR_ANYCRLF - common->bsr_nltype = NLTYPE_ANYCRLF; -#else - common->bsr_nltype = NLTYPE_ANY; -#endif - } -common->bsr_nlmax = READ_CHAR_MAX; -common->bsr_nlmin = 0; -common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0; -common->ctypes = (sljit_sw)(tables + ctypes_offset); -common->name_count = re->name_count; -common->name_entry_size = re->name_entry_size; -common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0; -common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0; -#ifdef SUPPORT_UNICODE -/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ -common->utf = (re->overall_options & PCRE2_UTF) != 0; -common->use_ucp = (re->overall_options & PCRE2_UCP) != 0; -if (common->utf) - { - if (common->nltype == NLTYPE_ANY) - common->nlmax = 0x2029; - else if (common->nltype == NLTYPE_ANYCRLF) - common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; - else - { - /* We only care about the first newline character. */ - common->nlmax = common->newline & 0xff; - } - - if (common->nltype == NLTYPE_FIXED) - common->nlmin = common->newline & 0xff; - else - common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; - - if (common->bsr_nltype == NLTYPE_ANY) - common->bsr_nlmax = 0x2029; - else - common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; - common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; - } -#endif /* SUPPORT_UNICODE */ -ccend = bracketend(common->start); - -/* Calculate the local space size on the stack. */ -common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); -common->optimized_cbracket = (sljit_ub *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); -if (!common->optimized_cbracket) - return PCRE2_ERROR_NOMEMORY; -#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 -memset(common->optimized_cbracket, 0, re->top_bracket + 1); -#else -memset(common->optimized_cbracket, 1, re->top_bracket + 1); -#endif - -SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); -#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2 -common->capture_last_ptr = common->ovector_start; -common->ovector_start += sizeof(sljit_sw); -#endif -if (!check_opcode_types(common, common->start, ccend)) - { - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - -/* Checking flags and updating ovector_start. */ -if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - common->req_char_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } -if (mode != PCRE2_JIT_COMPLETE) - { - common->start_used_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - if (mode == PCRE2_JIT_PARTIAL_SOFT) - { - common->hit_start = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - } -if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0) - { - common->match_end_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } -#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD -common->control_head_ptr = 1; -#endif -if (common->control_head_ptr != 0) - { - common->control_head_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } -if (common->has_set_som) - { - /* Saving the real start pointer is necessary. */ - common->start_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - -/* Aligning ovector to even number of sljit words. */ -if ((common->ovector_start & sizeof(sljit_sw)) != 0) - common->ovector_start += sizeof(sljit_sw); - -if (common->start_ptr == 0) - common->start_ptr = OVECTOR(0); - -/* Capturing brackets cannot be optimized if callouts are allowed. */ -if (common->capture_last_ptr != 0) - memset(common->optimized_cbracket, 0, re->top_bracket + 1); - -SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); -common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); - -total_length = ccend - common->start; -common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)), allocator_data); -if (!common->private_data_ptrs) - { - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } -memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); - -private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); -set_private_data_ptrs(common, &private_data_size, ccend); -if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back) - detect_fast_fail(common, common->start, &private_data_size, 4); - } - -SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr); - -if (private_data_size > SLJIT_MAX_LOCAL_SIZE) - { - SLJIT_FREE(common->private_data_ptrs, allocator_data); - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - -if (common->has_then) - { - common->then_offsets = (sljit_ub *)(common->private_data_ptrs + total_length); - memset(common->then_offsets, 0, total_length); - set_then_offsets(common, common->start, NULL); - } - -compiler = sljit_create_compiler(allocator_data); -if (!compiler) - { - SLJIT_FREE(common->optimized_cbracket, allocator_data); - SLJIT_FREE(common->private_data_ptrs, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } -common->compiler = compiler; - -/* Main pcre_jit_exec entry. */ -sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size); - -/* Register init. */ -reset_ovector(common, (re->top_bracket + 1) * 2); -if (common->req_char_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0); - -OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0); -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); -OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); -OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0); - -if (common->fast_fail_start_ptr < common->fast_fail_end_ptr) - reset_fast_fail(common); - -if (mode == PCRE2_JIT_PARTIAL_SOFT) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); -if (common->control_head_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); - -/* Main part of the matching */ -if ((re->overall_options & PCRE2_ANCHORED) == 0) - { - mainloop_label = mainloop_entry(common, (re->flags & PCRE2_HASCRORLF) != 0, re->overall_options); - continue_match_label = LABEL(); - /* Forward search if possible. */ - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common)) - ; - else if ((re->flags & PCRE2_FIRSTSET) != 0) - fast_forward_first_char(common, (PCRE2_UCHAR)(re->first_codeunit), (re->flags & PCRE2_FIRSTCASELESS) != 0); - else if ((re->flags & PCRE2_STARTLINE) != 0) - fast_forward_newline(common); - else if ((re->flags & PCRE2_FIRSTMAPSET) != 0) - fast_forward_start_bits(common, re->start_bitmap); - } - } -else - continue_match_label = LABEL(); - -if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength)); - minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0); - } -if (common->req_char_ptr != 0) - reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0); - -/* Store the current STR_PTR in OVECTOR(0). */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); -/* Copy the limit of allowed recursions. */ -OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH); -if (common->capture_last_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0); -if (common->fast_forward_bc_ptr != NULL) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0); - -if (common->start_ptr != OVECTOR(0)) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0); - -/* Copy the beginning of the string. */ -if (mode == PCRE2_JIT_PARTIAL_SOFT) - { - jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); - JUMPHERE(jump); - } -else if (mode == PCRE2_JIT_PARTIAL_HARD) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); - -compile_matchingpath(common, common->start, ccend, &rootbacktrack); -if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); - SLJIT_FREE(common->private_data_ptrs, allocator_data); - PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - -if (common->might_be_empty) - { - empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); - empty_match_found_label = LABEL(); - } - -common->accept_label = LABEL(); -if (common->accept != NULL) - set_jumps(common->accept, common->accept_label); - -/* This means we have a match. Update the ovector. */ -copy_ovector(common, re->top_bracket + 1); -common->quit_label = common->forced_quit_label = LABEL(); -if (common->quit != NULL) - set_jumps(common->quit, common->quit_label); -if (common->forced_quit != NULL) - set_jumps(common->forced_quit, common->forced_quit_label); -if (minlength_check_failed != NULL) - SET_LABEL(minlength_check_failed, common->forced_quit_label); -sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); - -if (mode != PCRE2_JIT_COMPLETE) - { - common->partialmatchlabel = LABEL(); - set_jumps(common->partialmatch, common->partialmatchlabel); - return_with_partial_match(common, common->quit_label); - } - -if (common->might_be_empty) - empty_match_backtrack_label = LABEL(); -compile_backtrackingpath(common, rootbacktrack.top); -if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); - SLJIT_FREE(common->private_data_ptrs, allocator_data); - PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - -SLJIT_ASSERT(rootbacktrack.prev == NULL); -reset_match_label = LABEL(); - -if (mode == PCRE2_JIT_PARTIAL_SOFT) - { - /* Update hit_start only in the first time. */ - jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0); - JUMPHERE(jump); - } - -/* Check we have remaining characters. */ -if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - } - -if (common->fast_forward_bc_ptr != NULL) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1)); -else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); - -if ((re->overall_options & PCRE2_ANCHORED) == 0) - { - if (common->ff_newline_shortcut != NULL) - { - /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */ - if ((re->overall_options & PCRE2_FIRSTLINE) == 0) - { - if (common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); - CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut); - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - } - else - CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut); - } - } - else - { - CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label); - } - } - -/* No more remaining characters. */ -if (reqbyte_notfound != NULL) - JUMPHERE(reqbyte_notfound); - -if (mode == PCRE2_JIT_PARTIAL_SOFT) - CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel); - -OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); -JUMPTO(SLJIT_JUMP, common->quit_label); - -flush_stubs(common); - -if (common->might_be_empty) - { - JUMPHERE(empty_match); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); - JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); - JUMPTO(SLJIT_ZERO, empty_match_found_label); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label); - JUMPTO(SLJIT_JUMP, empty_match_backtrack_label); - } - -common->fast_forward_bc_ptr = NULL; -common->fast_fail_start_ptr = 0; -common->fast_fail_end_ptr = 0; -common->currententry = common->entries; -common->local_exit = TRUE; -quit_label = common->quit_label; -while (common->currententry != NULL) - { - /* Might add new entries. */ - compile_recurse(common); - if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); - SLJIT_FREE(common->private_data_ptrs, allocator_data); - PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - flush_stubs(common); - common->currententry = common->currententry->next; - } -common->local_exit = FALSE; -common->quit_label = quit_label; - -/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ -/* This is a (really) rare case. */ -set_jumps(common->stackalloc, LABEL()); -/* RETURN_ADDR is not a saved register. */ -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); -OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); - -sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); -jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); -OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); - -/* Allocation failed. */ -JUMPHERE(jump); -/* We break the return address cache here, but this is a really rare case. */ -OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT); -JUMPTO(SLJIT_JUMP, common->quit_label); - -/* Call limit reached. */ -set_jumps(common->calllimit, LABEL()); -OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT); -JUMPTO(SLJIT_JUMP, common->quit_label); - -if (common->revertframes != NULL) - { - set_jumps(common->revertframes, LABEL()); - do_revertframes(common); - } -if (common->wordboundary != NULL) - { - set_jumps(common->wordboundary, LABEL()); - check_wordboundary(common); - } -if (common->anynewline != NULL) - { - set_jumps(common->anynewline, LABEL()); - check_anynewline(common); - } -if (common->hspace != NULL) - { - set_jumps(common->hspace, LABEL()); - check_hspace(common); - } -if (common->vspace != NULL) - { - set_jumps(common->vspace, LABEL()); - check_vspace(common); - } -if (common->casefulcmp != NULL) - { - set_jumps(common->casefulcmp, LABEL()); - do_casefulcmp(common); - } -if (common->caselesscmp != NULL) - { - set_jumps(common->caselesscmp, LABEL()); - do_caselesscmp(common); - } -if (common->reset_match != NULL) - { - set_jumps(common->reset_match, LABEL()); - do_reset_match(common, (re->top_bracket + 1) * 2); - CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); - OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); - JUMPTO(SLJIT_JUMP, reset_match_label); - } -#ifdef SUPPORT_UNICODE -#if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utfreadchar != NULL) - { - set_jumps(common->utfreadchar, LABEL()); - do_utfreadchar(common); - } -if (common->utfreadchar16 != NULL) - { - set_jumps(common->utfreadchar16, LABEL()); - do_utfreadchar16(common); - } -if (common->utfreadtype8 != NULL) - { - set_jumps(common->utfreadtype8, LABEL()); - do_utfreadtype8(common); - } -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ -if (common->getucd != NULL) - { - set_jumps(common->getucd, LABEL()); - do_getucd(common); - } -#endif /* SUPPORT_UNICODE */ - -SLJIT_FREE(common->optimized_cbracket, allocator_data); -SLJIT_FREE(common->private_data_ptrs, allocator_data); - -executable_func = sljit_generate_code(compiler); -executable_size = sljit_get_generated_code_size(compiler); -label_addr = common->label_addrs; -while (label_addr != NULL) - { - *label_addr->update_addr = sljit_get_label_addr(label_addr->label); - label_addr = label_addr->next; - } -sljit_free_compiler(compiler); -if (executable_func == NULL) - { - PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - -/* Reuse the function descriptor if possible. */ -if (re->executable_jit != NULL) - functions = (executable_functions *)re->executable_jit; -else - { - functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data); - if (functions == NULL) - { - /* This case is highly unlikely since we just recently - freed a lot of memory. Not impossible though. */ - sljit_free_code(executable_func); - PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data); - return PCRE2_ERROR_NOMEMORY; - } - memset(functions, 0, sizeof(executable_functions)); - functions->top_bracket = re->top_bracket + 1; - functions->limit_match = re->limit_match; - re->executable_jit = functions; - } - -/* Turn mode into an index. */ -if (mode == PCRE2_JIT_COMPLETE) - mode = 0; -else - mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2; - -SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES); -functions->executable_funcs[mode] = executable_func; -functions->read_only_data_heads[mode] = common->read_only_data_head; -functions->executable_sizes[mode] = executable_size; -return 0; -} - -#endif - -/************************************************* -* JIT compile a Regular Expression * -*************************************************/ - -/* This function used JIT to convert a previously-compiled pattern into machine -code. - -Arguments: - code a compiled pattern - options JIT option bits - -Returns: 0: success or (*NOJIT) was used - <0: an error code -*/ - -#define PUBLIC_JIT_COMPILE_OPTIONS \ - (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD) - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_jit_compile(pcre2_code *code, uint32_t options) -{ -#ifndef SUPPORT_JIT - -(void)code; -(void)options; -return PCRE2_ERROR_JIT_BADOPTION; - -#else /* SUPPORT_JIT */ - -pcre2_real_code *re = (pcre2_real_code *)code; -executable_functions *functions; -int result; - -if (code == NULL) - return PCRE2_ERROR_NULL; - -if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0) - return PCRE2_ERROR_JIT_BADOPTION; - -if ((re->flags & PCRE2_NOJIT) != 0) return 0; - -functions = (executable_functions *)re->executable_jit; - -if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL - || functions->executable_funcs[0] == NULL)) { - result = jit_compile(code, PCRE2_JIT_COMPLETE); - if (result != 0) - return result; - } - -if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL - || functions->executable_funcs[1] == NULL)) { - result = jit_compile(code, PCRE2_JIT_PARTIAL_SOFT); - if (result != 0) - return result; - } - -if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL - || functions->executable_funcs[2] == NULL)) { - result = jit_compile(code, PCRE2_JIT_PARTIAL_HARD); - if (result != 0) - return result; - } - -return 0; - -#endif /* SUPPORT_JIT */ -} - -/* JIT compiler uses an all-in-one approach. This improves security, - since the code generator functions are not exported. */ - -#define INCLUDED_FROM_PCRE2_JIT_COMPILE - -#include "pcre2_jit_match.c" -#include "pcre2_jit_misc.c" - -/* End of pcre2_jit_compile.c */ diff --git a/pcre2/src/pcre2_jit_match.c b/pcre2/src/pcre2_jit_match.c deleted file mode 100644 index d804cfea4..000000000 --- a/pcre2/src/pcre2_jit_match.c +++ /dev/null @@ -1,189 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE -#error This file must be included from pcre2_jit_compile.c. -#endif - -#ifdef SUPPORT_JIT - -static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) -{ -sljit_ub local_space[MACHINE_STACK_SIZE]; -struct sljit_stack local_stack; - -local_stack.top = (sljit_sw)&local_space; -local_stack.base = local_stack.top; -local_stack.limit = local_stack.base + MACHINE_STACK_SIZE; -local_stack.max_limit = local_stack.limit; -arguments->stack = &local_stack; -return executable_func(arguments); -} - -#endif - - -/************************************************* -* Do a JIT pattern match * -*************************************************/ - -/* This function runs a JIT pattern match. - -Arguments: - code points to the compiled expression - subject points to the subject string - length length of subject string (may contain binary zeros) - start_offset where to start in the subject string - options option bits - match_data points to a match_data block - mcontext points to a match context - jit_stack points to a JIT stack - -Returns: > 0 => success; value is the number of ovector pairs filled - = 0 => success, but ovector is not big enough - -1 => failed to match (PCRE_ERROR_NOMATCH) - < -1 => some kind of unexpected problem -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, - PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, - pcre2_match_context *mcontext) -{ -#ifndef SUPPORT_JIT - -(void)code; -(void)subject; -(void)length; -(void)start_offset; -(void)options; -(void)match_data; -(void)mcontext; -return PCRE2_ERROR_JIT_BADOPTION; - -#else /* SUPPORT_JIT */ - -pcre2_real_code *re = (pcre2_real_code *)code; -executable_functions *functions = (executable_functions *)re->executable_jit; -pcre2_jit_stack *jit_stack; -uint32_t oveccount = match_data->oveccount; -uint32_t max_oveccount; -union { - void *executable_func; - jit_function call_executable_func; -} convert_executable_func; -jit_arguments arguments; -int rc; -int index = 0; - -if ((options & PCRE2_PARTIAL_HARD) != 0) - index = 2; -else if ((options & PCRE2_PARTIAL_SOFT) != 0) - index = 1; - -if (functions->executable_funcs[index] == NULL) - return PCRE2_ERROR_JIT_BADOPTION; - -/* Sanity checks should be handled by pcre_exec. */ -arguments.str = subject + start_offset; -arguments.begin = subject; -arguments.end = subject + length; -arguments.match_data = match_data; -arguments.startchar_ptr = subject; -arguments.mark_ptr = NULL; -arguments.options = options; - -if (mcontext != NULL) - { - arguments.callout = mcontext->callout; - arguments.callout_data = mcontext->callout_data; - arguments.offset_limit = mcontext->offset_limit; - arguments.limit_match = (mcontext->match_limit < re->limit_match)? - mcontext->match_limit : re->limit_match; - if (mcontext->jit_callback != NULL) - jit_stack = mcontext->jit_callback(mcontext->jit_callback_data); - else - jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data; - } -else - { - arguments.callout = NULL; - arguments.callout_data = NULL; - arguments.offset_limit = PCRE2_UNSET; - arguments.limit_match = (MATCH_LIMIT < re->limit_match)? - MATCH_LIMIT : re->limit_match; - jit_stack = NULL; - } - -/* JIT only need two offsets for each ovector entry. Hence - the last 1/3 of the ovector will never be touched. */ - -max_oveccount = functions->top_bracket; -if (oveccount > max_oveccount) - oveccount = max_oveccount; -arguments.oveccount = oveccount << 1; - - -convert_executable_func.executable_func = functions->executable_funcs[index]; -if (jit_stack != NULL) - { - arguments.stack = (struct sljit_stack *)(jit_stack->stack); - rc = convert_executable_func.call_executable_func(&arguments); - } -else - rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func); - -if (rc > (int)oveccount) - rc = 0; -match_data->code = re; -match_data->subject = subject; -match_data->rc = rc; -match_data->startchar = arguments.startchar_ptr - subject; -match_data->leftchar = 0; -match_data->rightchar = 0; -match_data->mark = arguments.mark_ptr; -match_data->matchedby = PCRE2_MATCHEDBY_JIT; - -return match_data->rc; - -#endif /* SUPPORT_JIT */ -} - -/* End of pcre2_jit_match.c */ diff --git a/pcre2/src/pcre2_jit_misc.c b/pcre2/src/pcre2_jit_misc.c deleted file mode 100644 index efdb05580..000000000 --- a/pcre2/src/pcre2_jit_misc.c +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE -#error This file must be included from pcre2_jit_compile.c. -#endif - - - -/************************************************* -* Free JIT read-only data * -*************************************************/ - -void -PRIV(jit_free_rodata)(void *current, void *allocator_data) -{ -#ifndef SUPPORT_JIT -(void)current; -(void)allocator_data; -#else /* SUPPORT_JIT */ -void *next; - -SLJIT_UNUSED_ARG(allocator_data); - -while (current != NULL) - { - next = *(void**)current; - SLJIT_FREE(current, allocator_data); - current = next; - } - -#endif /* SUPPORT_JIT */ -} - -/************************************************* -* Free JIT compiled code * -*************************************************/ - -void -PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) -{ -#ifndef SUPPORT_JIT -(void)executable_jit; -(void)memctl; -#else /* SUPPORT_JIT */ - -executable_functions *functions = (executable_functions *)executable_jit; -void *allocator_data = memctl; -int i; - -for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) - { - if (functions->executable_funcs[i] != NULL) - sljit_free_code(functions->executable_funcs[i]); - PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); - } - -SLJIT_FREE(functions, allocator_data); - -#endif /* SUPPORT_JIT */ -} - - -/************************************************* -* Free unused JIT memory * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_jit_free_unused_memory(pcre2_general_context *gcontext) -{ -#ifndef SUPPORT_JIT -(void)gcontext; /* Suppress warning */ -#else /* SUPPORT_JIT */ -SLJIT_UNUSED_ARG(gcontext); -sljit_free_unused_memory_exec(); -#endif /* SUPPORT_JIT */ -} - - - -/************************************************* -* Allocate a JIT stack * -*************************************************/ - -PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION -pcre2_jit_stack_create(size_t startsize, size_t maxsize, - pcre2_general_context *gcontext) -{ -#ifndef SUPPORT_JIT - -(void)gcontext; -(void)startsize; -(void)maxsize; -return NULL; - -#else /* SUPPORT_JIT */ - -pcre2_jit_stack *jit_stack; - -if (startsize < 1 || maxsize < 1) - return NULL; -if (startsize > maxsize) - startsize = maxsize; -startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); -maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); - -jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); -if (jit_stack == NULL) return NULL; -jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); -return jit_stack; - -#endif -} - - -/************************************************* -* Assign a JIT stack to a pattern * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback, - void *callback_data) -{ -#ifndef SUPPORT_JIT -(void)mcontext; -(void)callback; -(void)callback_data; -#else /* SUPPORT_JIT */ - -if (mcontext == NULL) return; -mcontext->jit_callback = callback; -mcontext->jit_callback_data = callback_data; - -#endif /* SUPPORT_JIT */ -} - - -/************************************************* -* Free a JIT stack * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_jit_stack_free(pcre2_jit_stack *jit_stack) -{ -#ifndef SUPPORT_JIT -(void)jit_stack; -#else /* SUPPORT_JIT */ -if (jit_stack != NULL) - { - sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl); - jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); - } -#endif /* SUPPORT_JIT */ -} - - -/************************************************* -* Get target CPU type * -*************************************************/ - -const char* -PRIV(jit_get_target)(void) -{ -#ifndef SUPPORT_JIT -return "JIT is not supported"; -#else /* SUPPORT_JIT */ -return sljit_get_platform_name(); -#endif /* SUPPORT_JIT */ -} - - -/************************************************* -* Get size of JIT code * -*************************************************/ - -size_t -PRIV(jit_get_size)(void *executable_jit) -{ -#ifndef SUPPORT_JIT -(void)executable_jit; -return 0; -#else /* SUPPORT_JIT */ -sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes; -SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed); -return executable_sizes[0] + executable_sizes[1] + executable_sizes[2]; -#endif -} - -/* End of pcre2_jit_misc.c */ diff --git a/pcre2/src/pcre2_jit_test.c b/pcre2/src/pcre2_jit_test.c deleted file mode 100644 index 78837cf56..000000000 --- a/pcre2/src/pcre2_jit_test.c +++ /dev/null @@ -1,1735 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#define PCRE2_CODE_UNIT_WIDTH 0 -#include "pcre2.h" - -/* - Letter characters: - \xe6\x92\xad = 0x64ad = 25773 (kanji) - Non-letter characters: - \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark) - \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888 - \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character) - \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character) - Newlines: - \xc2\x85 = 0x85 = 133 (NExt Line = NEL) - \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator) - Othercase pairs: - \xc3\xa9 = 0xe9 = 233 (e') - \xc3\x89 = 0xc9 = 201 (E') - \xc3\xa1 = 0xe1 = 225 (a') - \xc3\x81 = 0xc1 = 193 (A') - \x53 = 0x53 = S - \x73 = 0x73 = s - \xc5\xbf = 0x17f = 383 (long S) - \xc8\xba = 0x23a = 570 - \xe2\xb1\xa5 = 0x2c65 = 11365 - \xe1\xbd\xb8 = 0x1f78 = 8056 - \xe1\xbf\xb8 = 0x1ff8 = 8184 - \xf0\x90\x90\x80 = 0x10400 = 66560 - \xf0\x90\x90\xa8 = 0x10428 = 66600 - \xc7\x84 = 0x1c4 = 452 - \xc7\x85 = 0x1c5 = 453 - \xc7\x86 = 0x1c6 = 454 - Caseless sets: - ucp_Armenian - \x{531}-\x{556} -> \x{561}-\x{586} - ucp_Coptic - \x{2c80}-\x{2ce3} -> caseless: XOR 0x1 - ucp_Latin - \x{ff21}-\x{ff3a} -> \x{ff41]-\x{ff5a} - - Mark property: - \xcc\x8d = 0x30d = 781 - Special: - \xc2\x80 = 0x80 = 128 (lowest 2 byte character) - \xdf\xbf = 0x7ff = 2047 (highest 2 byte character) - \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character) - \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character) - \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character) - \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character) -*/ - -static int regression_tests(void); - -int main(void) -{ - int jit = 0; -#if defined SUPPORT_PCRE2_8 - pcre2_config_8(PCRE2_CONFIG_JIT, &jit); -#elif defined SUPPORT_PCRE2_16 - pcre2_config_16(PCRE2_CONFIG_JIT, &jit); -#elif defined SUPPORT_PCRE2_32 - pcre2_config_32(PCRE2_CONFIG_JIT, &jit); -#endif - if (!jit) { - printf("JIT must be enabled to run pcre_jit_test\n"); - return 1; - } - return regression_tests(); -} - -/* --------------------------------------------------------------------------------------- */ - -#if !(defined SUPPORT_PCRE2_8) && !(defined SUPPORT_PCRE2_16) && !(defined SUPPORT_PCRE2_32) -#error SUPPORT_PCRE2_8 or SUPPORT_PCRE2_16 or SUPPORT_PCRE2_32 must be defined -#endif - -#define MU (PCRE2_MULTILINE | PCRE2_UTF) -#define MUP (PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP) -#define CMU (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF) -#define CMUP (PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP) -#define M (PCRE2_MULTILINE) -#define MP (PCRE2_MULTILINE | PCRE2_UCP) -#define U (PCRE2_UTF) -#define CM (PCRE2_CASELESS | PCRE2_MULTILINE) - -#define BSR(x) ((x) << 16) -#define A PCRE2_NEWLINE_ANYCRLF - -#define GET_NEWLINE(x) ((x) & 0xffff) -#define GET_BSR(x) ((x) >> 16) - -#define OFFSET_MASK 0x00ffff -#define F_NO8 0x010000 -#define F_NO16 0x020000 -#define F_NO32 0x020000 -#define F_NOMATCH 0x040000 -#define F_DIFF 0x080000 -#define F_FORCECONV 0x100000 -#define F_PROPERTY 0x200000 -#define F_STUDY 0x400000 - -struct regression_test_case { - int compile_options; - int newline; - int match_options; - int start_offset; - const char *pattern; - const char *input; -}; - -static struct regression_test_case regression_test_cases[] = { - /* Constant strings. */ - { MU, A, 0, 0, "AbC", "AbAbC" }, - { MU, A, 0, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" }, - { CMU, A, 0, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" }, - { M, A, 0, 0, "[^a]", "aAbB" }, - { CM, A, 0, 0, "[^m]", "mMnN" }, - { M, A, 0, 0, "a[^b][^#]", "abacd" }, - { CM, A, 0, 0, "A[^B][^E]", "abacd" }, - { CMU, A, 0, 0, "[^x][^#]", "XxBll" }, - { MU, A, 0, 0, "[^a]", "aaa\xc3\xa1#Ab" }, - { CMU, A, 0, 0, "[^A]", "aA\xe6\x92\xad" }, - { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\n+bc" }, - { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\r+bc" }, - { MU, A, 0, 0, "\\W(\\W)?\\w", "\r\r+bc" }, - { MU, A, 0, 0, "\\W(\\W)?\\w", "\n\n+bc" }, - { MU, A, 0, 0, "[axd]", "sAXd" }, - { CMU, A, 0, 0, "[axd]", "sAXd" }, - { CMU, A, 0, 0 | F_NOMATCH, "[^axd]", "DxA" }, - { MU, A, 0, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" }, - { MU, A, 0, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, - { CMU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, - { MU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, - { MU, A, 0, 0, "[^a]", "\xc2\x80[]" }, - { CMU, A, 0, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, - { CM, A, 0, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, - { PCRE2_CASELESS, 0, 0, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, - { PCRE2_CASELESS, 0, 0, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, - { PCRE2_CASELESS, 0, 0, 0, "a1", "Aa1" }, - { M, A, 0, 0, "\\Ca", "cda" }, - { CM, A, 0, 0, "\\Ca", "CDA" }, - { M, A, 0, 0 | F_NOMATCH, "\\Cx", "cda" }, - { CM, A, 0, 0 | F_NOMATCH, "\\Cx", "CDA" }, - { CMUP, A, 0, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, - { CMUP, A, 0, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, - { CMUP, A, 0, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, - { CMUP, A, 0, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, - { M, A, 0, 0, "[3-57-9]", "5" }, - - /* Assertions. */ - { MU, A, 0, 0, "\\b[^A]", "A_B#" }, - { M, A, 0, 0 | F_NOMATCH, "\\b\\W", "\n*" }, - { MU, A, 0, 0, "\\B[^,]\\b[^s]\\b", "#X" }, - { MP, A, 0, 0, "\\B", "_\xa1" }, - { MP, A, 0, 0 | F_PROPERTY, "\\b_\\b[,A]\\B", "_," }, - { MUP, A, 0, 0, "\\b", "\xe6\x92\xad!" }, - { MUP, A, 0, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" }, - { MUP, A, 0, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" }, - { MUP, A, 0, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, - { MU, A, 0, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" }, - { CMUP, A, 0, 0, "\\By", "\xf0\x90\x90\xa8y" }, - { M, A, 0, 0 | F_NOMATCH, "\\R^", "\n" }, - { M, A, 0, 1 | F_NOMATCH, "^", "\n" }, - { 0, 0, 0, 0, "^ab", "ab" }, - { 0, 0, 0, 0 | F_NOMATCH, "^ab", "aab" }, - { M, PCRE2_NEWLINE_CRLF, 0, 0, "^a", "\r\raa\n\naa\r\naa" }, - { MU, A, 0, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" }, - { M, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--b--\x85--" }, - { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xe2\x80\xa8--" }, - { MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xc2\x85--" }, - { 0, 0, 0, 0, "ab$", "ab" }, - { 0, 0, 0, 0 | F_NOMATCH, "ab$", "abab\n\n" }, - { PCRE2_DOLLAR_ENDONLY, 0, 0, 0 | F_NOMATCH, "ab$", "abab\r\n" }, - { M, PCRE2_NEWLINE_CRLF, 0, 0, "a$", "\r\raa\n\naa\r\naa" }, - { M, PCRE2_NEWLINE_ANY, 0, 0, "a$", "aaa" }, - { MU, PCRE2_NEWLINE_ANYCRLF, 0, 0, "#$", "#\xc2\x85###\r#" }, - { MU, PCRE2_NEWLINE_ANY, 0, 0, "#$", "#\xe2\x80\xa9" }, - { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0 | F_NOMATCH, "^a", "aa\naa" }, - { M, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0, "^a", "aa\naa" }, - { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\naa" }, - { 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\r\n" }, - { U | PCRE2_DOLLAR_ENDONLY, PCRE2_NEWLINE_ANY, 0, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" }, - { M, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0, "a$", "aa\naa" }, - { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa" }, - { U, PCRE2_NEWLINE_CR, 0, 0, "a\\Z", "aaa\r" }, - { 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa\n" }, - { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r" }, - { U, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\n" }, - { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r\n" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" }, - { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xc2\x85" }, - { U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" }, - { M, A, 0, 0, "\\Aa", "aaa" }, - { M, A, 0, 1 | F_NOMATCH, "\\Aa", "aaa" }, - { M, A, 0, 1, "\\Ga", "aaa" }, - { M, A, 0, 1 | F_NOMATCH, "\\Ga", "aba" }, - { M, A, 0, 0, "a\\z", "aaa" }, - { M, A, 0, 0 | F_NOMATCH, "a\\z", "aab" }, - - /* Brackets and alternatives. */ - { MU, A, 0, 0, "(ab|bb|cd)", "bacde" }, - { MU, A, 0, 0, "(?:ab|a)(bc|c)", "ababc" }, - { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" }, - { CMU, A, 0, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" }, - { MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" }, - { MU, A, 0, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" }, - { MU, A, 0, 0, "\xc7\x82|\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, - { MU, A, 0, 0, "=\xc7\x82|#\xc6\x82", "\xf1\x83\x82\x82=\xc7\x82\xc7\x83" }, - { MU, A, 0, 0, "\xc7\x82\xc7\x83|\xc6\x82\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, - { MU, A, 0, 0, "\xc6\x82\xc6\x82|\xc7\x83\xc7\x83|\xc8\x84\xc8\x84", "\xf1\x83\x82\x82\xc8\x84\xc8\x84" }, - - /* Greedy and non-greedy ? operators. */ - { MU, A, 0, 0, "(?:a)?a", "laab" }, - { CMU, A, 0, 0, "(A)?A", "llaab" }, - { MU, A, 0, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */ - { MU, A, 0, 0, "(a)?a", "manm" }, - { CMU, A, 0, 0, "(a|b)?\?d((?:e)?)", "ABABdx" }, - { MU, A, 0, 0, "(a|b)?\?d((?:e)?)", "abcde" }, - { MU, A, 0, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" }, - - /* Greedy and non-greedy + operators */ - { MU, A, 0, 0, "(aa)+aa", "aaaaaaa" }, - { MU, A, 0, 0, "(aa)+?aa", "aaaaaaa" }, - { MU, A, 0, 0, "(?:aba|ab|a)+l", "ababamababal" }, - { MU, A, 0, 0, "(?:aba|ab|a)+?l", "ababamababal" }, - { MU, A, 0, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, - { MU, A, 0, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, - { MU, A, 0, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" }, - - /* Greedy and non-greedy * operators */ - { CMU, A, 0, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" }, - { MU, A, 0, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" }, - { MU, A, 0, 0, "(aa|ab)*ab", "aaabaaab" }, - { CMU, A, 0, 0, "(aa|Ab)*?aB", "aaabaaab" }, - { MU, A, 0, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" }, - { MU, A, 0, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" }, - { M, A, 0, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" }, - { M, A, 0, 0, "((?:a|)*){0}a", "a" }, - - /* Combining ? + * operators */ - { MU, A, 0, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" }, - { MU, A, 0, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" }, - { MU, A, 0, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" }, - { MU, A, 0, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" }, - { MU, A, 0, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" }, - - /* Single character iterators. */ - { MU, A, 0, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" }, - { MU, A, 0, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" }, - { MU, A, 0, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" }, - { MU, A, 0, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" }, - { MU, A, 0, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" }, - { MU, A, 0, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" }, - { MU, A, 0, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" }, - { MU, A, 0, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" }, - { MU, A, 0, 0, "(ba{2})+c", "baabaaabacbaabaac" }, - { MU, A, 0, 0, "(a*+bc++)+", "aaabbcaaabcccab" }, - { MU, A, 0, 0, "(a?+[^b])+", "babaacacb" }, - { MU, A, 0, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" }, - { CMU, A, 0, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" }, - { CMU, A, 0, 0, "[c-f]+k", "DemmFke" }, - { MU, A, 0, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" }, - { MU, A, 0, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" }, - { CMU, A, 0, 0, "[ace]{3,7}", "AcbDAcEEcEd" }, - { CMU, A, 0, 0, "[ace]{3,7}?", "AcbDAcEEcEd" }, - { CMU, A, 0, 0, "[ace]{3,}", "AcbDAcEEcEd" }, - { CMU, A, 0, 0, "[ace]{3,}?", "AcbDAcEEcEd" }, - { MU, A, 0, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" }, - { CMU, A, 0, 0, "[ace]{5}?", "AcCebDAcEEcEd" }, - { MU, A, 0, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" }, - { MU, A, 0, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" }, - { MU, A, 0, 0, "\\b\\w+\\B", "x,a_cd" }, - { MUP, A, 0, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, - { CMU, A, 0, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" }, - { CMUP, A, 0, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" }, - { CMU, A, 0, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" }, - { CMU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, - { MU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, - { MU, A, 0, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" }, - { MU, A, 0, 0, "\\d+123", "987654321,01234" }, - { MU, A, 0, 0, "abcd*|\\w+xy", "aaaaa,abxyz" }, - { MU, A, 0, 0, "(?:abc|((?:amc|\\b\\w*xy)))", "aaaaa,abxyz" }, - { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.abcd#."}, - { MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.mbcd#."}, - { MU, A, 0, 0, ".[ab]*.", "xx" }, - { MU, A, 0, 0, ".[ab]*a", "xxa" }, - { MU, A, 0, 0, ".[ab]?.", "xx" }, - - /* Bracket repeats with limit. */ - { MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" }, - { MU, A, 0, 0, "(?:ab|abab){1,5}M", "abababababababababababM" }, - { MU, A, 0, 0, "(?>ab|abab){1,5}M", "abababababababababababM" }, - { MU, A, 0, 0, "(?:ab|abab){1,5}?M", "abababababababababababM" }, - { MU, A, 0, 0, "(?>ab|abab){1,5}?M", "abababababababababababM" }, - { MU, A, 0, 0, "(?:(ab){1,4}?){1,3}?M", "abababababababababababababM" }, - { MU, A, 0, 0, "(?:(ab){1,4}){1,3}abababababababababababM", "ababababababababababababM" }, - { MU, A, 0, 0 | F_NOMATCH, "(?:(ab){1,4}){1,3}abababababababababababM", "abababababababababababM" }, - { MU, A, 0, 0, "(ab){4,6}?M", "abababababababM" }, - - /* Basic character sets. */ - { MU, A, 0, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " }, - { MU, A, 0, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" }, - { MU, A, 0, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" }, - { MU, A, 0, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" }, - { MU, A, 0, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" }, - { MU, A, 0, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" }, - { MU, A, 0, 0, "x[bcef]+", "xaxdxecbfg" }, - { MU, A, 0, 0, "x[bcdghij]+", "xaxexfxdgbjk" }, - { MU, A, 0, 0, "x[^befg]+", "xbxexacdhg" }, - { MU, A, 0, 0, "x[^bcdl]+", "xlxbxaekmd" }, - { MU, A, 0, 0, "x[^bcdghi]+", "xbxdxgxaefji" }, - { MU, A, 0, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" }, - { CMU, A, 0, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" }, - { CMU, A, 0, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" }, - { MU, A, 0, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" }, - { MU, A, 0, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" }, - { MU, A, 0, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" }, - { MU, A, 0, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" }, - { MU, A, 0, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" }, - { MU, A, 0, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" }, - { MU, A, 0, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" }, - { MU, A, 0, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" }, - - /* Unicode properties. */ - { MUP, A, 0, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" }, - { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" }, - { MUP, A, 0, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, - { MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, - { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, - { MUP, A, 0, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, - { MUP, A, 0, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" }, - { CMUP, A, 0, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" }, - { MUP, A, 0, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" }, - { MUP, A, 0, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" }, - { MU, A, 0, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" }, - { CMUP, A, 0, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" }, - { MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" }, - { MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" }, - { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB baaa" }, - - /* Possible empty brackets. */ - { MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" }, - { MU, A, 0, 0, "(|ab||bc|a)+d", "abcxabcabd" }, - { MU, A, 0, 0, "(?:|ab||bc|a)*d", "abcxabcabd" }, - { MU, A, 0, 0, "(|ab||bc|a)*d", "abcxabcabd" }, - { MU, A, 0, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" }, - { MU, A, 0, 0, "(|ab||bc|a)+?d", "abcxabcabd" }, - { MU, A, 0, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" }, - { MU, A, 0, 0, "(|ab||bc|a)*?d", "abcxabcabd" }, - { MU, A, 0, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" }, - { MU, A, 0, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" }, - - /* Start offset. */ - { MU, A, 0, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" }, - { MU, A, 0, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, - { MU, A, 0, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, - { MU, A, 0, 1, "(\\w\\W\\w)+", "ab#d" }, - - /* Newline. */ - { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, - { M, PCRE2_NEWLINE_CR, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, - { M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{1,3}[^#]", "\r\n##...." }, - { MU, A, PCRE2_NO_UTF_CHECK, 1, "^.a", "\n\x80\nxa" }, - { MU, A, 0, 1, "^", "\r\n" }, - { M, PCRE2_NEWLINE_CRLF, 0, 1 | F_NOMATCH, "^", "\r\n" }, - { M, PCRE2_NEWLINE_CRLF, 0, 1, "^", "\r\na" }, - - /* Any character except newline or any newline. */ - { 0, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" }, - { U, PCRE2_NEWLINE_CRLF, 0, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" }, - { 0, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, - { U, PCRE2_NEWLINE_ANY, 0, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" }, - { U, PCRE2_NEWLINE_ANYCRLF, 0, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" }, - { 0, PCRE2_NEWLINE_ANY, 0, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" }, - { U, PCRE2_NEWLINE_ANY, 0, 0, "(.+)#", "#\rMn\xc2\x85#\n###" }, - { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\r" }, - { 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\x85#\r\n#" }, - { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\xe2\x80\xa8#c" }, - { U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\r\nc" }, - { U, PCRE2_NEWLINE_CRLF | BSR(PCRE2_BSR_UNICODE), 0, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" }, - { MU, A, 0, 0 | F_NOMATCH, "\\R+", "ab" }, - { MU, A, 0, 0, "\\R+", "ab\r\n\r" }, - { MU, A, 0, 0, "\\R*", "ab\r\n\r" }, - { MU, A, 0, 0, "\\R*", "\r\n\r" }, - { MU, A, 0, 0, "\\R{2,4}", "\r\nab\r\r" }, - { MU, A, 0, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" }, - { MU, A, 0, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" }, - { MU, A, 0, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" }, - { MU, A, 0, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" }, - { MU, A, 0, 0, "\\R+\\R\\R", "\r\r\r" }, - { MU, A, 0, 0, "\\R*\\R\\R", "\n\r" }, - { MU, A, 0, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" }, - { MU, A, 0, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" }, - - /* Atomic groups (no fallback from "next" direction). */ - { MU, A, 0, 0 | F_NOMATCH, "(?>ab)ab", "bab" }, - { MU, A, 0, 0 | F_NOMATCH, "(?>(ab))ab", "bab" }, - { MU, A, 0, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op", - "bababcdedefgheijijklmlmnop" }, - { MU, A, 0, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" }, - { MU, A, 0, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" }, - { MU, A, 0, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" }, - { MU, A, 0, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" }, - { MU, A, 0, 0, "((?>a|)+?)b", "aaacaaab" }, - { MU, A, 0, 0, "(?>x|)*$", "aaa" }, - { MU, A, 0, 0, "(?>(x)|)*$", "aaa" }, - { MU, A, 0, 0, "(?>x|())*$", "aaa" }, - { MU, A, 0, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" }, - { MU, A, 0, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" }, - { MU, A, 0, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" }, - { MU, A, 0, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" }, - { MU, A, 0, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" }, - { MU, A, 0, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" }, - { MU, A, 0, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" }, - { MU, A, 0, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" }, - { MU, A, 0, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" }, - { MU, A, 0, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" }, - { MU, A, 0, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" }, - { MU, A, 0, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" }, - { MU, A, 0, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" }, - { MU, A, 0, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" }, - { CM, A, 0, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" }, - { MU, A, 0, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, - { MU, A, 0, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" }, - { MU, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" }, - { MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" }, - { MU, A, 0, 0, "(c(ab)?+ab)+", "cabcababcab" }, - { MU, A, 0, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, - - /* Possessive quantifiers. */ - { MU, A, 0, 0, "(?:a|b)++m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, - { MU, A, 0, 0, "(a|b)++m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(a|b)*+m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(a|b)*+m", "ababbaaxababbaam" }, - { MU, A, 0, 0, "(a|b(*ACCEPT))++m", "maaxab" }, - { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(b*)++m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, - { MU, A, 0, 0, "(a|(b))++m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "((a)|b)*+m", "mababbaaxababbaam" }, - { MU, A, 0, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, - { MU, A, 0, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, - { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "((b*))++m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxm" }, - { MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxbbm" }, - { MU, A, 0, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" }, - { MU, A, 0, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" }, - { MU, A, 0, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" }, - { MU, A, 0, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, - { MU, A, 0, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, - - /* Back references. */ - { MU, A, 0, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" }, - { CMU, A, 0, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" }, - { CM, A, 0, 0, "(a{2,4})\\1", "AaAaaAaA" }, - { MU, A, 0, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" }, - { MU, A, 0, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" }, - { MU, A, 0, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, - { MU, A, 0, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, - { MU, A, 0, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" }, - { MU, A, 0, 0, "(?:(aa)|b)\\1?b", "bb" }, - { CMU, A, 0, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" }, - { MU, A, 0, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" }, - { CMU, A, 0, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" }, - { MU, A, 0, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, - { CM, A, 0, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, - { MU, A, 0, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" }, - { MU, A, 0, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" }, - { M, A, 0, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" }, - { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, - { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." }, - { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" }, - { MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" }, - { PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, - { CMUP, A, 0, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" }, - { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k{1,3}(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k{1,3}(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k*(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?aa)(?bb)\\k{0,3}aaaaaa", "aabbaaaaaa" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?aa)(?bb)\\k{2,5}bb", "aabbaaaabb" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{0,3}m", "aaaaaaaabbbbaabbbbm" }, - { MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k{1,3}?(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k{1,3}?(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "\\k*?(?aa)(?bb)", "aabb" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{0,3}?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k*?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, - { MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?aa)|(?bb))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, - { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{0,3}M", "aaaaaaaabbbbaabbbbm" }, - { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{1,3}M", "aaaaaaaabbbbaabbbbm" }, - { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{0,3}?M", "aaaaaabbbbbbaabbbbbbbbbbm" }, - { CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?AA)|(?BB))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, - - /* Assertions. */ - { MU, A, 0, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" }, - { MU, A, 0, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" }, - { MU, A, 0, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" }, - { MU, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" }, - { MU, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" }, - { M, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" }, - { M, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" }, - { MU, A, 0, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" }, - { MU, A, 0, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" }, - { MU, A, 0, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" }, - { MU, A, 0, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" }, - { MU, A, 0, 0, "((?(?=(a))a)+k)", "bbak" }, - { MU, A, 0, 0, "((?(?=a)a)+k)", "bbak" }, - { MU, A, 0, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" }, - { MU, A, 0, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" }, - { MU, A, 0, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" }, - { MU, A, 0, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" }, - { MU, A, 0, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" }, - { MU, A, 0, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, - { MU, A, 0, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, - { MU, A, 0, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" }, - { MU, A, 0, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" }, - { MU, A, 0, 0, "((?!a)?(?!([^a]))?)+$", "acbab" }, - { MU, A, 0, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" }, - { MU, A, 0, 0, "a(?=(?C)\\B(?C`x`))b", "ab" }, - { MU, A, 0, 0, "a(?!(?C)\\B(?C`x`))bb|ab", "abb" }, - { MU, A, 0, 0, "a(?=\\b|(?C)\\B(?C`x`))b", "ab" }, - { MU, A, 0, 0, "a(?!\\b|(?C)\\B(?C`x`))bb|ab", "abb" }, - { MU, A, 0, 0, "c(?(?=(?C)\\B(?C`x`))ab|a)", "cab" }, - { MU, A, 0, 0, "c(?(?!(?C)\\B(?C`x`))ab|a)", "cab" }, - { MU, A, 0, 0, "c(?(?=\\b|(?C)\\B(?C`x`))ab|a)", "cab" }, - { MU, A, 0, 0, "c(?(?!\\b|(?C)\\B(?C`x`))ab|a)", "cab" }, - { MU, A, 0, 0, "a(?=)b", "ab" }, - { MU, A, 0, 0 | F_NOMATCH, "a(?!)b", "ab" }, - - /* Not empty, ACCEPT, FAIL */ - { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" }, - { MU, A, PCRE2_NOTEMPTY, 0, "a*", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY, 0, "a*?", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*", "bcaad" }, - { MU, A, 0, 0, "a(*ACCEPT)b", "ab" }, - { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" }, - { MU, A, PCRE2_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" }, - { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" }, - { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" }, - { MU, A, PCRE2_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" }, - { MU, A, 0, 0, "((a(*ACCEPT)b))", "ab" }, - { MU, A, 0, 0, "(a(*FAIL)a|a)", "aaa" }, - { MU, A, 0, 0, "(?=ab(*ACCEPT)b)a", "ab" }, - { MU, A, 0, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" }, - { MU, A, 0, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" }, - { MU, A, PCRE2_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" }, - - /* Conditional blocks. */ - { MU, A, 0, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, - { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, - { MU, A, 0, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, - { MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, - { MU, A, 0, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" }, - { MU, A, 0, 0, "(?(?=a)ab)", "a" }, - { MU, A, 0, 0, "(?(?a)?(?Pb)?(?(Name)c|d)*l", "bc ddd abccabccl" }, - { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" }, - { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" }, - { MU, A, 0, 0, "((?:a|aa)(?(1)aaa))x", "aax" }, - { MU, A, 0, 0, "(?(?!)a|b)", "ab" }, - { MU, A, 0, 0, "(?(?!)a)", "ab" }, - { MU, A, 0, 0 | F_NOMATCH, "(?(?!)a|b)", "ac" }, - - /* Set start of match. */ - { MU, A, 0, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, - { MU, A, 0, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, - { MU, A, 0, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, - { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" }, - { MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" }, - - /* First line. */ - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0, "(?<=a)", "a" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[^a][^b]", "ab" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "a", "\na" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[abc]", "\na" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^a", "\na" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^(?<=\n)", "\na" }, - { MU | PCRE2_FIRSTLINE, A, 0, 0, "\xf0\x90\x90\x80", "\xf0\x90\x90\x80" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\xc2\x85#" }, - { M | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\x85#" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_PROPERTY, "\\p{Any}", "\r\na" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, "a", "\ra" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH, "ba", "bbb\r\nba" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" }, - { MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 1, ".", "\r\n" }, - { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_LF, 0, 0 | F_NOMATCH, "ab.", "ab" }, - { MU | PCRE2_FIRSTLINE, A, 0, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" }, - { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_ANY, 0, 0, "....a", "012\n0a" }, - - /* Recurse. */ - { MU, A, 0, 0, "(a)(?1)", "aa" }, - { MU, A, 0, 0, "((a))(?1)", "aa" }, - { MU, A, 0, 0, "(b|a)(?1)", "aa" }, - { MU, A, 0, 0, "(b|(a))(?1)", "aa" }, - { MU, A, 0, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" }, - { MU, A, 0, 0, "((a)(b)(?:a*))(?1)", "abab" }, - { MU, A, 0, 0, "((a+)c(?2))b(?1)", "aacaabaca" }, - { MU, A, 0, 0, "((?2)b|(a)){2}(?1)", "aabab" }, - { MU, A, 0, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" }, - { MU, A, 0, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" }, - { MU, A, 0, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" }, - { MU, A, 0, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" }, - { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" }, - { MU, A, 0, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" }, - { MU, A, 0, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" }, - { MU, A, 0, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" }, - { MU, A, 0, 0, "b|<(?R)*>", "<" }, - { MU, A, 0, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" }, - { MU, A, 0, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" }, - { MU, A, 0, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" }, - { MU, A, 0, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" }, - { MU, A, 0, 0, "(a)((?(R1)a|b))(?2)", "ababba" }, - { MU, A, 0, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" }, - { MU, A, 0, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" }, - { MU, A, 0, 0, "(?Pa(?(R&Name)a|b))(?1)", "aab abb abaa" }, - { MU, A, 0, 0, "((?(R)a|(?1)){3})", "XaaaaaaaaaX" }, - { MU, A, 0, 0, "((?:(?(R)a|(?1))){3})", "XaaaaaaaaaX" }, - { MU, A, 0, 0, "((?(R)a|(?1)){1,3})aaaaaa", "aaaaaaaaXaaaaaaaaa" }, - { MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" }, - - /* 16 bit specific tests. */ - { CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" }, - { CM, A, 0, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" }, - { CM, A, 0, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" }, - { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" }, - { CM, A, 0, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" }, - { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" }, - { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" }, - { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" }, - { CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" }, - { CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" }, - { M, A, 0, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, - { M, A, 0, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, - { CM, A, 0, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" }, - { CM, A, 0, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" }, - { CM, A, 0, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" }, - { CM, A, 0, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" }, - { CM | PCRE2_EXTENDED, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" }, - { CM, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" }, - { CM, A, 0, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" }, - { M, PCRE2_NEWLINE_ANY, 0, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" }, - { 0, BSR(PCRE2_BSR_UNICODE), 0, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" }, - { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" }, - { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" }, - { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" }, - { 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" }, - - /* Partial matching. */ - { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab", "a" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "ab|a", "a" }, - { MU, A, PCRE2_PARTIAL_HARD, 0, "ab|a", "a" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "\\b#", "a" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "(?<=a)b", "a" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "a\\B", "a" }, - { MU, A, PCRE2_PARTIAL_HARD, 0, "a\\b", "a" }, - - /* (*MARK) verb. */ - { MU, A, 0, 0, "a(*MARK:aa)a", "ababaa" }, - { MU, A, 0, 0 | F_NOMATCH, "a(*:aa)a", "abab" }, - { MU, A, 0, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" }, - { MU, A, 0, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" }, - { MU, A, 0, 0, "(?>a(*:aa))b|ac", "ac" }, - { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" }, - { MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" }, - { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" }, - { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, - { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, - { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, - { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(*:mark)m", "a" }, - - /* (*COMMIT) verb. */ - { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" }, - { MU, A, 0, 0, "aa(*COMMIT)b", "xaxaab" }, - { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" }, - { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b)++", "abac" }, - { MU, A, 0, 0 | F_NOMATCH, "((a)(*COMMIT)b)++", "abac" }, - { MU, A, 0, 0 | F_NOMATCH, "(?=a(*COMMIT)b)ab|ad", "ad" }, - - /* (*PRUNE) verb. */ - { MU, A, 0, 0, "aa\\K(*PRUNE)b", "aaab" }, - { MU, A, 0, 0, "aa(*PRUNE:bb)b|a", "aa" }, - { MU, A, 0, 0, "(a)(a)(*PRUNE)b|(a)", "aa" }, - { MU, A, 0, 0, "(a)(a)(a)(a)(a)(a)(a)(a)(*PRUNE)b|(a)", "aaaaaaaa" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|", "a" }, - { MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|m", "a" }, - { MU, A, 0, 0 | F_NOMATCH, "(?=a(*PRUNE)b)ab|ad", "ad" }, - { MU, A, 0, 0, "a(*COMMIT)(*PRUNE)d|bc", "abc" }, - { MU, A, 0, 0, "(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0, "(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0, "(a(*COMMIT)b){0}a(?1)(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b){0}a(*COMMIT)(?1)(*PRUNE)c|bc", "abc" }, - { MU, A, 0, 0, "(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, - { MU, A, 0, 0, "((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, - { MU, A, 0, 0, "(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, - { MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, - - /* (*SKIP) verb. */ - { MU, A, 0, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" }, - { MU, A, 0, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," }, - { MU, A, 0, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," }, - { MU, A, 0, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" }, - - /* (*THEN) verb. */ - { MU, A, 0, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" }, - { MU, A, 0, 0 | F_NOMATCH, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcm" }, - { MU, A, 0, 0, "((?:a(*THEN)|aab)c|a+)+m", "aabcaabcnmaabcaabcm" }, - { MU, A, 0, 0, "((?:a|aab)(*THEN)c|a+)+m", "aam" }, - { MU, A, 0, 0, "((?:a(*COMMIT)|aab)(*THEN)c|a+)+m", "aam" }, - { MU, A, 0, 0, "(?(?=a(*THEN)b)ab|ad)", "ad" }, - { MU, A, 0, 0, "(?(?!a(*THEN)b)ad|add)", "add" }, - { MU, A, 0, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" }, - { MU, A, 0, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" }, - - /* Deep recursion. */ - { MU, A, 0, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, - { MU, A, 0, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " }, - { MU, A, 0, 0, "((a?)+)+b", "aaaaaaaaaaaa b" }, - - /* Deep recursion: Stack limit reached. */ - { M, A, 0, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" }, - { M, A, 0, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, - { M, A, 0, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, - { M, A, 0, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, - { M, A, 0, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, - - { 0, 0, 0, 0, NULL, NULL } -}; - -#ifdef SUPPORT_PCRE2_8 -static pcre2_jit_stack_8* callback8(void *arg) -{ - return (pcre2_jit_stack_8 *)arg; -} -#endif - -#ifdef SUPPORT_PCRE2_16 -static pcre2_jit_stack_16* callback16(void *arg) -{ - return (pcre2_jit_stack_16 *)arg; -} -#endif - -#ifdef SUPPORT_PCRE2_32 -static pcre2_jit_stack_32* callback32(void *arg) -{ - return (pcre2_jit_stack_32 *)arg; -} -#endif - -#ifdef SUPPORT_PCRE2_8 -static pcre2_jit_stack_8 *stack8; - -static pcre2_jit_stack_8 *getstack8(void) -{ - if (!stack8) - stack8 = pcre2_jit_stack_create_8(1, 1024 * 1024, NULL); - return stack8; -} - -static void setstack8(pcre2_match_context_8 *mcontext) -{ - if (!mcontext) { - if (stack8) - pcre2_jit_stack_free_8(stack8); - stack8 = NULL; - return; - } - - pcre2_jit_stack_assign_8(mcontext, callback8, getstack8()); -} -#endif /* SUPPORT_PCRE2_8 */ - -#ifdef SUPPORT_PCRE2_16 -static pcre2_jit_stack_16 *stack16; - -static pcre2_jit_stack_16 *getstack16(void) -{ - if (!stack16) - stack16 = pcre2_jit_stack_create_16(1, 1024 * 1024, NULL); - return stack16; -} - -static void setstack16(pcre2_match_context_16 *mcontext) -{ - if (!mcontext) { - if (stack16) - pcre2_jit_stack_free_16(stack16); - stack16 = NULL; - return; - } - - pcre2_jit_stack_assign_16(mcontext, callback16, getstack16()); -} -#endif /* SUPPORT_PCRE2_16 */ - -#ifdef SUPPORT_PCRE2_32 -static pcre2_jit_stack_32 *stack32; - -static pcre2_jit_stack_32 *getstack32(void) -{ - if (!stack32) - stack32 = pcre2_jit_stack_create_32(1, 1024 * 1024, NULL); - return stack32; -} - -static void setstack32(pcre2_match_context_32 *mcontext) -{ - if (!mcontext) { - if (stack32) - pcre2_jit_stack_free_32(stack32); - stack32 = NULL; - return; - } - - pcre2_jit_stack_assign_32(mcontext, callback32, getstack32()); -} -#endif /* SUPPORT_PCRE2_32 */ - -#ifdef SUPPORT_PCRE2_16 - -static int convert_utf8_to_utf16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int *offsetmap, int max_length) -{ - PCRE2_SPTR8 iptr = input; - PCRE2_UCHAR16 *optr = output; - unsigned int c; - - if (max_length == 0) - return 0; - - while (*iptr && max_length > 1) { - c = 0; - if (offsetmap) - *offsetmap++ = (int)(iptr - (unsigned char*)input); - - if (*iptr < 0xc0) - c = *iptr++; - else if (!(*iptr & 0x20)) { - c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); - iptr += 2; - } else if (!(*iptr & 0x10)) { - c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); - iptr += 3; - } else if (!(*iptr & 0x08)) { - c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); - iptr += 4; - } - - if (c < 65536) { - *optr++ = c; - max_length--; - } else if (max_length <= 2) { - *optr = '\0'; - return (int)(optr - output); - } else { - c -= 0x10000; - *optr++ = 0xd800 | ((c >> 10) & 0x3ff); - *optr++ = 0xdc00 | (c & 0x3ff); - max_length -= 2; - if (offsetmap) - offsetmap++; - } - } - if (offsetmap) - *offsetmap = (int)(iptr - (unsigned char*)input); - *optr = '\0'; - return (int)(optr - output); -} - -static int copy_char8_to_char16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int max_length) -{ - PCRE2_SPTR8 iptr = input; - PCRE2_UCHAR16 *optr = output; - - if (max_length == 0) - return 0; - - while (*iptr && max_length > 1) { - *optr++ = *iptr++; - max_length--; - } - *optr = '\0'; - return (int)(optr - output); -} - -#define REGTEST_MAX_LENGTH16 4096 -static PCRE2_UCHAR16 regtest_buf16[REGTEST_MAX_LENGTH16]; -static int regtest_offsetmap16[REGTEST_MAX_LENGTH16]; - -#endif /* SUPPORT_PCRE2_16 */ - -#ifdef SUPPORT_PCRE2_32 - -static int convert_utf8_to_utf32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int *offsetmap, int max_length) -{ - PCRE2_SPTR8 iptr = input; - PCRE2_UCHAR32 *optr = output; - unsigned int c; - - if (max_length == 0) - return 0; - - while (*iptr && max_length > 1) { - c = 0; - if (offsetmap) - *offsetmap++ = (int)(iptr - (unsigned char*)input); - - if (*iptr < 0xc0) - c = *iptr++; - else if (!(*iptr & 0x20)) { - c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); - iptr += 2; - } else if (!(*iptr & 0x10)) { - c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); - iptr += 3; - } else if (!(*iptr & 0x08)) { - c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); - iptr += 4; - } - - *optr++ = c; - max_length--; - } - if (offsetmap) - *offsetmap = (int)(iptr - (unsigned char*)input); - *optr = 0; - return (int)(optr - output); -} - -static int copy_char8_to_char32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int max_length) -{ - PCRE2_SPTR8 iptr = input; - PCRE2_UCHAR32 *optr = output; - - if (max_length == 0) - return 0; - - while (*iptr && max_length > 1) { - *optr++ = *iptr++; - max_length--; - } - *optr = '\0'; - return (int)(optr - output); -} - -#define REGTEST_MAX_LENGTH32 4096 -static PCRE2_UCHAR32 regtest_buf32[REGTEST_MAX_LENGTH32]; -static int regtest_offsetmap32[REGTEST_MAX_LENGTH32]; - -#endif /* SUPPORT_PCRE2_32 */ - -static int check_ascii(const char *input) -{ - const unsigned char *ptr = (unsigned char *)input; - while (*ptr) { - if (*ptr > 127) - return 0; - ptr++; - } - return 1; -} - -#define OVECTOR_SIZE 15 - -static int regression_tests(void) -{ - struct regression_test_case *current = regression_test_cases; - int error; - PCRE2_SIZE err_offs; - int is_successful; - int is_ascii; - int total = 0; - int successful = 0; - int successful_row = 0; - int counter = 0; - int jit_compile_mode; - int utf = 0; - int disabled_options = 0; - int i; -#ifdef SUPPORT_PCRE2_8 - pcre2_code_8 *re8; - pcre2_compile_context_8 *ccontext8; - pcre2_match_data_8 *mdata8_1; - pcre2_match_data_8 *mdata8_2; - pcre2_match_context_8 *mcontext8; - PCRE2_SIZE *ovector8_1 = NULL; - PCRE2_SIZE *ovector8_2 = NULL; - int return_value8[2]; -#endif -#ifdef SUPPORT_PCRE2_16 - pcre2_code_16 *re16; - pcre2_compile_context_16 *ccontext16; - pcre2_match_data_16 *mdata16_1; - pcre2_match_data_16 *mdata16_2; - pcre2_match_context_16 *mcontext16; - PCRE2_SIZE *ovector16_1 = NULL; - PCRE2_SIZE *ovector16_2 = NULL; - int return_value16[2]; - int length16; -#endif -#ifdef SUPPORT_PCRE2_32 - pcre2_code_32 *re32; - pcre2_compile_context_32 *ccontext32; - pcre2_match_data_32 *mdata32_1; - pcre2_match_data_32 *mdata32_2; - pcre2_match_context_32 *mcontext32; - PCRE2_SIZE *ovector32_1 = NULL; - PCRE2_SIZE *ovector32_2 = NULL; - int return_value32[2]; - int length32; -#endif - -#if defined SUPPORT_PCRE2_8 - PCRE2_UCHAR8 cpu_info[128]; -#elif defined SUPPORT_PCRE2_16 - PCRE2_UCHAR16 cpu_info[128]; -#elif defined SUPPORT_PCRE2_32 - PCRE2_UCHAR32 cpu_info[128]; -#endif -#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2) - int return_value; -#endif - - /* This test compares the behaviour of interpreter and JIT. Although disabling - utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is - still considered successful from pcre_jit_test point of view. */ - -#if defined SUPPORT_PCRE2_8 - pcre2_config_8(PCRE2_CONFIG_JITTARGET, &cpu_info); -#elif defined SUPPORT_PCRE2_16 - pcre2_config_16(PCRE2_CONFIG_JITTARGET, &cpu_info); -#elif defined SUPPORT_PCRE2_32 - pcre2_config_32(PCRE2_CONFIG_JITTARGET, &cpu_info); -#endif - - printf("Running JIT regression tests\n"); - printf(" target CPU of SLJIT compiler: "); - for (i = 0; cpu_info[i]; i++) - printf("%c", (char)(cpu_info[i])); - printf("\n"); - -#if defined SUPPORT_PCRE2_8 - pcre2_config_8(PCRE2_CONFIG_UNICODE, &utf); -#elif defined SUPPORT_PCRE2_16 - pcre2_config_16(PCRE2_CONFIG_UNICODE, &utf); -#elif defined SUPPORT_PCRE2_32 - pcre2_config_32(PCRE2_CONFIG_UNICODE, &utf); -#endif - - if (!utf) - disabled_options |= PCRE2_UTF; -#ifdef SUPPORT_PCRE2_8 - printf(" in 8 bit mode with UTF-8 %s:\n", utf ? "enabled" : "disabled"); -#endif -#ifdef SUPPORT_PCRE2_16 - printf(" in 16 bit mode with UTF-16 %s:\n", utf ? "enabled" : "disabled"); -#endif -#ifdef SUPPORT_PCRE2_32 - printf(" in 32 bit mode with UTF-32 %s:\n", utf ? "enabled" : "disabled"); -#endif - - while (current->pattern) { - /* printf("\nPattern: %s :\n", current->pattern); */ - total++; - is_ascii = 0; - if (!(current->start_offset & F_PROPERTY)) - is_ascii = check_ascii(current->pattern) && check_ascii(current->input); - - if (current->match_options & PCRE2_PARTIAL_SOFT) - jit_compile_mode = PCRE2_JIT_PARTIAL_SOFT; - else if (current->match_options & PCRE2_PARTIAL_HARD) - jit_compile_mode = PCRE2_JIT_PARTIAL_HARD; - else - jit_compile_mode = PCRE2_JIT_COMPLETE; - error = 0; -#ifdef SUPPORT_PCRE2_8 - re8 = NULL; - ccontext8 = pcre2_compile_context_create_8(NULL); - if (ccontext8) { - if (GET_NEWLINE(current->newline)) - pcre2_set_newline_8(ccontext8, GET_NEWLINE(current->newline)); - if (GET_BSR(current->newline)) - pcre2_set_bsr_8(ccontext8, GET_BSR(current->newline)); - - if (!(current->start_offset & F_NO8)) { - re8 = pcre2_compile_8((PCRE2_SPTR8)current->pattern, PCRE2_ZERO_TERMINATED, - current->compile_options & ~disabled_options, - &error, &err_offs, ccontext8); - - if (!re8 && (utf || is_ascii)) - printf("\n8 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); - } - pcre2_compile_context_free_8(ccontext8); - } - else - printf("\n8 bit: Cannot allocate compile context\n"); -#endif -#ifdef SUPPORT_PCRE2_16 - if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) - convert_utf8_to_utf16((PCRE2_SPTR8)current->pattern, regtest_buf16, NULL, REGTEST_MAX_LENGTH16); - else - copy_char8_to_char16((PCRE2_SPTR8)current->pattern, regtest_buf16, REGTEST_MAX_LENGTH16); - - re16 = NULL; - ccontext16 = pcre2_compile_context_create_16(NULL); - if (ccontext16) { - if (GET_NEWLINE(current->newline)) - pcre2_set_newline_16(ccontext16, GET_NEWLINE(current->newline)); - if (GET_BSR(current->newline)) - pcre2_set_bsr_16(ccontext16, GET_BSR(current->newline)); - - if (!(current->start_offset & F_NO16)) { - re16 = pcre2_compile_16(regtest_buf16, PCRE2_ZERO_TERMINATED, - current->compile_options & ~disabled_options, - &error, &err_offs, ccontext16); - - if (!re16 && (utf || is_ascii)) - printf("\n16 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); - } - pcre2_compile_context_free_16(ccontext16); - } - else - printf("\n16 bit: Cannot allocate compile context\n"); -#endif -#ifdef SUPPORT_PCRE2_32 - if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) - convert_utf8_to_utf32((PCRE2_SPTR8)current->pattern, regtest_buf32, NULL, REGTEST_MAX_LENGTH32); - else - copy_char8_to_char32((PCRE2_SPTR8)current->pattern, regtest_buf32, REGTEST_MAX_LENGTH32); - - re32 = NULL; - ccontext32 = pcre2_compile_context_create_32(NULL); - if (ccontext32) { - if (GET_NEWLINE(current->newline)) - pcre2_set_newline_32(ccontext32, GET_NEWLINE(current->newline)); - if (GET_BSR(current->newline)) - pcre2_set_bsr_32(ccontext32, GET_BSR(current->newline)); - - if (!(current->start_offset & F_NO32)) { - re32 = pcre2_compile_32(regtest_buf32, PCRE2_ZERO_TERMINATED, - current->compile_options & ~disabled_options, - &error, &err_offs, ccontext32); - - if (!re32 && (utf || is_ascii)) - printf("\n32 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error); - } - pcre2_compile_context_free_32(ccontext32); - } - else - printf("\n32 bit: Cannot allocate compile context\n"); -#endif - - counter++; - if ((counter & 0x3) != 0) { -#ifdef SUPPORT_PCRE2_8 - setstack8(NULL); -#endif -#ifdef SUPPORT_PCRE2_16 - setstack16(NULL); -#endif -#ifdef SUPPORT_PCRE2_32 - setstack32(NULL); -#endif - } - -#ifdef SUPPORT_PCRE2_8 - return_value8[0] = -1000; - return_value8[1] = -1000; - mdata8_1 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL); - mdata8_2 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL); - mcontext8 = pcre2_match_context_create_8(NULL); - if (!mdata8_1 || !mdata8_2 || !mcontext8) { - printf("\n8 bit: Cannot allocate match data\n"); - pcre2_match_data_free_8(mdata8_1); - pcre2_match_data_free_8(mdata8_2); - pcre2_match_context_free_8(mcontext8); - pcre2_code_free_8(re8); - re8 = NULL; - } else { - ovector8_1 = pcre2_get_ovector_pointer_8(mdata8_1); - ovector8_2 = pcre2_get_ovector_pointer_8(mdata8_2); - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector8_1[i] = -2; - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector8_2[i] = -2; - } - if (re8) { - return_value8[1] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), - current->start_offset & OFFSET_MASK, current->match_options, mdata8_2, NULL); - - if (pcre2_jit_compile_8(re8, jit_compile_mode)) { - printf("\n8 bit: JIT compiler does not support \"%s\"\n", current->pattern); - } else if ((counter & 0x1) != 0) { - setstack8(mcontext8); - return_value8[0] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), - current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8); - } else { - pcre2_jit_stack_assign_8(mcontext8, NULL, getstack8()); - return_value8[0] = pcre2_jit_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input), - current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8); - } - } -#endif - -#ifdef SUPPORT_PCRE2_16 - return_value16[0] = -1000; - return_value16[1] = -1000; - mdata16_1 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL); - mdata16_2 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL); - mcontext16 = pcre2_match_context_create_16(NULL); - if (!mdata16_1 || !mdata16_2 || !mcontext16) { - printf("\n16 bit: Cannot allocate match data\n"); - pcre2_match_data_free_16(mdata16_1); - pcre2_match_data_free_16(mdata16_2); - pcre2_match_context_free_16(mcontext16); - pcre2_code_free_16(re16); - re16 = NULL; - } else { - ovector16_1 = pcre2_get_ovector_pointer_16(mdata16_1); - ovector16_2 = pcre2_get_ovector_pointer_16(mdata16_2); - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector16_1[i] = -2; - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector16_2[i] = -2; - } - if (re16) { - if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) - length16 = convert_utf8_to_utf16((PCRE2_SPTR8)current->input, regtest_buf16, regtest_offsetmap16, REGTEST_MAX_LENGTH16); - else - length16 = copy_char8_to_char16((PCRE2_SPTR8)current->input, regtest_buf16, REGTEST_MAX_LENGTH16); - - return_value16[1] = pcre2_match_16(re16, regtest_buf16, length16, - current->start_offset & OFFSET_MASK, current->match_options, mdata16_2, NULL); - - if (pcre2_jit_compile_16(re16, jit_compile_mode)) { - printf("\n16 bit: JIT compiler does not support \"%s\"\n", current->pattern); - } else if ((counter & 0x1) != 0) { - setstack16(mcontext16); - return_value16[0] = pcre2_match_16(re16, regtest_buf16, length16, - current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16); - } else { - pcre2_jit_stack_assign_16(mcontext16, NULL, getstack16()); - return_value16[0] = pcre2_jit_match_16(re16, regtest_buf16, length16, - current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16); - } - } -#endif - -#ifdef SUPPORT_PCRE2_32 - return_value32[0] = -1000; - return_value32[1] = -1000; - mdata32_1 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL); - mdata32_2 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL); - mcontext32 = pcre2_match_context_create_32(NULL); - if (!mdata32_1 || !mdata32_2 || !mcontext32) { - printf("\n32 bit: Cannot allocate match data\n"); - pcre2_match_data_free_32(mdata32_1); - pcre2_match_data_free_32(mdata32_2); - pcre2_match_context_free_32(mcontext32); - pcre2_code_free_32(re32); - re32 = NULL; - } else { - ovector32_1 = pcre2_get_ovector_pointer_32(mdata32_1); - ovector32_2 = pcre2_get_ovector_pointer_32(mdata32_2); - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector32_1[i] = -2; - for (i = 0; i < OVECTOR_SIZE * 3; ++i) - ovector32_2[i] = -2; - } - if (re32) { - if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV)) - length32 = convert_utf8_to_utf32((PCRE2_SPTR8)current->input, regtest_buf32, regtest_offsetmap32, REGTEST_MAX_LENGTH32); - else - length32 = copy_char8_to_char32((PCRE2_SPTR8)current->input, regtest_buf32, REGTEST_MAX_LENGTH32); - - return_value32[1] = pcre2_match_32(re32, regtest_buf32, length32, - current->start_offset & OFFSET_MASK, current->match_options, mdata32_2, NULL); - - if (pcre2_jit_compile_32(re32, jit_compile_mode)) { - printf("\n32 bit: JIT compiler does not support \"%s\"\n", current->pattern); - } else if ((counter & 0x1) != 0) { - setstack32(mcontext32); - return_value32[0] = pcre2_match_32(re32, regtest_buf32, length32, - current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32); - } else { - pcre2_jit_stack_assign_32(mcontext32, NULL, getstack32()); - return_value32[0] = pcre2_jit_match_32(re32, regtest_buf32, length32, - current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32); - } - } -#endif - - /* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s", - return_value8[0], return_value16[0], return_value32[0], - (int)ovector8_1[0], (int)ovector8_1[1], - (int)ovector16_1[0], (int)ovector16_1[1], - (int)ovector32_1[0], (int)ovector32_1[1], - (current->compile_options & PCRE2_CASELESS) ? "C" : ""); */ - - /* If F_DIFF is set, just run the test, but do not compare the results. - Segfaults can still be captured. */ - - is_successful = 1; - if (!(current->start_offset & F_DIFF)) { -#if defined SUPPORT_UTF && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2) - if (!(current->start_offset & F_FORCECONV)) { - - /* All results must be the same. */ -#ifdef SUPPORT_PCRE2_8 - if ((return_value = return_value8[0]) != return_value8[1]) { - printf("\n8 bit: Return value differs(J8:%d,I8:%d): [%d] '%s' @ '%s'\n", - return_value8[0], return_value8[1], total, current->pattern, current->input); - is_successful = 0; - } else -#endif -#ifdef SUPPORT_PCRE2_16 - if ((return_value = return_value16[0]) != return_value16[1]) { - printf("\n16 bit: Return value differs(J16:%d,I16:%d): [%d] '%s' @ '%s'\n", - return_value16[0], return_value16[1], total, current->pattern, current->input); - is_successful = 0; - } else -#endif -#ifdef SUPPORT_PCRE2_32 - if ((return_value = return_value32[0]) != return_value32[1]) { - printf("\n32 bit: Return value differs(J32:%d,I32:%d): [%d] '%s' @ '%s'\n", - return_value32[0], return_value32[1], total, current->pattern, current->input); - is_successful = 0; - } else -#endif -#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16 - if (return_value8[0] != return_value16[0]) { - printf("\n8 and 16 bit: Return value differs(J8:%d,J16:%d): [%d] '%s' @ '%s'\n", - return_value8[0], return_value16[0], - total, current->pattern, current->input); - is_successful = 0; - } else -#endif -#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32 - if (return_value8[0] != return_value32[0]) { - printf("\n8 and 32 bit: Return value differs(J8:%d,J32:%d): [%d] '%s' @ '%s'\n", - return_value8[0], return_value32[0], - total, current->pattern, current->input); - is_successful = 0; - } else -#endif -#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32 - if (return_value16[0] != return_value32[0]) { - printf("\n16 and 32 bit: Return value differs(J16:%d,J32:%d): [%d] '%s' @ '%s'\n", - return_value16[0], return_value32[0], - total, current->pattern, current->input); - is_successful = 0; - } else -#endif - if (return_value >= 0 || return_value == PCRE_ERROR_PARTIAL) { - if (return_value == PCRE_ERROR_PARTIAL) { - return_value = 2; - } else { - return_value *= 2; - } -#ifdef SUPPORT_PCRE2_8 - return_value8[0] = return_value; -#endif -#ifdef SUPPORT_PCRE2_16 - return_value16[0] = return_value; -#endif -#ifdef SUPPORT_PCRE2_32 - return_value32[0] = return_value; -#endif - /* Transform back the results. */ - if (current->flags & PCRE_UTF8) { -#ifdef SUPPORT_PCRE2_16 - for (i = 0; i < return_value; ++i) { - if (ovector16_1[i] >= 0) - ovector16_1[i] = regtest_offsetmap16[ovector16_1[i]]; - if (ovector16_2[i] >= 0) - ovector16_2[i] = regtest_offsetmap16[ovector16_2[i]]; - } -#endif -#ifdef SUPPORT_PCRE2_32 - for (i = 0; i < return_value; ++i) { - if (ovector32_1[i] >= 0) - ovector32_1[i] = regtest_offsetmap32[ovector32_1[i]]; - if (ovector32_2[i] >= 0) - ovector32_2[i] = regtest_offsetmap32[ovector32_2[i]]; - } -#endif - } - - for (i = 0; i < return_value; ++i) { -#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16 - if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) { - printf("\n8 and 16 bit: Ovector[%d] value differs(J8:%d,I8:%d,J16:%d,I16:%d): [%d] '%s' @ '%s' \n", - i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i], - total, current->pattern, current->input); - is_successful = 0; - } -#endif -#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32 - if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector32_1[i] || ovector8_1[i] != ovector32_2[i]) { - printf("\n8 and 32 bit: Ovector[%d] value differs(J8:%d,I8:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", - i, ovector8_1[i], ovector8_2[i], ovector32_1[i], ovector32_2[i], - total, current->pattern, current->input); - is_successful = 0; - } -#endif -#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_16 - if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector16_1[i] || ovector16_1[i] != ovector16_2[i]) { - printf("\n16 and 16 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", - i, ovector16_1[i], ovector16_2[i], ovector16_1[i], ovector16_2[i], - total, current->pattern, current->input); - is_successful = 0; - } -#endif - } - } - } else -#endif /* more than one of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16 and SUPPORT_PCRE2_32 */ - { -#ifdef SUPPORT_PCRE2_8 - if (return_value8[0] != return_value8[1]) { - printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", - return_value8[0], return_value8[1], total, current->pattern, current->input); - is_successful = 0; - } else if (return_value8[0] >= 0 || return_value8[0] == PCRE2_ERROR_PARTIAL) { - if (return_value8[0] == PCRE2_ERROR_PARTIAL) - return_value8[0] = 2; - else - return_value8[0] *= 2; - - for (i = 0; i < return_value8[0]; ++i) - if (ovector8_1[i] != ovector8_2[i]) { - printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", - i, (int)ovector8_1[i], (int)ovector8_2[i], total, current->pattern, current->input); - is_successful = 0; - } - } -#endif - -#ifdef SUPPORT_PCRE2_16 - if (return_value16[0] != return_value16[1]) { - printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", - return_value16[0], return_value16[1], total, current->pattern, current->input); - is_successful = 0; - } else if (return_value16[0] >= 0 || return_value16[0] == PCRE2_ERROR_PARTIAL) { - if (return_value16[0] == PCRE2_ERROR_PARTIAL) - return_value16[0] = 2; - else - return_value16[0] *= 2; - - for (i = 0; i < return_value16[0]; ++i) - if (ovector16_1[i] != ovector16_2[i]) { - printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", - i, (int)ovector16_1[i], (int)ovector16_2[i], total, current->pattern, current->input); - is_successful = 0; - } - } -#endif - -#ifdef SUPPORT_PCRE2_32 - if (return_value32[0] != return_value32[1]) { - printf("\n32 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", - return_value32[0], return_value32[1], total, current->pattern, current->input); - is_successful = 0; - } else if (return_value32[0] >= 0 || return_value32[0] == PCRE2_ERROR_PARTIAL) { - if (return_value32[0] == PCRE2_ERROR_PARTIAL) - return_value32[0] = 2; - else - return_value32[0] *= 2; - - for (i = 0; i < return_value32[0]; ++i) - if (ovector32_1[i] != ovector32_2[i]) { - printf("\n32 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", - i, (int)ovector32_1[i], (int)ovector32_2[i], total, current->pattern, current->input); - is_successful = 0; - } - } -#endif - } - } - - if (is_successful) { -#ifdef SUPPORT_PCRE2_8 - if (!(current->start_offset & F_NO8) && (utf || is_ascii)) { - if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) { - printf("8 bit: Test should match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - - if (return_value8[0] >= 0 && (current->start_offset & F_NOMATCH)) { - printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - } -#endif -#ifdef SUPPORT_PCRE2_16 - if (!(current->start_offset & F_NO16) && (utf || is_ascii)) { - if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) { - printf("16 bit: Test should match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - - if (return_value16[0] >= 0 && (current->start_offset & F_NOMATCH)) { - printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - } -#endif -#ifdef SUPPORT_PCRE2_32 - if (!(current->start_offset & F_NO32) && (utf || is_ascii)) { - if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) { - printf("32 bit: Test should match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - - if (return_value32[0] >= 0 && (current->start_offset & F_NOMATCH)) { - printf("32 bit: Test should not match: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } - } -#endif - } - - if (is_successful) { -#ifdef SUPPORT_PCRE2_8 - if (re8 && !(current->start_offset & F_NO8) && pcre2_get_mark_8(mdata8_1) != pcre2_get_mark_8(mdata8_2)) { - printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } -#endif -#ifdef SUPPORT_PCRE2_16 - if (re16 && !(current->start_offset & F_NO16) && pcre2_get_mark_16(mdata16_1) != pcre2_get_mark_16(mdata16_2)) { - printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } -#endif -#ifdef SUPPORT_PCRE2_32 - if (re32 && !(current->start_offset & F_NO32) && pcre2_get_mark_32(mdata32_1) != pcre2_get_mark_32(mdata32_2)) { - printf("32 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", - total, current->pattern, current->input); - is_successful = 0; - } -#endif - } - -#ifdef SUPPORT_PCRE2_8 - pcre2_code_free_8(re8); - pcre2_match_data_free_8(mdata8_1); - pcre2_match_data_free_8(mdata8_2); - pcre2_match_context_free_8(mcontext8); -#endif -#ifdef SUPPORT_PCRE2_16 - pcre2_code_free_16(re16); - pcre2_match_data_free_16(mdata16_1); - pcre2_match_data_free_16(mdata16_2); - pcre2_match_context_free_16(mcontext16); -#endif -#ifdef SUPPORT_PCRE2_32 - pcre2_code_free_32(re32); - pcre2_match_data_free_32(mdata32_1); - pcre2_match_data_free_32(mdata32_2); - pcre2_match_context_free_32(mcontext32); -#endif - - if (is_successful) { - successful++; - successful_row++; - printf("."); - if (successful_row >= 60) { - successful_row = 0; - printf("\n"); - } - } else - successful_row = 0; - - fflush(stdout); - current++; - } -#ifdef SUPPORT_PCRE2_8 - setstack8(NULL); -#endif -#ifdef SUPPORT_PCRE2_16 - setstack16(NULL); -#endif -#ifdef SUPPORT_PCRE2_32 - setstack32(NULL); -#endif - - if (total == successful) { - printf("\nAll JIT regression tests are successfully passed.\n"); - return 0; - } else { - printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful); - return 1; - } -} - -/* End of pcre2_jit_test.c */ diff --git a/pcre2/src/pcre2_maketables.c b/pcre2/src/pcre2_maketables.c deleted file mode 100644 index 2c7ae84d8..000000000 --- a/pcre2/src/pcre2_maketables.c +++ /dev/null @@ -1,157 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains the external function pcre2_maketables(), which builds -character tables for PCRE2 in the current locale. The file is compiled on its -own as part of the PCRE2 library. However, it is also included in the -compilation of dftables.c, in which case the macro DFTABLES is defined. */ - -#ifndef DFTABLES -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif -# include "pcre2_internal.h" -#endif - - - -/************************************************* -* Create PCRE2 character tables * -*************************************************/ - -/* This function builds a set of character tables for use by PCRE2 and returns -a pointer to them. They are build using the ctype functions, and consequently -their contents will depend upon the current locale setting. When compiled as -part of the library, the store is obtained via a general context malloc, if -supplied, but when DFTABLES is defined (when compiling the dftables auxiliary -program) malloc() is used, and the function has a different name so as not to -clash with the prototype in pcre2.h. - -Arguments: none when DFTABLES is defined - else a PCRE2 general context or NULL -Returns: pointer to the contiguous block of data -*/ - -#ifdef DFTABLES /* Included in freestanding dftables.c program */ -static const uint8_t *maketables(void) -{ -uint8_t *yield = (uint8_t *)malloc(tables_length); - -#else /* Not DFTABLES, compiling the library */ -PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION -pcre2_maketables(pcre2_general_context *gcontext) -{ -uint8_t *yield = (uint8_t *)((gcontext != NULL)? - gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) : - malloc(tables_length)); -#endif /* DFTABLES */ - -int i; -uint8_t *p; - -if (yield == NULL) return NULL; -p = yield; - -/* First comes the lower casing table */ - -for (i = 0; i < 256; i++) *p++ = tolower(i); - -/* Next the case-flipping table */ - -for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); - -/* Then the character class tables. Don't try to be clever and save effort on -exclusive ones - in some locales things may be different. - -Note that the table for "space" includes everything "isspace" gives, including -VT in the default locale. This makes it work for the POSIX class [:space:]. -From release 8.34 is is also correct for Perl space, because Perl added VT at -release 5.18. - -Note also that it is possible for a character to be alnum or alpha without -being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the -fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must -test for alnum specially. */ - -memset(p, 0, cbit_length); -for (i = 0; i < 256; i++) - { - if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); - if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); - if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); - if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); - if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); - if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); - if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); - if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); - if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); - if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); - if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); - } -p += cbit_length; - -/* Finally, the character type table. In this, we used to exclude VT from the -white space chars, because Perl didn't recognize it as such for \s and for -comments within regexes. However, Perl changed at release 5.18, so PCRE changed -at release 8.34. */ - -for (i = 0; i < 256; i++) - { - int x = 0; - if (isspace(i)) x += ctype_space; - if (isalpha(i)) x += ctype_letter; - if (isdigit(i)) x += ctype_digit; - if (isxdigit(i)) x += ctype_xdigit; - if (isalnum(i) || i == '_') x += ctype_word; - - /* Note: strchr includes the terminating zero in the characters it considers. - In this instance, that is ok because we want binary zero to be flagged as a - meta-character, which in this sense is any character that terminates a run - of data characters. */ - - if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta; - *p++ = x; - } - -return yield; -} - -/* End of pcre2_maketables.c */ diff --git a/pcre2/src/pcre2_match.c b/pcre2/src/pcre2_match.c deleted file mode 100644 index f5275c7c4..000000000 --- a/pcre2/src/pcre2_match.c +++ /dev/null @@ -1,7243 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define NLBLOCK mb /* Block containing newline information */ -#define PSSTART start_subject /* Field containing processed string start */ -#define PSEND end_subject /* Field containing processed string end */ - -#include "pcre2_internal.h" - -/* Masks for identifying the public options that are permitted at match time. -*/ - -#define PUBLIC_MATCH_OPTIONS \ - (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ - PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT) - -#define PUBLIC_JIT_MATCH_OPTIONS \ - (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ - PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD) - -/* The mb->capture_last field uses the lower 16 bits for the last captured -substring (which can never be greater than 65535) and a bit in the top half -to mean "capture vector overflowed". This odd way of doing things was -implemented when it was realized that preserving and restoring the overflow bit -whenever the last capture number was saved/restored made for a neater -interface, and doing it this way saved on (a) another variable, which would -have increased the stack frame size (a big NO-NO in PCRE) and (b) another -separate set of save/restore instructions. The following defines are used in -implementing this. */ - -#define CAPLMASK 0x0000ffff /* The bits used for last_capture */ -#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */ -#define OVFLBIT 0x00010000 /* The bit that is set for overflow */ - -/* Bits for setting in mb->match_function_type to indicate two special types -of call to match(). We do it this way to save on using another stack variable, -as stack usage is to be discouraged. */ - -#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */ -#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */ - -/* Non-error returns from the match() function. Error returns are externally -defined PCRE2_ERROR_xxx codes, which are all negative. */ - -#define MATCH_MATCH 1 -#define MATCH_NOMATCH 0 - -/* Special internal returns from the match() function. Make them sufficiently -negative to avoid the external error codes. */ - -#define MATCH_ACCEPT (-999) -#define MATCH_KETRPOS (-998) -#define MATCH_ONCE (-997) -/* The next 5 must be kept together and in sequence so that a test that checks -for any one of them can use a range. */ -#define MATCH_COMMIT (-996) -#define MATCH_PRUNE (-995) -#define MATCH_SKIP (-994) -#define MATCH_SKIP_ARG (-993) -#define MATCH_THEN (-992) -#define MATCH_BACKTRACK_MAX MATCH_THEN -#define MATCH_BACKTRACK_MIN MATCH_COMMIT - -/* Min and max values for the common repeats; for the maxima, 0 => infinity */ - -static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, }; -static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, }; - -/* Maximum number of ovector elements that can be saved on the system stack -when processing OP_RECURSE in non-HEAP_MATCH_RECURSE mode. If the ovector is -bigger, malloc() is used. This value should be a multiple of 3, because the -ovector length is always a multiple of 3. */ - -#define OP_RECURSE_STACK_SAVE_MAX 45 - - - -/************************************************* -* Match a back-reference * -*************************************************/ - -/* This function is called only when it is known that the offset lies within -the offsets that have so far been used in the match. Note that in caseless -UTF-8 mode, the number of subject bytes matched may be different to the number -of reference bytes. (In theory this could also happen in UTF-16 mode, but it -seems unlikely.) - -Arguments: - offset index into the offset vector - offset_top top of the used offset vector - eptr pointer into the subject - mb points to match block - caseless TRUE if caseless - lengthptr pointer for returning the length matched - -Returns: = 0 sucessful match; number of code units matched is set - < 0 no match - > 0 partial match -*/ - -static int -match_ref(PCRE2_SIZE offset, PCRE2_SIZE offset_top, register PCRE2_SPTR eptr, - match_block *mb, BOOL caseless, PCRE2_SIZE *lengthptr) -{ -#if defined SUPPORT_UNICODE -BOOL utf = (mb->poptions & PCRE2_UTF) != 0; -#endif - -register PCRE2_SPTR p; -PCRE2_SIZE length; -PCRE2_SPTR eptr_start = eptr; - -/* Deal with an unset group. The default is no match, but there is an option to -match an empty string. */ - -if (offset >= offset_top || mb->ovector[offset] == PCRE2_UNSET) - { - if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0) - { - *lengthptr = 0; - return 0; /* Match */ - } - else return -1; /* No match */ - } - -/* Separate the caseless and UTF cases for speed. */ - -p = mb->start_subject + mb->ovector[offset]; -length = mb->ovector[offset+1] - mb->ovector[offset]; - -if (caseless) - { -#if defined SUPPORT_UNICODE - if (utf) - { - /* Match characters up to the end of the reference. NOTE: the number of - code units matched may differ, because in UTF-8 there are some characters - whose upper and lower case versions code have different numbers of bytes. - For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 - (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a - sequence of two of the latter. It is important, therefore, to check the - length along the reference, not along the subject (earlier code did this - wrong). */ - - PCRE2_SPTR endptr = p + length; - while (p < endptr) - { - uint32_t c, d; - const ucd_record *ur; - if (eptr >= mb->end_subject) return 1; /* Partial match */ - GETCHARINC(c, eptr); - GETCHARINC(d, p); - ur = GET_UCD(d); - if (c != d && c != (uint32_t)((int)d + ur->other_case)) - { - const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset; - for (;;) - { - if (c < *pp) return -1; /* No match */ - if (c == *pp++) break; - } - } - } - } - else -#endif - - /* Not in UTF mode */ - - { - for (; length > 0; length--) - { - uint32_t cc, cp; - if (eptr >= mb->end_subject) return 1; /* Partial match */ - cc = UCHAR21TEST(eptr); - cp = UCHAR21TEST(p); - if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc)) - return -1; /* No match */ - p++; - eptr++; - } - } - } - -/* In the caseful case, we can just compare the code units, whether or not we -are in UTF mode. */ - -else - { - for (; length > 0; length--) - { - if (eptr >= mb->end_subject) return 1; /* Partial match */ - if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; /*No match */ - } - } - -*lengthptr = eptr - eptr_start; -return 0; /* Match */ -} - - - -/*************************************************************************** -**************************************************************************** - RECURSION IN THE match() FUNCTION - -The match() function is highly recursive, though not every recursive call -increases the recursion depth. Nevertheless, some regular expressions can cause -it to recurse to a great depth. I was writing for Unix, so I just let it call -itself recursively. This uses the stack for saving everything that has to be -saved for a recursive call. On Unix, the stack can be large, and this works -fine. - -It turns out that on some non-Unix-like systems there are problems with -programs that use a lot of stack. (This despite the fact that every last chip -has oodles of memory these days, and techniques for extending the stack have -been known for decades.) So.... - -There is a fudge, triggered by defining HEAP_MATCH_RECURSE, which avoids -recursive calls by keeping local variables that need to be preserved in blocks -of memory on the heap instead instead of on the stack. Macros are used to -achieve this so that the actual code doesn't look very different to what it -always used to. - -The original heap-recursive code used longjmp(). However, it seems that this -can be very slow on some operating systems. Following a suggestion from Stan -Switzer, the use of longjmp() has been abolished, at the cost of having to -provide a unique number for each call to RMATCH. There is no way of generating -a sequence of numbers at compile time in C. I have given them names, to make -them stand out more clearly. - -Crude tests on x86 Linux show a small speedup of around 5-8%. However, on -FreeBSD, avoiding longjmp() more than halves the time taken to run the standard -tests. Furthermore, not using longjmp() means that local dynamic variables -don't have indeterminate values; this has meant that the frame size can be -reduced because the result can be "passed back" by straight setting of the -variable instead of being passed in the frame. -**************************************************************************** -***************************************************************************/ - -/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN -below must be updated in sync. */ - -enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, - RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, - RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, - RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, - RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, - RM61, RM62, RM63, RM64, RM65, RM66, RM67, RM68 }; - -/* These versions of the macros use the stack, as normal. Note that the "rw" -argument of RMATCH isn't actually used in this definition. */ - -#ifndef HEAP_MATCH_RECURSE -#define REGISTER register -#define RMATCH(ra,rb,rc,rd,re,rw) \ - rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) -#define RRETURN(ra) return ra -#else - -/* These versions of the macros manage a private stack on the heap. Note that -the "rd" argument of RMATCH isn't actually used in this definition. It's the mb -argument of match(), which never changes. */ - -#define REGISTER - -#define RMATCH(ra,rb,rc,rd,re,rw)\ - {\ - heapframe *newframe = frame->Xnextframe;\ - if (newframe == NULL)\ - {\ - newframe = (heapframe *)(mb->stack_memctl.malloc)\ - (sizeof(heapframe), mb->stack_memctl.memory_data);\ - if (newframe == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);\ - newframe->Xnextframe = NULL;\ - frame->Xnextframe = newframe;\ - }\ - frame->Xwhere = rw;\ - newframe->Xeptr = ra;\ - newframe->Xecode = rb;\ - newframe->Xmstart = mstart;\ - newframe->Xoffset_top = rc;\ - newframe->Xeptrb = re;\ - newframe->Xrdepth = frame->Xrdepth + 1;\ - newframe->Xprevframe = frame;\ - frame = newframe;\ - goto HEAP_RECURSE;\ - L_##rw:;\ - } - -#define RRETURN(ra)\ - {\ - heapframe *oldframe = frame;\ - frame = oldframe->Xprevframe;\ - if (frame != NULL)\ - {\ - rrc = ra;\ - goto HEAP_RETURN;\ - }\ - return ra;\ - } - - -/* Structure for remembering the local variables in a private frame. Arrange it -so as to minimize the number of holes. */ - -typedef struct heapframe { - struct heapframe *Xprevframe; - struct heapframe *Xnextframe; - -#ifdef SUPPORT_UNICODE - PCRE2_SPTR Xcharptr; -#endif - PCRE2_SPTR Xeptr; - PCRE2_SPTR Xecode; - PCRE2_SPTR Xmstart; - PCRE2_SPTR Xcallpat; - PCRE2_SPTR Xdata; - PCRE2_SPTR Xnext_ecode; - PCRE2_SPTR Xpp; - PCRE2_SPTR Xprev; - PCRE2_SPTR Xsaved_eptr; - - eptrblock *Xeptrb; - - PCRE2_SIZE Xlength; - PCRE2_SIZE Xoffset; - PCRE2_SIZE Xoffset_top; - PCRE2_SIZE Xsave_offset1, Xsave_offset2, Xsave_offset3; - - uint32_t Xfc; - uint32_t Xnumber; - uint32_t Xrdepth; - uint32_t Xop; - uint32_t Xsave_capture_last; - -#ifdef SUPPORT_UNICODE - uint32_t Xprop_value; - int Xprop_type; - int Xprop_fail_result; - int Xoclength; -#endif - - int Xcodelink; - int Xctype; - int Xfi; - int Xmax; - int Xmin; - int Xwhere; /* Where to jump back to */ - - BOOL Xcondition; - BOOL Xcur_is_word; - BOOL Xprev_is_word; - - eptrblock Xnewptrb; - recursion_info Xnew_recursive; - -#ifdef SUPPORT_UNICODE - PCRE2_UCHAR Xocchars[6]; -#endif -} heapframe; - -#endif - - -/*************************************************************************** -***************************************************************************/ - - -/* When HEAP_MATCH_RECURSE is not defined, the match() function implements -backtrack points by calling itself recursively in all but one case. The one -special case is when processing OP_RECURSE, which specifies recursion in the -pattern. The entire ovector must be saved and restored while processing -OP_RECURSE. If the ovector is small enough, instead of calling match() -directly, op_recurse_ovecsave() is called. This function uses the system stack -to save the ovector while calling match() to process the pattern recursion. */ - -#ifndef HEAP_MATCH_RECURSE - -/* We need a prototype for match() because it is mutually recursive with -op_recurse_ovecsave(). */ - -static int -match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart, - PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth); - - -/************************************************* -* Process OP_RECURSE, stacking ovector * -*************************************************/ - -/* When this function is called, mb->recursive has already been updated to -point to a new recursion data block, and all its fields other than ovec_save -have been set. - -This function exists so that the local vector variable ovecsave is no longer -defined in the match() function, as it was in PCRE1. It is used only when there -is recursion in the pattern, so it wastes a lot of stack to have it defined for -every call of match(). We now use this function as an indirect way of calling -match() only in the case when ovecsave is needed. (David Wheeler used to say -"All problems in computer science can be solved by another level of -indirection.") - -HOWEVER: when this file is compiled by gcc in an optimizing mode, because this -function is called only once, and only from within match(), gcc will "inline" -it - that is, move it inside match() - and this completely negates its reason -for existence. Therefore, we mark it as non-inline when gcc is in use. - -Arguments: - eptr pointer to current character in subject - callpat the recursion point in the pattern - mstart pointer to the current match start position (can be modified - by encountering \K) - offset_top current top pointer (highest ovector offset used + 1) - mb pointer to "static" info block for the match - eptrb pointer to chain of blocks containing eptr at start of - brackets - for testing for empty matches - rdepth the recursion depth - -Returns: a match() return code -*/ - -static int -#ifdef __GNUC__ -__attribute__ ((noinline)) -#endif -op_recurse_ovecsave(REGISTER PCRE2_SPTR eptr, PCRE2_SPTR callpat, - PCRE2_SPTR mstart, PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, - uint32_t rdepth) -{ -register int rrc; -BOOL cbegroup = *callpat >= OP_SBRA; -recursion_info *new_recursive = mb->recursive; -PCRE2_SIZE ovecsave[OP_RECURSE_STACK_SAVE_MAX]; - -/* Save the ovector */ - -new_recursive->ovec_save = ovecsave; -memcpy(ovecsave, mb->ovector, mb->offset_end * sizeof(PCRE2_SIZE)); - -/* Do the recursion. After processing each alternative, restore the ovector -data and the last captured value. */ - -do - { - if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP; - rrc = match(eptr, callpat + PRIV(OP_lengths)[*callpat], mstart, offset_top, - mb, eptrb, rdepth + 1); - memcpy(mb->ovector, new_recursive->ovec_save, - mb->offset_end * sizeof(PCRE2_SIZE)); - mb->capture_last = new_recursive->saved_capture_last; - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) return rrc; - - /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a - recursion; they cause a NOMATCH for the entire recursion. These codes - are defined in a range that can be tested for. */ - - if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX) - return MATCH_NOMATCH; - - /* Any return code other than NOMATCH is an error. Otherwise, advance to the - next alternative or to the end of the recursing subpattern. If there were - nested recursions, mb->recursive might be changed, so reset it before - looping. */ - - if (rrc != MATCH_NOMATCH) return rrc; - mb->recursive = new_recursive; - callpat += GET(callpat, 1); - } -while (*callpat == OP_ALT); /* Loop for the alternatives */ - -/* None of the alternatives matched. */ - -return MATCH_NOMATCH; -} -#endif /* HEAP_MATCH_RECURSE */ - - - -/************************************************* -* Match from current position * -*************************************************/ - -/* This function is called recursively in many circumstances. Whenever it -returns a negative (error) response, the outer incarnation must also return the -same response. */ - -/* These macros pack up tests that are used for partial matching, and which -appear several times in the code. We set the "hit end" flag if the pointer is -at the end of the subject and also past the earliest inspected character (i.e. -something has been matched, even if not part of the actual matched string). For -hard partial matching, we then return immediately. The second one is used when -we already know we are past the end of the subject. */ - -#define CHECK_PARTIAL()\ - if (mb->partial != 0 && eptr >= mb->end_subject && \ - eptr > mb->start_used_ptr) \ - { \ - mb->hitend = TRUE; \ - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \ - } - -#define SCHECK_PARTIAL()\ - if (mb->partial != 0 && eptr > mb->start_used_ptr) \ - { \ - mb->hitend = TRUE; \ - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \ - } - - -/* Performance note: It might be tempting to extract commonly used fields from -the mb structure (e.g. utf, end_subject) into individual variables to improve -performance. Tests using gcc on a SPARC disproved this; in the first case, it -made performance worse. - -Arguments: - eptr pointer to current character in subject - ecode pointer to current position in compiled code - mstart pointer to the current match start position (can be modified - by encountering \K) - offset_top current top pointer (highest ovector offset used + 1) - mb pointer to "static" info block for the match - eptrb pointer to chain of blocks containing eptr at start of - brackets - for testing for empty matches - rdepth the recursion depth - -Returns: MATCH_MATCH if matched ) these values are >= 0 - MATCH_NOMATCH if failed to match ) - a negative MATCH_xxx value for PRUNE, SKIP, etc - a negative PCRE2_ERROR_xxx value if aborted by an error condition - (e.g. stopped by repeated call or recursion limit) -*/ - -static int -match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart, - PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth) -{ -/* These variables do not need to be preserved over recursion in this function, -so they can be ordinary variables in all cases. Mark some of them with -"register" because they are used a lot in loops. */ - -register int rrc; /* Returns from recursive calls */ -register int i; /* Used for loops not involving calls to RMATCH() */ -register uint32_t c; /* Character values not kept over RMATCH() calls */ -register BOOL utf; /* Local copy of UTF flag for speed */ - -BOOL minimize, possessive; /* Quantifier options */ -BOOL caseless; -int condcode; - -/* When recursion is not being used, all "local" variables that have to be -preserved over calls to RMATCH() are part of a "frame". We set up the top-level -frame on the stack here; subsequent instantiations are obtained from the heap -whenever RMATCH() does a "recursion". See the macro definitions above. Putting -the top-level on the stack rather than malloc-ing them all gives a performance -boost in many cases where there is not much "recursion". */ - -#ifdef HEAP_MATCH_RECURSE -heapframe *frame = (heapframe *)mb->match_frames_base; - -/* Copy in the original argument variables */ - -frame->Xeptr = eptr; -frame->Xecode = ecode; -frame->Xmstart = mstart; -frame->Xoffset_top = offset_top; -frame->Xeptrb = eptrb; -frame->Xrdepth = rdepth; - -/* This is where control jumps back to to effect "recursion" */ - -HEAP_RECURSE: - -/* Macros make the argument variables come from the current frame */ - -#define eptr frame->Xeptr -#define ecode frame->Xecode -#define mstart frame->Xmstart -#define offset_top frame->Xoffset_top -#define eptrb frame->Xeptrb -#define rdepth frame->Xrdepth - -/* Ditto for the local variables */ - -#ifdef SUPPORT_UNICODE -#define charptr frame->Xcharptr -#define prop_value frame->Xprop_value -#define prop_type frame->Xprop_type -#define prop_fail_result frame->Xprop_fail_result -#define oclength frame->Xoclength -#define occhars frame->Xocchars -#endif - - -#define callpat frame->Xcallpat -#define codelink frame->Xcodelink -#define data frame->Xdata -#define next_ecode frame->Xnext_ecode -#define pp frame->Xpp -#define prev frame->Xprev -#define saved_eptr frame->Xsaved_eptr - -#define new_recursive frame->Xnew_recursive - -#define ctype frame->Xctype -#define fc frame->Xfc -#define fi frame->Xfi -#define length frame->Xlength -#define max frame->Xmax -#define min frame->Xmin -#define number frame->Xnumber -#define offset frame->Xoffset -#define op frame->Xop -#define save_capture_last frame->Xsave_capture_last -#define save_offset1 frame->Xsave_offset1 -#define save_offset2 frame->Xsave_offset2 -#define save_offset3 frame->Xsave_offset3 - -#define condition frame->Xcondition -#define cur_is_word frame->Xcur_is_word -#define prev_is_word frame->Xprev_is_word - -#define newptrb frame->Xnewptrb - -/* When normal stack-based recursion is being used for match(), local variables -are allocated on the stack and get preserved during recursion in the usual way. -In this environment, fi and i, and fc and c, can be the same variables. */ - -#else /* HEAP_MATCH_RECURSE not defined */ -#define fi i -#define fc c - -/* Many of the following variables are used only in small blocks of the code. -My normal style of coding would have declared them within each of those blocks. -However, in order to accommodate the version of this code that uses an external -"stack" implemented on the heap, it is easier to declare them all here, so the -declarations can be cut out in a block. The only declarations within blocks -below are for variables that do not have to be preserved over a recursive call -to RMATCH(). */ - -#ifdef SUPPORT_UNICODE -PCRE2_SPTR charptr; -#endif -PCRE2_SPTR callpat; -PCRE2_SPTR data; -PCRE2_SPTR next_ecode; -PCRE2_SPTR pp; -PCRE2_SPTR prev; -PCRE2_SPTR saved_eptr; - -PCRE2_SIZE length; -PCRE2_SIZE offset; -PCRE2_SIZE save_offset1, save_offset2, save_offset3; - -uint32_t number; -uint32_t op; -uint32_t save_capture_last; - -#ifdef SUPPORT_UNICODE -uint32_t prop_value; -int prop_type; -int prop_fail_result; -int oclength; -PCRE2_UCHAR occhars[6]; -#endif - -int codelink; -int ctype; -int max; -int min; - -BOOL condition; -BOOL cur_is_word; -BOOL prev_is_word; - -eptrblock newptrb; -recursion_info new_recursive; -#endif /* HEAP_MATCH_RECURSE not defined */ - -/* To save space on the stack and in the heap frame, I have doubled up on some -of the local variables that are used only in localised parts of the code, but -still need to be preserved over recursive calls of match(). These macros define -the alternative names that are used. */ - -#define allow_zero cur_is_word -#define cbegroup condition -#define code_offset codelink -#define condassert condition -#define foc number -#define matched_once prev_is_word -#define save_mark data - -/* These statements are here to stop the compiler complaining about unitialized -variables. */ - -#ifdef SUPPORT_UNICODE -prop_value = 0; -prop_fail_result = 0; -#endif - - -/* This label is used for tail recursion, which is used in a few cases even -when HEAP_MATCH_RECURSE is not defined, in order to reduce the amount of stack -that is used. Thanks to Ian Taylor for noticing this possibility and sending -the original patch. */ - -TAIL_RECURSE: - -/* OK, now we can get on with the real code of the function. Recursive calls -are specified by the macro RMATCH and RRETURN is used to return. When -HEAP_MATCH_RECURSE is *not* defined, these just turn into a recursive call to -match() and a "return", respectively. However, RMATCH isn't like a function -call because it's quite a complicated macro. It has to be used in one -particular way. This shouldn't, however, impact performance when true recursion -is being used. */ - -#ifdef SUPPORT_UNICODE -utf = (mb->poptions & PCRE2_UTF) != 0; -#else -utf = FALSE; -#endif - -/* First check that we haven't called match() too many times, or that we -haven't exceeded the recursive call limit. */ - -if (mb->match_call_count++ >= mb->match_limit) RRETURN(PCRE2_ERROR_MATCHLIMIT); -if (rdepth >= mb->match_limit_recursion) RRETURN(PCRE2_ERROR_RECURSIONLIMIT); - -/* At the start of a group with an unlimited repeat that may match an empty -string, the variable mb->match_function_type contains the MATCH_CBEGROUP bit. -It is done this way to save having to use another function argument, which -would take up space on the stack. See also MATCH_CONDASSERT below. - -When MATCH_CBEGROUP is set, add the current subject pointer to the chain of -such remembered pointers, to be checked when we hit the closing ket, in order -to break infinite loops that match no characters. When match() is called in -other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must -NOT be used with tail recursion, because the memory block that is used is on -the stack, so a new one may be required for each match(). */ - -if ((mb->match_function_type & MATCH_CBEGROUP) != 0) - { - newptrb.epb_saved_eptr = eptr; - newptrb.epb_prev = eptrb; - eptrb = &newptrb; - mb->match_function_type &= ~MATCH_CBEGROUP; - } - -/* Now, at last, we can start processing the opcodes. */ - -for (;;) - { - minimize = possessive = FALSE; - op = *ecode; - - switch(op) - { - case OP_MARK: - mb->nomatch_mark = ecode + 2; - mb->mark = NULL; /* In case previously set by assertion */ - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, - eptrb, RM55); - if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && - mb->mark == NULL) mb->mark = ecode + 2; - - /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an - argument, and we must check whether that argument matches this MARK's - argument. It is passed back in mb->start_match_ptr (an overloading of that - variable). If it does match, we reset that variable to the current subject - position and return MATCH_SKIP. Otherwise, pass back the return code - unaltered. */ - - else if (rrc == MATCH_SKIP_ARG && - PRIV(strcmp)(ecode + 2, mb->start_match_ptr) == 0) - { - mb->start_match_ptr = eptr; - RRETURN(MATCH_SKIP); - } - RRETURN(rrc); - - case OP_FAIL: - RRETURN(MATCH_NOMATCH); - - case OP_COMMIT: - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM52); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - RRETURN(MATCH_COMMIT); - - case OP_PRUNE: - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM51); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - RRETURN(MATCH_PRUNE); - - case OP_PRUNE_ARG: - mb->nomatch_mark = ecode + 2; - mb->mark = NULL; /* In case previously set by assertion */ - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, - eptrb, RM56); - if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && - mb->mark == NULL) mb->mark = ecode + 2; - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - RRETURN(MATCH_PRUNE); - - case OP_SKIP: - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM53); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->start_match_ptr = eptr; /* Pass back current position */ - RRETURN(MATCH_SKIP); - - /* Note that, for Perl compatibility, SKIP with an argument does NOT set - nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was - not a matching mark, we have to re-run the match, ignoring the SKIP_ARG - that failed and any that precede it (either they also failed, or were not - triggered). To do this, we maintain a count of executed SKIP_ARGs. If a - SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg - set to the count of the one that failed. */ - - case OP_SKIP_ARG: - mb->skip_arg_count++; - if (mb->skip_arg_count <= mb->ignore_skip_arg) - { - ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; - break; - } - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb, - eptrb, RM57); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - - /* Pass back the current skip name by overloading mb->start_match_ptr and - returning the special MATCH_SKIP_ARG return code. This will either be - caught by a matching MARK, or get to the top, where it causes a rematch - with mb->ignore_skip_arg set to the value of mb->skip_arg_count. */ - - mb->start_match_ptr = ecode + 2; - RRETURN(MATCH_SKIP_ARG); - - /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that - the branch in which it occurs can be determined. Overload the start of - match pointer to do this. */ - - case OP_THEN: - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM54); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->start_match_ptr = ecode; - RRETURN(MATCH_THEN); - - case OP_THEN_ARG: - mb->nomatch_mark = ecode + 2; - mb->mark = NULL; /* In case previously set by assertion */ - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, - mb, eptrb, RM58); - if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && - mb->mark == NULL) mb->mark = ecode + 2; - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->start_match_ptr = ecode; - RRETURN(MATCH_THEN); - - /* Handle an atomic group that does not contain any capturing parentheses. - This can be handled like an assertion. Prior to 8.13, all atomic groups - were handled this way. In 8.13, the code was changed as below for ONCE, so - that backups pass through the group and thereby reset captured values. - However, this uses a lot more stack, so in 8.20, atomic groups that do not - contain any captures generate OP_ONCE_NC, which can be handled in the old, - less stack intensive way. - - Check the alternative branches in turn - the matching won't pass the KET - for this kind of subpattern. If any one branch matches, we carry on as at - the end of a normal bracket, leaving the subject pointer, but resetting - the start-of-match value in case it was changed by \K. */ - - case OP_ONCE_NC: - prev = ecode; - saved_eptr = eptr; - save_mark = mb->mark; - do - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM64); - if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ - { - mstart = mb->start_match_ptr; - break; - } - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += GET(ecode,1); - mb->mark = save_mark; - } - while (*ecode == OP_ALT); - - /* If hit the end of the group (which could be repeated), fail */ - - if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); - - /* Continue as from after the group, updating the offsets high water - mark, since extracts may have been taken. */ - - do ecode += GET(ecode, 1); while (*ecode == OP_ALT); - - offset_top = mb->end_offset_top; - eptr = mb->end_match_ptr; - - /* For a non-repeating ket, just continue at this level. This also - happens for a repeating ket if no characters were matched in the group. - This is the forcible breaking of infinite loops as implemented in Perl - 5.005. */ - - if (*ecode == OP_KET || eptr == saved_eptr) - { - ecode += 1+LINK_SIZE; - break; - } - - /* The repeating kets try the rest of the pattern or restart from the - preceding bracket, in the appropriate order. The second "call" of match() - uses tail recursion, to avoid using another stack frame. */ - - if (*ecode == OP_KETRMIN) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM65); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode = prev; - goto TAIL_RECURSE; - } - else /* OP_KETRMAX */ - { - RMATCH(eptr, prev, offset_top, mb, eptrb, RM66); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += 1 + LINK_SIZE; - goto TAIL_RECURSE; - } - /* Control never gets here */ - - /* Handle a capturing bracket, other than those that are possessive with an - unlimited repeat. If there is space in the offset vector, save the current - subject position in the working slot at the top of the vector. We mustn't - change the current values of the data slot, because they may be set from a - previous iteration of this group, and be referred to by a reference inside - the group. A failure to match might occur after the group has succeeded, - if something later on doesn't match. For this reason, we need to restore - the working value and also the values of the final offsets, in case they - were set by a previous iteration of the same bracket. - - If there isn't enough space in the offset vector, treat this as if it were - a non-capturing bracket. Don't worry about setting the flag for the error - case here; that is handled in the code for KET. */ - - case OP_CBRA: - case OP_SCBRA: - number = GET2(ecode, 1+LINK_SIZE); - offset = number << 1; - - if (offset < mb->offset_max) - { - save_offset1 = mb->ovector[offset]; - save_offset2 = mb->ovector[offset+1]; - save_offset3 = mb->ovector[mb->offset_end - number]; - save_capture_last = mb->capture_last; - save_mark = mb->mark; - - mb->ovector[mb->offset_end - number] = eptr - mb->start_subject; - - for (;;) - { - if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM1); - if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ - - /* If we backed up to a THEN, check whether it is within the current - branch by comparing the address of the THEN that is passed back with - the end of the branch. If it is within the current branch, and the - branch is one of two or more alternatives (it either starts or ends - with OP_ALT), we have reached the limit of THEN's action, so convert - the return code to NOMATCH, which will cause normal backtracking to - happen from now on. Otherwise, THEN is passed back to an outer - alternative. This implements Perl's treatment of parenthesized groups, - where a group not containing | does not affect the current alternative, - that is, (X) is NOT the same as (X|(*F)). */ - - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - /* Anything other than NOMATCH is passed back. */ - - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->capture_last = save_capture_last; - ecode += GET(ecode, 1); - mb->mark = save_mark; - if (*ecode != OP_ALT) break; - } - - mb->ovector[offset] = save_offset1; - mb->ovector[offset+1] = save_offset2; - mb->ovector[mb->offset_end - number] = save_offset3; - - /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ - - RRETURN(rrc); - } - - /* FALL THROUGH ... Insufficient room for saving captured contents. Treat - as a non-capturing bracket. */ - - /* VVVVVVVVVVVVVVVVVVVVVVVVV */ - /* VVVVVVVVVVVVVVVVVVVVVVVVV */ - - /* Non-capturing or atomic group, except for possessive with unlimited - repeat and ONCE group with no captures. Loop for all the alternatives. - - When we get to the final alternative within the brackets, we used to return - the result of a recursive call to match() whatever happened so it was - possible to reduce stack usage by turning this into a tail recursion, - except in the case of a possibly empty group. However, now that there is - the possiblity of (*THEN) occurring in the final alternative, this - optimization is no longer always possible. - - We can optimize if we know there are no (*THEN)s in the pattern; at present - this is the best that can be done. - - MATCH_ONCE is returned when the end of an atomic group is successfully - reached, but subsequent matching fails. It passes back up the tree (causing - captured values to be reset) until the original atomic group level is - reached. This is tested by comparing mb->once_target with the start of the - group. At this point, the return is converted into MATCH_NOMATCH so that - previous backup points can be taken. */ - - case OP_ONCE: - case OP_BRA: - case OP_SBRA: - - for (;;) - { - if (op >= OP_SBRA || op == OP_ONCE) - mb->match_function_type |= MATCH_CBEGROUP; - - /* If this is not a possibly empty group, and there are no (*THEN)s in - the pattern, and this is the final alternative, optimize as described - above. */ - - else if (!mb->hasthen && ecode[GET(ecode, 1)] != OP_ALT) - { - ecode += PRIV(OP_lengths)[*ecode]; - goto TAIL_RECURSE; - } - - /* In all other cases, we have to make another call to match(). */ - - save_mark = mb->mark; - save_capture_last = mb->capture_last; - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, eptrb, - RM2); - - /* See comment in the code for capturing groups above about handling - THEN. */ - - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - if (rrc != MATCH_NOMATCH) - { - if (rrc == MATCH_ONCE) - { - PCRE2_SPTR scode = ecode; - if (*scode != OP_ONCE) /* If not at start, find it */ - { - while (*scode == OP_ALT) scode += GET(scode, 1); - scode -= GET(scode, 1); - } - if (mb->once_target == scode) rrc = MATCH_NOMATCH; - } - RRETURN(rrc); - } - ecode += GET(ecode, 1); - mb->mark = save_mark; - if (*ecode != OP_ALT) break; - mb->capture_last = save_capture_last; - } - - RRETURN(MATCH_NOMATCH); - - /* Handle possessive capturing brackets with an unlimited repeat. We come - here from BRAZERO with allow_zero set TRUE. The ovector values are - handled similarly to the normal case above. However, the matching is - different. The end of these brackets will always be OP_KETRPOS, which - returns MATCH_KETRPOS without going further in the pattern. By this means - we can handle the group by iteration rather than recursion, thereby - reducing the amount of stack needed. If the ovector is too small for - capturing, treat as non-capturing. */ - - case OP_CBRAPOS: - case OP_SCBRAPOS: - allow_zero = FALSE; - - POSSESSIVE_CAPTURE: - number = GET2(ecode, 1+LINK_SIZE); - offset = number << 1; - if (offset >= mb->offset_max) goto POSSESSIVE_NON_CAPTURE; - - matched_once = FALSE; - code_offset = (int)(ecode - mb->start_code); - - save_offset1 = mb->ovector[offset]; - save_offset2 = mb->ovector[offset+1]; - save_offset3 = mb->ovector[mb->offset_end - number]; - save_capture_last = mb->capture_last; - - /* Each time round the loop, save the current subject position for use - when the group matches. For MATCH_MATCH, the group has matched, so we - restart it with a new subject starting position, remembering that we had - at least one match. For MATCH_NOMATCH, carry on with the alternatives, as - usual. If we haven't matched any alternatives in any iteration, check to - see if a previous iteration matched. If so, the group has matched; - continue from afterwards. Otherwise it has failed; restore the previous - capture values before returning NOMATCH. */ - - for (;;) - { - mb->ovector[mb->offset_end - number] = eptr - mb->start_subject; - if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM63); - if (rrc == MATCH_KETRPOS) - { - offset_top = mb->end_offset_top; - ecode = mb->start_code + code_offset; - save_capture_last = mb->capture_last; - matched_once = TRUE; - mstart = mb->start_match_ptr; /* In case \K changed it */ - if (eptr == mb->end_match_ptr) /* Matched an empty string */ - { - do ecode += GET(ecode, 1); while (*ecode == OP_ALT); - break; - } - eptr = mb->end_match_ptr; - continue; - } - - /* See comment in the code for capturing groups above about handling - THEN. */ - - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->capture_last = save_capture_last; - ecode += GET(ecode, 1); - if (*ecode != OP_ALT) break; - } - - if (!matched_once) - { - mb->ovector[offset] = save_offset1; - mb->ovector[offset+1] = save_offset2; - mb->ovector[mb->offset_end - number] = save_offset3; - } - - if (allow_zero || matched_once) - { - ecode += 1 + LINK_SIZE; - break; - } - RRETURN(MATCH_NOMATCH); - - /* Non-capturing possessive bracket with unlimited repeat. We come here - from BRAZERO with allow_zero = TRUE. The code is similar to the above, - without the capturing complication. It is written out separately for speed - and cleanliness. */ - - case OP_BRAPOS: - case OP_SBRAPOS: - allow_zero = FALSE; - - POSSESSIVE_NON_CAPTURE: - matched_once = FALSE; - code_offset = (int)(ecode - mb->start_code); - save_capture_last = mb->capture_last; - - for (;;) - { - if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP; - RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, - eptrb, RM48); - if (rrc == MATCH_KETRPOS) - { - offset_top = mb->end_offset_top; - ecode = mb->start_code + code_offset; - matched_once = TRUE; - mstart = mb->start_match_ptr; /* In case \K reset it */ - if (eptr == mb->end_match_ptr) /* Matched an empty string */ - { - do ecode += GET(ecode, 1); while (*ecode == OP_ALT); - break; - } - eptr = mb->end_match_ptr; - continue; - } - - /* See comment in the code for capturing groups above about handling - THEN. */ - - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += GET(ecode, 1); - if (*ecode != OP_ALT) break; - mb->capture_last = save_capture_last; - } - - if (matched_once || allow_zero) - { - ecode += 1 + LINK_SIZE; - break; - } - RRETURN(MATCH_NOMATCH); - - /* Control never reaches here. */ - - /* Conditional group: compilation checked that there are no more than two - branches. If the condition is false, skipping the first branch takes us - past the end of the item if there is only one branch, but that's exactly - what we want. */ - - case OP_COND: - case OP_SCOND: - - /* The variable codelink will be added to ecode when the condition is - false, to get to the second branch. Setting it to the offset to the ALT - or KET, then incrementing ecode achieves this effect. We now have ecode - pointing to the condition or callout. */ - - codelink = GET(ecode, 1); /* Offset to the second branch */ - ecode += 1 + LINK_SIZE; /* From this opcode */ - - /* Because of the way auto-callout works during compile, a callout item is - inserted between OP_COND and an assertion condition. */ - - if (*ecode == OP_CALLOUT || *ecode == OP_CALLOUT_STR) - { - unsigned int callout_length = (*ecode == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE); - - if (mb->callout != NULL) - { - pcre2_callout_block cb; - cb.version = 1; - cb.capture_top = offset_top/2; - cb.capture_last = mb->capture_last & CAPLMASK; - cb.offset_vector = mb->ovector; - cb.mark = mb->nomatch_mark; - cb.subject = mb->start_subject; - cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject); - cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject); - cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject); - cb.pattern_position = GET(ecode, 1); - cb.next_item_length = GET(ecode, 1 + LINK_SIZE); - - if (*ecode == OP_CALLOUT) - { - cb.callout_number = ecode[1 + 2*LINK_SIZE]; - cb.callout_string_offset = 0; - cb.callout_string = NULL; - cb.callout_string_length = 0; - } - else - { - cb.callout_number = 0; - cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE); - cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1; - cb.callout_string_length = - callout_length - (1 + 4*LINK_SIZE) - 2; - } - - if ((rrc = mb->callout(&cb, mb->callout_data)) > 0) - RRETURN(MATCH_NOMATCH); - if (rrc < 0) RRETURN(rrc); - } - - /* Advance ecode past the callout, so it now points to the condition. We - must adjust codelink so that the value of ecode+codelink is unchanged. */ - - ecode += callout_length; - codelink -= callout_length; - } - - /* Test the various possible conditions */ - - condition = FALSE; - switch(condcode = *ecode) - { - case OP_RREF: /* Numbered group recursion test */ - if (mb->recursive != NULL) /* Not recursing => FALSE */ - { - uint32_t recno = GET2(ecode, 1); /* Recursion group number*/ - condition = (recno == RREF_ANY || recno == mb->recursive->group_num); - } - break; - - case OP_DNRREF: /* Duplicate named group recursion test */ - if (mb->recursive != NULL) - { - int count = GET2(ecode, 1 + IMM2_SIZE); - PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; - while (count-- > 0) - { - uint32_t recno = GET2(slot, 0); - condition = recno == mb->recursive->group_num; - if (condition) break; - slot += mb->name_entry_size; - } - } - break; - - case OP_CREF: /* Numbered group used test */ - offset = GET2(ecode, 1) << 1; /* Doubled ref number */ - condition = offset < offset_top && - mb->ovector[offset] != PCRE2_UNSET; - break; - - case OP_DNCREF: /* Duplicate named group used test */ - { - int count = GET2(ecode, 1 + IMM2_SIZE); - PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; - while (count-- > 0) - { - offset = GET2(slot, 0) << 1; - condition = offset < offset_top && - mb->ovector[offset] != PCRE2_UNSET; - if (condition) break; - slot += mb->name_entry_size; - } - } - break; - - case OP_FALSE: - case OP_FAIL: /* The assertion (?!) becomes OP_FAIL */ - break; - - case OP_TRUE: - condition = TRUE; - break; - - /* The condition is an assertion. Call match() to evaluate it - setting - the MATCH_CONDASSERT bit in mb->match_function_type causes it to stop at - the end of an assertion. */ - - default: - mb->match_function_type |= MATCH_CONDASSERT; - RMATCH(eptr, ecode, offset_top, mb, NULL, RM3); - if (rrc == MATCH_MATCH) - { - if (mb->end_offset_top > offset_top) - offset_top = mb->end_offset_top; /* Captures may have happened */ - condition = TRUE; - - /* Advance ecode past the assertion to the start of the first branch, - but adjust it so that the general choosing code below works. If the - assertion has a quantifier that allows zero repeats we must skip over - the BRAZERO. This is a lunatic thing to do, but somebody did! */ - - if (*ecode == OP_BRAZERO) ecode++; - ecode += GET(ecode, 1); - while (*ecode == OP_ALT) ecode += GET(ecode, 1); - ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode]; - } - - /* PCRE doesn't allow the effect of (*THEN) to escape beyond an - assertion; it is therefore treated as NOMATCH. Any other return is an - error. */ - - else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) - { - RRETURN(rrc); /* Need braces because of following else */ - } - break; - } - - /* Choose branch according to the condition */ - - ecode += condition? PRIV(OP_lengths)[condcode] : codelink; - - /* We are now at the branch that is to be obeyed. As there is only one, we - can use tail recursion to avoid using another stack frame, except when - there is unlimited repeat of a possibly empty group. In the latter case, a - recursive call to match() is always required, unless the second alternative - doesn't exist, in which case we can just plough on. Note that, for - compatibility with Perl, the | in a conditional group is NOT treated as - creating two alternatives. If a THEN is encountered in the branch, it - propagates out to the enclosing alternative (unless nested in a deeper set - of alternatives, of course). */ - - if (condition || ecode[-(1+LINK_SIZE)] == OP_ALT) - { - if (op != OP_SCOND) - { - goto TAIL_RECURSE; - } - - mb->match_function_type |= MATCH_CBEGROUP; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM49); - RRETURN(rrc); - } - - /* Condition false & no alternative; continue after the group. */ - - else - { - } - break; - - - /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, - to close any currently open capturing brackets. */ - - case OP_CLOSE: - number = GET2(ecode, 1); /* Must be less than 65536 */ - offset = number << 1; - mb->capture_last = (mb->capture_last & OVFLMASK) | number; - if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else - { - mb->ovector[offset] = - mb->ovector[mb->offset_end - number]; - mb->ovector[offset+1] = eptr - mb->start_subject; - - /* If this group is at or above the current highwater mark, ensure that - any groups between the current high water mark and this group are marked - unset and then update the high water mark. */ - - if (offset >= offset_top) - { - register PCRE2_SIZE *iptr = mb->ovector + offset_top; - register PCRE2_SIZE *iend = mb->ovector + offset; - while (iptr < iend) *iptr++ = PCRE2_UNSET; - offset_top = offset + 2; - } - } - ecode += 1 + IMM2_SIZE; - break; - - - /* End of the pattern, either real or forced. In an assertion ACCEPT, - update the last used pointer. */ - - case OP_ASSERT_ACCEPT: - if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; - - case OP_ACCEPT: - case OP_END: - - /* If we have matched an empty string, fail if not in an assertion and not - in a recursion if either PCRE2_NOTEMPTY is set, or if PCRE2_NOTEMPTY_ATSTART - is set and we have matched at the start of the subject. In both cases, - backtracking will then try other alternatives, if any. */ - - if (eptr == mstart && op != OP_ASSERT_ACCEPT && - mb->recursive == NULL && - ((mb->moptions & PCRE2_NOTEMPTY) != 0 || - ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 && - mstart == mb->start_subject + mb->start_offset))) - RRETURN(MATCH_NOMATCH); - - /* Otherwise, we have a match. */ - - mb->end_match_ptr = eptr; /* Record where we ended */ - mb->end_offset_top = offset_top; /* and how many extracts were taken */ - mb->start_match_ptr = mstart; /* and the start (\K can modify) */ - - /* For some reason, the macros don't work properly if an expression is - given as the argument to RRETURN when the heap is in use. */ - - rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; - RRETURN(rrc); - - /* Assertion brackets. Check the alternative branches in turn - the - matching won't pass the KET for an assertion. If any one branch matches, - the assertion is true. Lookbehind assertions have an OP_REVERSE item at the - start of each branch to move the current point backwards, so the code at - this level is identical to the lookahead case. When the assertion is part - of a condition, we want to return immediately afterwards. The caller of - this incarnation of the match() function will have set MATCH_CONDASSERT in - mb->match_function type, and one of these opcodes will be the first opcode - that is processed. We use a local variable that is preserved over calls to - match() to remember this case. */ - - case OP_ASSERT: - case OP_ASSERTBACK: - save_mark = mb->mark; - if ((mb->match_function_type & MATCH_CONDASSERT) != 0) - { - condassert = TRUE; - mb->match_function_type &= ~MATCH_CONDASSERT; - } - else condassert = FALSE; - - /* Loop for each branch */ - - do - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM4); - - /* A match means that the assertion is true; break out of the loop - that matches its alternatives. */ - - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) - { - mstart = mb->start_match_ptr; /* In case \K reset it */ - break; - } - - /* If not matched, restore the previous mark setting. */ - - mb->mark = save_mark; - - /* See comment in the code for capturing groups above about handling - THEN. */ - - if (rrc == MATCH_THEN) - { - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - rrc = MATCH_NOMATCH; - } - - /* Anything other than NOMATCH causes the entire assertion to fail, - passing back the return code. This includes COMMIT, SKIP, PRUNE and an - uncaptured THEN, which means they take their normal effect. This - consistent approach does not always have exactly the same effect as in - Perl. */ - - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += GET(ecode, 1); - } - while (*ecode == OP_ALT); /* Continue for next alternative */ - - /* If we have tried all the alternative branches, the assertion has - failed. If not, we broke out after a match. */ - - if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); - - /* If checking an assertion for a condition, return MATCH_MATCH. */ - - if (condassert) RRETURN(MATCH_MATCH); - - /* Continue from after a successful assertion, updating the offsets high - water mark, since extracts may have been taken during the assertion. */ - - do ecode += GET(ecode,1); while (*ecode == OP_ALT); - ecode += 1 + LINK_SIZE; - offset_top = mb->end_offset_top; - continue; - - /* Negative assertion: all branches must fail to match for the assertion to - succeed. */ - - case OP_ASSERT_NOT: - case OP_ASSERTBACK_NOT: - save_mark = mb->mark; - if ((mb->match_function_type & MATCH_CONDASSERT) != 0) - { - condassert = TRUE; - mb->match_function_type &= ~MATCH_CONDASSERT; - } - else condassert = FALSE; - - /* Loop for each alternative branch. */ - - do - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM5); - mb->mark = save_mark; /* Always restore the mark setting */ - - switch(rrc) - { - case MATCH_MATCH: /* A successful match means */ - case MATCH_ACCEPT: /* the assertion has failed. */ - RRETURN(MATCH_NOMATCH); - - case MATCH_NOMATCH: /* Carry on with next branch */ - break; - - /* See comment in the code for capturing groups above about handling - THEN. */ - - case MATCH_THEN: - next_ecode = ecode + GET(ecode,1); - if (mb->start_match_ptr < next_ecode && - (*ecode == OP_ALT || *next_ecode == OP_ALT)) - { - rrc = MATCH_NOMATCH; - break; - } - /* Otherwise fall through. */ - - /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole - assertion to fail to match, without considering any more alternatives. - Failing to match means the assertion is true. This is a consistent - approach, but does not always have the same effect as in Perl. */ - - case MATCH_COMMIT: - case MATCH_SKIP: - case MATCH_SKIP_ARG: - case MATCH_PRUNE: - do ecode += GET(ecode,1); while (*ecode == OP_ALT); - goto NEG_ASSERT_TRUE; /* Break out of alternation loop */ - - /* Anything else is an error */ - - default: - RRETURN(rrc); - } - - /* Continue with next branch */ - - ecode += GET(ecode,1); - } - while (*ecode == OP_ALT); - - /* All branches in the assertion failed to match. */ - - NEG_ASSERT_TRUE: - if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ - ecode += 1 + LINK_SIZE; /* Continue with current branch */ - continue; - - /* Move the subject pointer back. This occurs only at the start of - each branch of a lookbehind assertion. If we are too close to the start to - move back, this match function fails. When working with UTF-8 we move - back a number of characters, not bytes. */ - - case OP_REVERSE: - i = GET(ecode, 1); -#ifdef SUPPORT_UNICODE - if (utf) - { - while (i-- > 0) - { - if (eptr <= mb->start_subject) RRETURN(MATCH_NOMATCH); - eptr--; - BACKCHAR(eptr); - } - } - else -#endif - - /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ - - { - if (i > eptr - mb->start_subject) RRETURN(MATCH_NOMATCH); - eptr -= i; - } - - /* Save the earliest consulted character, then skip to next op code */ - - if (eptr < mb->start_used_ptr) mb->start_used_ptr = eptr; - ecode += 1 + LINK_SIZE; - break; - - /* The callout item calls an external function, if one is provided, passing - details of the match so far. This is mainly for debugging, though the - function is able to force a failure. */ - - case OP_CALLOUT: - case OP_CALLOUT_STR: - { - unsigned int callout_length = (*ecode == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE); - - if (mb->callout != NULL) - { - pcre2_callout_block cb; - cb.version = 1; - cb.callout_number = ecode[LINK_SIZE + 1]; - cb.capture_top = offset_top/2; - cb.capture_last = mb->capture_last & CAPLMASK; - cb.offset_vector = mb->ovector; - cb.mark = mb->nomatch_mark; - cb.subject = mb->start_subject; - cb.subject_length = (PCRE2_SIZE)(mb->end_subject - mb->start_subject); - cb.start_match = (PCRE2_SIZE)(mstart - mb->start_subject); - cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject); - cb.pattern_position = GET(ecode, 1); - cb.next_item_length = GET(ecode, 1 + LINK_SIZE); - - if (*ecode == OP_CALLOUT) - { - cb.callout_number = ecode[1 + 2*LINK_SIZE]; - cb.callout_string_offset = 0; - cb.callout_string = NULL; - cb.callout_string_length = 0; - } - else - { - cb.callout_number = 0; - cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE); - cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1; - cb.callout_string_length = - callout_length - (1 + 4*LINK_SIZE) - 2; - } - - if ((rrc = mb->callout(&cb, mb->callout_data)) > 0) - RRETURN(MATCH_NOMATCH); - if (rrc < 0) RRETURN(rrc); - } - ecode += callout_length; - } - break; - - /* Recursion either matches the current regex, or some subexpression. The - offset data is the offset to the starting bracket from the start of the - whole pattern. (This is so that it works from duplicated subpatterns.) - - The state of the capturing groups is preserved over recursion, and - re-instated afterwards. We don't know how many are started and not yet - finished (offset_top records the completed total) so we just have to save - all the potential data. There may be up to 65535 such values, which is too - large to put on the stack, but using malloc for small numbers seems - expensive. As a compromise, the stack is used when there are no more than - OP_RECURSE_STACK_SAVE_MAX values to store; otherwise malloc is used. - - There are also other values that have to be saved. We use a chained - sequence of blocks that actually live on the stack. Thanks to Robin Houston - for the original version of this logic. It has, however, been hacked around - a lot, so he is not to blame for the current way it works. */ - - case OP_RECURSE: - { - ovecsave_frame *fr; - recursion_info *ri; - uint32_t recno; - - callpat = mb->start_code + GET(ecode, 1); - recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); - - /* Check for repeating a pattern recursion without advancing the subject - pointer. This should catch convoluted mutual recursions. (Some simple - cases are caught at compile time.) */ - - for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) - if (recno == ri->group_num && eptr == ri->subject_position) - RRETURN(PCRE2_ERROR_RECURSELOOP); - - /* Add to "recursing stack" */ - - new_recursive.group_num = recno; - new_recursive.saved_capture_last = mb->capture_last; - new_recursive.subject_position = eptr; - new_recursive.prevrec = mb->recursive; - mb->recursive = &new_recursive; - - /* Where to continue from afterwards */ - - ecode += 1 + LINK_SIZE; - - /* When we are using the system stack for match() recursion we can call a - function that uses the system stack for preserving the ovector while - processing the pattern recursion, but only if the ovector is small - enough. */ - -#ifndef HEAP_MATCH_RECURSE - if (mb->offset_end <= OP_RECURSE_STACK_SAVE_MAX) - { - rrc = op_recurse_ovecsave(eptr, callpat, mstart, offset_top, mb, - eptrb, rdepth); - mb->recursive = new_recursive.prevrec; - if (rrc != MATCH_MATCH && rrc != MATCH_ACCEPT) RRETURN(rrc); - - /* Set where we got to in the subject, and reset the start, in case - it was changed by \K. This *is* propagated back out of a recursion, - for Perl compatibility. */ - - eptr = mb->end_match_ptr; - mstart = mb->start_match_ptr; - break; /* End of processing OP_RECURSE */ - } -#endif - /* If the ovector is too big, or if we are using the heap for match() - recursion, we have to use the heap for saving the ovector. Used ovecsave - frames are kept on a chain and re-used. This makes a small improvement in - execution time on Linux. */ - - if (mb->ovecsave_chain != NULL) - { - new_recursive.ovec_save = mb->ovecsave_chain->saved_ovec; - mb->ovecsave_chain = mb->ovecsave_chain->next; - } - else - { - fr = (ovecsave_frame *)(mb->memctl.malloc(sizeof(ovecsave_frame *) + - mb->offset_end * sizeof(PCRE2_SIZE), mb->memctl.memory_data)); - if (fr == NULL) RRETURN(PCRE2_ERROR_NOMEMORY); - new_recursive.ovec_save = fr->saved_ovec; - } - - memcpy(new_recursive.ovec_save, mb->ovector, - mb->offset_end * sizeof(PCRE2_SIZE)); - - /* Do the recursion. After processing each alternative, restore the - ovector data and the last captured value. This code has the same overall - logic as the code in the op_recurse_ovecsave() function, but is adapted - to use RMATCH/RRETURN and to release the heap block containing the saved - ovector. */ - - cbegroup = (*callpat >= OP_SBRA); - do - { - if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP; - RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, - mb, eptrb, RM6); - memcpy(mb->ovector, new_recursive.ovec_save, - mb->offset_end * sizeof(PCRE2_SIZE)); - mb->capture_last = new_recursive.saved_capture_last; - mb->recursive = new_recursive.prevrec; - - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) - { - fr = (ovecsave_frame *) - ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *)); - fr->next = mb->ovecsave_chain; - mb->ovecsave_chain = fr; - - /* Set where we got to in the subject, and reset the start, in case - it was changed by \K. This *is* propagated back out of a recursion, - for Perl compatibility. */ - - eptr = mb->end_match_ptr; - mstart = mb->start_match_ptr; - goto RECURSION_MATCHED; /* Exit loop; end processing */ - } - - /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a - recursion; they cause a NOMATCH for the entire recursion. These codes - are defined in a range that can be tested for. */ - - if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX) - { - rrc = MATCH_NOMATCH; - goto RECURSION_RETURN; - } - - /* Any return code other than NOMATCH is an error. */ - - if (rrc != MATCH_NOMATCH) goto RECURSION_RETURN; - mb->recursive = &new_recursive; - callpat += GET(callpat, 1); - } - while (*callpat == OP_ALT); - - RECURSION_RETURN: - mb->recursive = new_recursive.prevrec; - fr = (ovecsave_frame *) - ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *)); - fr->next = mb->ovecsave_chain; - mb->ovecsave_chain = fr; - RRETURN(rrc); - } - - RECURSION_MATCHED: - break; - - /* An alternation is the end of a branch; scan along to find the end of the - bracketed group and go to there. */ - - case OP_ALT: - do ecode += GET(ecode,1); while (*ecode == OP_ALT); - break; - - /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group, - indicating that it may occur zero times. It may repeat infinitely, or not - at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets - with fixed upper repeat limits are compiled as a number of copies, with the - optional ones preceded by BRAZERO or BRAMINZERO. */ - - case OP_BRAZERO: - next_ecode = ecode + 1; - RMATCH(eptr, next_ecode, offset_top, mb, eptrb, RM10); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT); - ecode = next_ecode + 1 + LINK_SIZE; - break; - - case OP_BRAMINZERO: - next_ecode = ecode + 1; - do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT); - RMATCH(eptr, next_ecode + 1+LINK_SIZE, offset_top, mb, eptrb, RM11); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode++; - break; - - case OP_SKIPZERO: - next_ecode = ecode+1; - do next_ecode += GET(next_ecode,1); while (*next_ecode == OP_ALT); - ecode = next_ecode + 1 + LINK_SIZE; - break; - - /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything - here; just jump to the group, with allow_zero set TRUE. */ - - case OP_BRAPOSZERO: - op = *(++ecode); - allow_zero = TRUE; - if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE; - goto POSSESSIVE_NON_CAPTURE; - - /* End of a group, repeated or non-repeating. */ - - case OP_KET: - case OP_KETRMIN: - case OP_KETRMAX: - case OP_KETRPOS: - prev = ecode - GET(ecode, 1); - - /* If this was a group that remembered the subject start, in order to break - infinite repeats of empty string matches, retrieve the subject start from - the chain. Otherwise, set it NULL. */ - - if (*prev >= OP_SBRA || *prev == OP_ONCE) - { - saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ - eptrb = eptrb->epb_prev; /* Backup to previous group */ - } - else saved_eptr = NULL; - - /* If we are at the end of an assertion group or a non-capturing atomic - group, stop matching and return MATCH_MATCH, but record the current high - water mark for use by positive assertions. We also need to record the match - start in case it was changed by \K. */ - - if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) || - *prev == OP_ONCE_NC) - { - mb->end_match_ptr = eptr; /* For ONCE_NC */ - mb->end_offset_top = offset_top; - mb->start_match_ptr = mstart; - if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; - RRETURN(MATCH_MATCH); /* Sets mb->mark */ - } - - /* For capturing groups we have to check the group number back at the start - and if necessary complete handling an extraction by setting the offsets and - bumping the high water mark. Whole-pattern recursion is coded as a recurse - into group 0, so it won't be picked up here. Instead, we catch it when the - OP_END is reached. Other recursion is handled here. We just have to record - the current subject position and start match pointer and give a MATCH - return. */ - - if (*prev == OP_CBRA || *prev == OP_SCBRA || - *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS) - { - number = GET2(prev, 1+LINK_SIZE); - offset = number << 1; - - /* Handle a recursively called group. */ - - if (mb->recursive != NULL && mb->recursive->group_num == number) - { - mb->end_match_ptr = eptr; - mb->start_match_ptr = mstart; - if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; - RRETURN(MATCH_MATCH); - } - - /* Deal with capturing */ - - mb->capture_last = (mb->capture_last & OVFLMASK) | number; - if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else - { - /* If offset is greater than offset_top, it means that we are - "skipping" a capturing group, and that group's offsets must be marked - unset. In earlier versions of PCRE, all the offsets were unset at the - start of matching, but this doesn't work because atomic groups and - assertions can cause a value to be set that should later be unset. - Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as - part of the atomic group, but this is not on the final matching path, - so must be unset when 2 is set. (If there is no group 2, there is no - problem, because offset_top will then be 2, indicating no capture.) */ - - if (offset > offset_top) - { - register PCRE2_SIZE *iptr = mb->ovector + offset_top; - register PCRE2_SIZE *iend = mb->ovector + offset; - while (iptr < iend) *iptr++ = PCRE2_UNSET; - } - - /* Now make the extraction */ - - mb->ovector[offset] = mb->ovector[mb->offset_end - number]; - mb->ovector[offset+1] = eptr - mb->start_subject; - if (offset_top <= offset) offset_top = offset + 2; - } - } - - /* OP_KETRPOS is a possessive repeating ket. Remember the current position, - and return the MATCH_KETRPOS. This makes it possible to do the repeats one - at a time from the outer level, thus saving stack. This must precede the - empty string test - in this case that test is done at the outer level. */ - - if (*ecode == OP_KETRPOS) - { - mb->start_match_ptr = mstart; /* In case \K reset it */ - mb->end_match_ptr = eptr; - mb->end_offset_top = offset_top; - if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr; - RRETURN(MATCH_KETRPOS); - } - - /* For an ordinary non-repeating ket, just continue at this level. This - also happens for a repeating ket if no characters were matched in the - group. This is the forcible breaking of infinite loops as implemented in - Perl 5.005. For a non-repeating atomic group that includes captures, - establish a backup point by processing the rest of the pattern at a lower - level. If this results in a NOMATCH return, pass MATCH_ONCE back to the - original OP_ONCE level, thereby bypassing intermediate backup points, but - resetting any captures that happened along the way. */ - - if (*ecode == OP_KET || eptr == saved_eptr) - { - if (*prev == OP_ONCE) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM12); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ - RRETURN(MATCH_ONCE); - } - ecode += 1 + LINK_SIZE; /* Carry on at this level */ - break; - } - - /* The normal repeating kets try the rest of the pattern or restart from - the preceding bracket, in the appropriate order. In the second case, we can - use tail recursion to avoid using another stack frame, unless we have an - an atomic group or an unlimited repeat of a group that can match an empty - string. */ - - if (*ecode == OP_KETRMIN) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM7); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (*prev == OP_ONCE) - { - RMATCH(eptr, prev, offset_top, mb, eptrb, RM8); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ - RRETURN(MATCH_ONCE); - } - if (*prev >= OP_SBRA) /* Could match an empty string */ - { - RMATCH(eptr, prev, offset_top, mb, eptrb, RM50); - RRETURN(rrc); - } - ecode = prev; - goto TAIL_RECURSE; - } - else /* OP_KETRMAX */ - { - RMATCH(eptr, prev, offset_top, mb, eptrb, RM13); - if (rrc == MATCH_ONCE && mb->once_target == prev) rrc = MATCH_NOMATCH; - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (*prev == OP_ONCE) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM9); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - mb->once_target = prev; - RRETURN(MATCH_ONCE); - } - ecode += 1 + LINK_SIZE; - goto TAIL_RECURSE; - } - /* Control never gets here */ - - /* Not multiline mode: start of subject assertion, unless notbol. */ - - case OP_CIRC: - if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject) - RRETURN(MATCH_NOMATCH); - - /* Start of subject assertion */ - - case OP_SOD: - if (eptr != mb->start_subject) RRETURN(MATCH_NOMATCH); - ecode++; - break; - - /* Multiline mode: start of subject unless notbol, or after any newline - except for one at the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */ - - case OP_CIRCM: - if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject) - RRETURN(MATCH_NOMATCH); - if (eptr != mb->start_subject && - ((eptr == mb->end_subject && - (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) || - !WAS_NEWLINE(eptr))) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - /* Start of match assertion */ - - case OP_SOM: - if (eptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH); - ecode++; - break; - - /* Reset the start of match point */ - - case OP_SET_SOM: - mstart = eptr; - ecode++; - break; - - /* Multiline mode: assert before any newline, or before end of subject - unless noteol is set. */ - - case OP_DOLLM: - if (eptr < mb->end_subject) - { - if (!IS_NEWLINE(eptr)) - { - if (mb->partial != 0 && - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - UCHAR21TEST(eptr) == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - RRETURN(MATCH_NOMATCH); - } - } - else - { - if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); - SCHECK_PARTIAL(); - } - ecode++; - break; - - /* Not multiline mode: assert before a terminating newline or before end of - subject unless noteol is set. */ - - case OP_DOLL: - if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); - if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - - /* ... else fall through for endonly */ - - /* End of subject assertion (\z) */ - - case OP_EOD: - if (eptr < mb->end_subject) RRETURN(MATCH_NOMATCH); - SCHECK_PARTIAL(); - ecode++; - break; - - /* End of subject or ending \n assertion (\Z) */ - - case OP_EODN: - ASSERT_NL_OR_EOS: - if (eptr < mb->end_subject && - (!IS_NEWLINE(eptr) || eptr != mb->end_subject - mb->nllen)) - { - if (mb->partial != 0 && - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - UCHAR21TEST(eptr) == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - RRETURN(MATCH_NOMATCH); - } - - /* Either at end of string or \n before end. */ - - SCHECK_PARTIAL(); - ecode++; - break; - - /* Word boundary assertions */ - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - { - - /* Find out if the previous and current characters are "word" characters. - It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to - be "non-word" characters. Remember the earliest consulted character for - partial matching. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - /* Get status of previous character */ - - if (eptr == mb->start_subject) prev_is_word = FALSE; else - { - PCRE2_SPTR lastptr = eptr - 1; - BACKCHAR(lastptr); - if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr; - GETCHAR(c, lastptr); - if ((mb->poptions & PCRE2_UCP) != 0) - { - if (c == '_') prev_is_word = TRUE; else - { - int cat = UCD_CATEGORY(c); - prev_is_word = (cat == ucp_L || cat == ucp_N); - } - } - else - prev_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0; - } - - /* Get status of next character */ - - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - cur_is_word = FALSE; - } - else - { - PCRE2_SPTR nextptr = eptr + 1; - FORWARDCHARTEST(nextptr, mb->end_subject); - if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr; - GETCHAR(c, eptr); - if ((mb->poptions & PCRE2_UCP) != 0) - { - if (c == '_') cur_is_word = TRUE; else - { - int cat = UCD_CATEGORY(c); - cur_is_word = (cat == ucp_L || cat == ucp_N); - } - } - else - cur_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0; - } - } - else -#endif /* SUPPORT UTF */ - - /* Not in UTF-8 mode, but we may still have PCRE2_UCP set, and for - consistency with the behaviour of \w we do use it in this case. */ - - { - /* Get status of previous character */ - - if (eptr == mb->start_subject) prev_is_word = FALSE; else - { - if (eptr <= mb->start_used_ptr) mb->start_used_ptr = eptr - 1; -#ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) - { - c = eptr[-1]; - if (c == '_') prev_is_word = TRUE; else - { - int cat = UCD_CATEGORY(c); - prev_is_word = (cat == ucp_L || cat == ucp_N); - } - } - else -#endif - prev_is_word = MAX_255(eptr[-1]) - && ((mb->ctypes[eptr[-1]] & ctype_word) != 0); - } - - /* Get status of next character */ - - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - cur_is_word = FALSE; - } - else - { - if (eptr >= mb->last_used_ptr) mb->last_used_ptr = eptr + 1; -#ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) - { - c = *eptr; - if (c == '_') cur_is_word = TRUE; else - { - int cat = UCD_CATEGORY(c); - cur_is_word = (cat == ucp_L || cat == ucp_N); - } - } - else -#endif - cur_is_word = MAX_255(*eptr) - && ((mb->ctypes[*eptr] & ctype_word) != 0); - } - } - - /* Now see if the situation is what we want */ - - if ((*ecode++ == OP_WORD_BOUNDARY)? - cur_is_word == prev_is_word : cur_is_word != prev_is_word) - RRETURN(MATCH_NOMATCH); - } - break; - - /* Match any single character type except newline; have to take care with - CRLF newlines and partial matching. */ - - case OP_ANY: - if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); - if (mb->partial != 0 && - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - UCHAR21TEST(eptr) == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - - /* Fall through */ - - /* Match any single character whatsoever. */ - - case OP_ALLANY: - if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */ - { /* not be updated before SCHECK_PARTIAL. */ - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr++; -#ifdef SUPPORT_UNICODE - if (utf) ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); -#endif - ecode++; - break; - - /* Match a single code unit, even in UTF-8 mode. This opcode really does - match any code unit, even newline. (It really should be called ANYCODEUNIT, - of course - the byte name is from pre-16 bit days.) */ - - case OP_ANYBYTE: - if (eptr >= mb->end_subject) /* DO NOT merge the eptr++ here; it must */ - { /* not be updated before SCHECK_PARTIAL. */ - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr++; - ecode++; - break; - - case OP_NOT_DIGIT: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c < 256 && -#endif - (mb->ctypes[c] & ctype_digit) != 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_DIGIT: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c > 255 || -#endif - (mb->ctypes[c] & ctype_digit) == 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_NOT_WHITESPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c < 256 && -#endif - (mb->ctypes[c] & ctype_space) != 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_WHITESPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c > 255 || -#endif - (mb->ctypes[c] & ctype_space) == 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_NOT_WORDCHAR: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c < 256 && -#endif - (mb->ctypes[c] & ctype_word) != 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_WORDCHAR: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ( -#ifdef SUPPORT_WIDE_CHARS - c > 255 || -#endif - (mb->ctypes[c] & ctype_word) == 0 - ) - RRETURN(MATCH_NOMATCH); - ecode++; - break; - - case OP_ANYNL: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - - case CHAR_CR: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - } - else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++; - break; - - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); - break; - } - ecode++; - break; - - case OP_NOT_HSPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ - default: break; - } - ecode++; - break; - - case OP_HSPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - HSPACE_CASES: break; /* Byte and multibyte cases */ - default: RRETURN(MATCH_NOMATCH); - } - ecode++; - break; - - case OP_NOT_VSPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); - default: break; - } - ecode++; - break; - - case OP_VSPACE: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - VSPACE_CASES: break; - default: RRETURN(MATCH_NOMATCH); - } - ecode++; - break; - -#ifdef SUPPORT_UNICODE - /* Check the next character by Unicode property. We will get here only - if the support is in the binary; otherwise a compile-time error occurs. */ - - case OP_PROP: - case OP_NOTPROP: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - { - const uint32_t *cp; - const ucd_record *prop = GET_UCD(c); - - switch(ecode[1]) - { - case PT_ANY: - if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); - break; - - case PT_LAMP: - if ((prop->chartype == ucp_Lu || - prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); - break; - - case PT_GC: - if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) - RRETURN(MATCH_NOMATCH); - break; - - case PT_PC: - if ((ecode[2] != prop->chartype) == (op == OP_PROP)) - RRETURN(MATCH_NOMATCH); - break; - - case PT_SC: - if ((ecode[2] != prop->script) == (op == OP_PROP)) - RRETURN(MATCH_NOMATCH); - break; - - /* These are specials */ - - case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); - break; - - default: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == - (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); - break; - } - break; - - case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); - break; - - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + ecode[2]; - for (;;) - { - if (c < *cp) - { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; } - if (c == *cp++) - { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } } - } - break; - - case PT_UCNC: - if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000) == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); - break; - - /* This should never occur */ - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - - ecode += 3; - } - break; - - /* Match an extended Unicode sequence. We will get here only if the support - is in the binary; otherwise a compile-time error occurs. */ - - case OP_EXTUNI: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - else - { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < mb->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } - } - CHECK_PARTIAL(); - ecode++; - break; -#endif /* SUPPORT_UNICODE */ - - - /* Match a back reference, possibly repeatedly. Look past the end of the - item to see if there is repeat information following. - - The OP_REF and OP_REFI opcodes are used for a reference to a numbered group - or to a non-duplicated named group. For a duplicated named group, OP_DNREF - and OP_DNREFI are used. In this case we must scan the list of groups to - which the name refers, and use the first one that is set. */ - - case OP_DNREF: - case OP_DNREFI: - caseless = op == OP_DNREFI; - { - int count = GET2(ecode, 1+IMM2_SIZE); - PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; - ecode += 1 + 2*IMM2_SIZE; - - /* Initializing 'offset' avoids a compiler warning in the REF_REPEAT - code. */ - - offset = 0; - while (count-- > 0) - { - offset = GET2(slot, 0) << 1; - if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) break; - slot += mb->name_entry_size; - } - } - goto REF_REPEAT; - - case OP_REF: - case OP_REFI: - caseless = op == OP_REFI; - offset = GET2(ecode, 1) << 1; /* Doubled ref number */ - ecode += 1 + IMM2_SIZE; - - /* Set up for repetition, or handle the non-repeated case */ - - REF_REPEAT: - switch (*ecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - c = *ecode++ - OP_CRSTAR; - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - minimize = (*ecode == OP_CRMINRANGE); - min = GET2(ecode, 1); - max = GET2(ecode, 1 + IMM2_SIZE); - if (max == 0) max = INT_MAX; - ecode += 1 + 2 * IMM2_SIZE; - break; - - default: /* No repeat follows */ - { - int rc = match_ref(offset, offset_top, eptr, mb, caseless, &length); - if (rc != 0) - { - if (rc > 0) eptr = mb->end_subject; /* Partial match */ - CHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - } - eptr += length; - continue; /* With the main loop */ - } - - /* Handle repeated back references. If a set group has length zero, just - continue with the main loop, because it matches however many times. For an - unset reference, if the minimum is zero, we can also just continue. We an - also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset - group be have as a zero-length group. For any other unset cases, carrying - on will result in NOMATCH. */ - - if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) - { - if (mb->ovector[offset] == mb->ovector[offset + 1]) continue; - } - else /* Group is not set */ - { - if (min == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0) - continue; - } - - /* First, ensure the minimum number of matches are present. We get back - the length of the reference string explicitly rather than passing the - address of eptr, so that eptr can be a register variable. */ - - for (i = 1; i <= min; i++) - { - PCRE2_SIZE slength; - int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); - if (rc != 0) - { - if (rc > 0) eptr = mb->end_subject; /* Partial match */ - CHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr += slength; - } - - /* If min = max, continue at the same level without recursion. - They are not both allowed to be zero. */ - - if (min == max) continue; - - /* If minimizing, keep trying and advancing the pointer */ - - if (minimize) - { - for (fi = min;; fi++) - { - int rc; - PCRE2_SIZE slength; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM14); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); - if (rc != 0) - { - if (rc > 0) eptr = mb->end_subject; /* Partial match */ - CHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr += slength; - } - /* Control never gets here */ - } - - /* If maximizing, find the longest string and work backwards, as long as - the matched lengths for each iteration are the same. */ - - else - { - BOOL samelengths = TRUE; - pp = eptr; - length = mb->ovector[offset+1] - mb->ovector[offset]; - - for (i = min; i < max; i++) - { - PCRE2_SIZE slength; - int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength); - - if (rc != 0) - { - /* Can't use CHECK_PARTIAL because we don't want to update eptr in - the soft partial matching case. */ - - if (rc > 0 && mb->partial != 0 && - mb->end_subject > mb->start_used_ptr) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - break; - } - - if (slength != length) samelengths = FALSE; - eptr += slength; - } - - /* If the length matched for each repetition is the same as the length of - the captured group, we can easily work backwards. This is the normal - case. However, in caseless UTF-8 mode there are pairs of case-equivalent - characters whose lengths (in terms of code units) differ. However, this - is very rare, so we handle it by re-matching fewer and fewer times. */ - - if (samelengths) - { - while (eptr >= pp) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM15); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr -= length; - } - } - - /* The rare case of non-matching lengths. Re-scan the repetition for each - iteration. We know that match_ref() will succeed every time. */ - - else - { - max = i; - for (;;) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM68); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr == pp) break; /* Failed after minimal repetition */ - eptr = pp; - max--; - for (i = min; i < max; i++) - { - PCRE2_SIZE slength; - (void)match_ref(offset, offset_top, eptr, mb, caseless, &slength); - eptr += slength; - } - } - } - - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - /* Match a bit-mapped character class, possibly repeatedly. This op code is - used when all the characters in the class have values in the range 0-255, - and either the matching is caseful, or the characters are in the range - 0-127 when UTF-8 processing is enabled. The only difference between - OP_CLASS and OP_NCLASS occurs when a data character outside the range is - encountered. - - First, look past the end of the item to see if there is repeat information - following. Then obey similar code to character type repeats - written out - again for speed. */ - - case OP_NCLASS: - case OP_CLASS: - { - /* The data variable is saved across frames, so the byte map needs to - be stored there. */ -#define BYTE_MAP ((uint8_t *)data) - data = ecode + 1; /* Save for matching */ - ecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */ - - switch (*ecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - c = *ecode++ - OP_CRSTAR; - if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; - else possessive = TRUE; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - minimize = (*ecode == OP_CRMINRANGE); - possessive = (*ecode == OP_CRPOSRANGE); - min = GET2(ecode, 1); - max = GET2(ecode, 1 + IMM2_SIZE); - if (max == 0) max = INT_MAX; - ecode += 1 + 2 * IMM2_SIZE; - break; - - default: /* No repeat follows */ - min = max = 1; - break; - } - - /* First, ensure the minimum number of matches are present. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - if (c > 255) - { - if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); - } - else - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); - } - } - else -#endif - /* Not UTF mode */ - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - c = *eptr++; -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) - { - if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); - } - else -#endif - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); - } - } - - /* If max == min we can continue with the main loop without the - need to recurse. */ - - if (min == max) continue; - - /* If minimizing, keep testing the rest of the expression and advancing - the pointer while it matches the class. */ - - if (minimize) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM16); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - if (c > 255) - { - if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); - } - else - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); - } - } - else -#endif - /* Not UTF mode */ - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM17); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - c = *eptr++; -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) - { - if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); - } - else -#endif - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); - } - } - /* Control never gets here */ - } - - /* If maximizing, find the longest possible run, then work backwards. */ - - else - { - pp = eptr; - -#ifdef SUPPORT_UNICODE - if (utf) - { - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c > 255) - { - if (op == OP_CLASS) break; - } - else - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; - eptr += len; - } - - if (possessive) continue; /* No backtracking */ - - for (;;) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM18); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ - BACKCHAR(eptr); - } - } - else -#endif - /* Not UTF mode */ - { - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - c = *eptr; -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) - { - if (op == OP_CLASS) break; - } - else -#endif - if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; - eptr++; - } - - if (possessive) continue; /* No backtracking */ - - while (eptr >= pp) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM19); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - } - } - - RRETURN(MATCH_NOMATCH); - } -#undef BYTE_MAP - } - /* Control never gets here */ - - - /* Match an extended character class. In the 8-bit library, this opcode is - encountered only when UTF-8 mode mode is supported. In the 16-bit and - 32-bit libraries, codepoints greater than 255 may be encountered even when - UTF is not supported. */ - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - { - data = ecode + 1 + LINK_SIZE; /* Save for matching */ - ecode += GET(ecode, 1); /* Advance past the item */ - - switch (*ecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - c = *ecode++ - OP_CRSTAR; - if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; - else possessive = TRUE; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - minimize = (*ecode == OP_CRMINRANGE); - possessive = (*ecode == OP_CRPOSRANGE); - min = GET2(ecode, 1); - max = GET2(ecode, 1 + IMM2_SIZE); - if (max == 0) max = INT_MAX; - ecode += 1 + 2 * IMM2_SIZE; - break; - - default: /* No repeat follows */ - min = max = 1; - break; - } - - /* First, ensure the minimum number of matches are present. */ - - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); - } - - /* If max == min we can continue with the main loop without the - need to recurse. */ - - if (min == max) continue; - - /* If minimizing, keep testing the rest of the expression and advancing - the pointer while it matches the class. */ - - if (minimize) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM20); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - } - - /* If maximizing, find the longest possible run, then work backwards. */ - - else - { - pp = eptr; - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } -#ifdef SUPPORT_UNICODE - GETCHARLENTEST(c, eptr, len); -#else - c = *eptr; -#endif - if (!PRIV(xclass)(c, data, utf)) break; - eptr += len; - } - - if (possessive) continue; /* No backtracking */ - - for(;;) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM21); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ -#ifdef SUPPORT_UNICODE - if (utf) BACKCHAR(eptr); -#endif - } - RRETURN(MATCH_NOMATCH); - } - - /* Control never gets here */ - } -#endif /* End of XCLASS */ - - /* Match a single character, casefully */ - - case OP_CHAR: -#ifdef SUPPORT_UNICODE - if (utf) - { - length = 1; - ecode++; - GETCHARLEN(fc, ecode, length); - if (length > (PCRE2_SIZE)(mb->end_subject - eptr)) - { - CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ - RRETURN(MATCH_NOMATCH); - } - for (; length > 0; length--) - { - if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH); - } - } - else -#endif - /* Not UTF mode */ - { - if (mb->end_subject - eptr < 1) - { - SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - RRETURN(MATCH_NOMATCH); - } - if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); - ecode += 2; - } - break; - - /* Match a single character, caselessly. If we are at the end of the - subject, give up immediately. */ - - case OP_CHARI: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - -#ifdef SUPPORT_UNICODE - if (utf) - { - length = 1; - ecode++; - GETCHARLEN(fc, ecode, length); - - /* If the pattern character's value is < 128, we have only one byte, and - we know that its other case must also be one byte long, so we can use the - fast lookup table. We know that there is at least one byte left in the - subject. */ - - if (fc < 128) - { - uint32_t cc = UCHAR21(eptr); - if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH); - ecode++; - eptr++; - } - - /* Otherwise we must pick up the subject character. Note that we cannot - use the value of "length" to check for sufficient bytes left, because the - other case of the character may have more or fewer bytes. */ - - else - { - uint32_t dc; - GETCHARINC(dc, eptr); - ecode += length; - - /* If we have Unicode property support, we can use it to test the other - case of the character, if there is one. */ - - if (fc != dc) - { -#ifdef SUPPORT_UNICODE - if (dc != UCD_OTHERCASE(fc)) -#endif - RRETURN(MATCH_NOMATCH); - } - } - } - else -#endif /* SUPPORT_UNICODE */ - - /* Not UTF mode */ - { - if (TABLE_GET(ecode[1], mb->lcc, ecode[1]) - != TABLE_GET(*eptr, mb->lcc, *eptr)) RRETURN(MATCH_NOMATCH); - eptr++; - ecode += 2; - } - break; - - /* Match a single character repeatedly. */ - - case OP_EXACT: - case OP_EXACTI: - min = max = GET2(ecode, 1); - ecode += 1 + IMM2_SIZE; - goto REPEATCHAR; - - case OP_POSUPTO: - case OP_POSUPTOI: - possessive = TRUE; - /* Fall through */ - - case OP_UPTO: - case OP_UPTOI: - case OP_MINUPTO: - case OP_MINUPTOI: - min = 0; - max = GET2(ecode, 1); - minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; - ecode += 1 + IMM2_SIZE; - goto REPEATCHAR; - - case OP_POSSTAR: - case OP_POSSTARI: - possessive = TRUE; - min = 0; - max = INT_MAX; - ecode++; - goto REPEATCHAR; - - case OP_POSPLUS: - case OP_POSPLUSI: - possessive = TRUE; - min = 1; - max = INT_MAX; - ecode++; - goto REPEATCHAR; - - case OP_POSQUERY: - case OP_POSQUERYI: - possessive = TRUE; - min = 0; - max = 1; - ecode++; - goto REPEATCHAR; - - case OP_STAR: - case OP_STARI: - case OP_MINSTAR: - case OP_MINSTARI: - case OP_PLUS: - case OP_PLUSI: - case OP_MINPLUS: - case OP_MINPLUSI: - case OP_QUERY: - case OP_QUERYI: - case OP_MINQUERY: - case OP_MINQUERYI: - c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI); - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - - /* Common code for all repeated single-character matches. We first check - for the minimum number of characters. If the minimum equals the maximum, we - are done. Otherwise, if minimizing, check the rest of the pattern for a - match; if there isn't one, advance up to the maximum, one character at a - time. - - If maximizing, advance up to the maximum number of matching characters, - until eptr is past the end of the maximum run. If possessive, we are - then done (no backing up). Otherwise, match at this position; anything - other than no match is immediately returned. For nomatch, back up one - character, unless we are matching \R and the last thing matched was - \r\n, in which case, back up two bytes. When we reach the first optional - character position, we can save stack by doing a tail recurse. - - The various UTF/non-UTF and caseful/caseless cases are handled separately, - for speed. */ - - REPEATCHAR: -#ifdef SUPPORT_UNICODE - if (utf) - { - length = 1; - charptr = ecode; - GETCHARLEN(fc, ecode, length); - ecode += length; - - /* Handle multibyte character matching specially here. There is - support for caseless matching if UCP support is present. */ - - if (length > 1) - { - uint32_t othercase; - if (op >= OP_STARI && /* Caseless */ - (othercase = UCD_OTHERCASE(fc)) != fc) - oclength = PRIV(ord2utf)(othercase, occhars); - else oclength = 0; - - for (i = 1; i <= min; i++) - { - if (eptr <= mb->end_subject - length && - memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; - else if (oclength > 0 && - eptr <= mb->end_subject - oclength && - memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; - else - { - CHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - } - - if (min == max) continue; - - if (minimize) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM22); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr <= mb->end_subject - length && - memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; - else if (oclength > 0 && - eptr <= mb->end_subject - oclength && - memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; - else - { - CHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - } - /* Control never gets here */ - } - - else /* Maximize */ - { - pp = eptr; - for (i = min; i < max; i++) - { - if (eptr <= mb->end_subject - length && - memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length; - else if (oclength > 0 && - eptr <= mb->end_subject - oclength && - memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength; - else - { - CHECK_PARTIAL(); - break; - } - } - - if (possessive) continue; /* No backtracking */ - - /* After \C in UTF mode, pp might be in the middle of a Unicode - character. Use <= pp to ensure backtracking doesn't go too far. */ - - for(;;) - { - if (eptr <= pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM23); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - BACKCHAR(eptr); - } - } - /* Control never gets here */ - } - - /* If the length of a UTF-8 character is 1, we fall through here, and - obey the code as for non-UTF-8 characters below, though in this case the - value of fc will always be < 128. */ - } - else -#endif /* SUPPORT_UNICODE */ - - /* When not in UTF-8 mode, load a single-byte character. */ - fc = *ecode++; - - /* The value of fc at this point is always one character, though we may - or may not be in UTF mode. The code is duplicated for the caseless and - caseful cases, for speed, since matching characters is likely to be quite - common. First, ensure the minimum number of matches are present. If min = - max, continue at the same level without recursing. Otherwise, if - minimizing, keep trying the rest of the expression and advancing one - matching character if failing, up to the maximum. Alternatively, if - maximizing, find the maximum number of characters and work backwards. */ - - if (op >= OP_STARI) /* Caseless */ - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - /* fc must be < 128 if UTF is enabled. */ - foc = mb->fcc[fc]; -#else -#ifdef SUPPORT_UNICODE - if (utf && fc > 127) - foc = UCD_OTHERCASE(fc); - else -#endif /* SUPPORT_UNICODE */ - foc = TABLE_GET(fc, mb->fcc, fc); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - - for (i = 1; i <= min; i++) - { - uint32_t cc; /* Faster than PCRE2_UCHAR */ - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21TEST(eptr); - if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); - eptr++; - } - if (min == max) continue; - if (minimize) - { - for (fi = min;; fi++) - { - uint32_t cc; /* Faster than PCRE2_UCHAR */ - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM24); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21TEST(eptr); - if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); - eptr++; - } - /* Control never gets here */ - } - else /* Maximize */ - { - pp = eptr; - for (i = min; i < max; i++) - { - uint32_t cc; /* Faster than PCRE2_UCHAR */ - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - cc = UCHAR21TEST(eptr); - if (fc != cc && foc != cc) break; - eptr++; - } - if (possessive) continue; /* No backtracking */ - for (;;) - { - if (eptr == pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM25); - eptr--; - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - } - /* Control never gets here */ - } - } - - /* Caseful comparisons (includes all multi-byte characters) */ - - else - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); - } - - if (min == max) continue; - - if (minimize) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM26); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - } - else /* Maximize */ - { - pp = eptr; - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (fc != UCHAR21TEST(eptr)) break; - eptr++; - } - if (possessive) continue; /* No backtracking */ - for (;;) - { - if (eptr == pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM27); - eptr--; - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - } - /* Control never gets here */ - } - } - /* Control never gets here */ - - /* Match a negated single one-byte character. The character we are - checking can be multibyte. */ - - case OP_NOT: - case OP_NOTI: - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t ch, och; - - ecode++; - GETCHARINC(ch, ecode); - GETCHARINC(c, eptr); - - if (op == OP_NOT) - { - if (ch == c) RRETURN(MATCH_NOMATCH); - } - else - { - if (ch > 127) - och = UCD_OTHERCASE(ch); - else - och = TABLE_GET(ch, mb->fcc, ch); - if (ch == c || och == c) RRETURN(MATCH_NOMATCH); - } - } - else -#endif /* SUPPORT_UNICODE */ - { - register uint32_t ch = ecode[1]; - c = *eptr++; - if (ch == c || (op == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == c)) - RRETURN(MATCH_NOMATCH); - ecode += 2; - } - break; - - /* Match a negated single one-byte character repeatedly. This is almost a - repeat of the code for a repeated single character, but I haven't found a - nice way of commoning these up that doesn't require a test of the - positive/negative option for each character match. Maybe that wouldn't add - very much to the time taken, but character matching *is* what this is all - about... */ - - case OP_NOTEXACT: - case OP_NOTEXACTI: - min = max = GET2(ecode, 1); - ecode += 1 + IMM2_SIZE; - goto REPEATNOTCHAR; - - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - min = 0; - max = GET2(ecode, 1); - minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; - ecode += 1 + IMM2_SIZE; - goto REPEATNOTCHAR; - - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - possessive = TRUE; - min = 0; - max = INT_MAX; - ecode++; - goto REPEATNOTCHAR; - - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - possessive = TRUE; - min = 1; - max = INT_MAX; - ecode++; - goto REPEATNOTCHAR; - - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - possessive = TRUE; - min = 0; - max = 1; - ecode++; - goto REPEATNOTCHAR; - - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - possessive = TRUE; - min = 0; - max = GET2(ecode, 1); - ecode += 1 + IMM2_SIZE; - goto REPEATNOTCHAR; - - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR); - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - - /* Common code for all repeated single-byte matches. */ - - REPEATNOTCHAR: - GETCHARINCTEST(fc, ecode); - - /* The code is duplicated for the caseless and caseful cases, for speed, - since matching characters is likely to be quite common. First, ensure the - minimum number of matches are present. If min = max, continue at the same - level without recursing. Otherwise, if minimizing, keep trying the rest of - the expression and advancing one matching character if failing, up to the - maximum. Alternatively, if maximizing, find the maximum number of - characters and work backwards. */ - - if (op >= OP_NOTSTARI) /* Caseless */ - { -#ifdef SUPPORT_UNICODE - if (utf && fc > 127) - foc = UCD_OTHERCASE(fc); - else -#endif /* SUPPORT_UNICODE */ - foc = TABLE_GET(fc, mb->fcc, fc); - -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(d, eptr); - if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH); - } - } - else -#endif /* SUPPORT_UNICODE */ - /* Not UTF mode */ - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); - eptr++; - } - } - - if (min == max) continue; - - if (minimize) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM28); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(d, eptr); - if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH); - } - } - else -#endif /*SUPPORT_UNICODE */ - /* Not UTF mode */ - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM29); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); - eptr++; - } - } - /* Control never gets here */ - } - - /* Maximize case */ - - else - { - pp = eptr; - -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(d, eptr, len); - if (fc == d || (uint32_t)foc == d) break; - eptr += len; - } - if (possessive) continue; /* No backtracking */ - - /* After \C in UTF mode, pp might be in the middle of a Unicode - character. Use <= pp to ensure backtracking doesn't go too far. */ - - for(;;) - { - if (eptr <= pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM30); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - BACKCHAR(eptr); - } - } - else -#endif /* SUPPORT_UNICODE */ - /* Not UTF mode */ - { - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (fc == *eptr || foc == *eptr) break; - eptr++; - } - if (possessive) continue; /* No backtracking */ - for (;;) - { - if (eptr == pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM31); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - } - } - /* Control never gets here */ - } - } - - /* Caseful comparisons */ - - else - { -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(d, eptr); - if (fc == d) RRETURN(MATCH_NOMATCH); - } - } - else -#endif - /* Not UTF mode */ - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc == *eptr++) RRETURN(MATCH_NOMATCH); - } - } - - if (min == max) continue; - - if (minimize) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM32); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(d, eptr); - if (fc == d) RRETURN(MATCH_NOMATCH); - } - } - else -#endif - /* Not UTF mode */ - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM33); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (fc == *eptr++) RRETURN(MATCH_NOMATCH); - } - } - /* Control never gets here */ - } - - /* Maximize case */ - - else - { - pp = eptr; - -#ifdef SUPPORT_UNICODE - if (utf) - { - register uint32_t d; - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(d, eptr, len); - if (fc == d) break; - eptr += len; - } - if (possessive) continue; /* No backtracking */ - - /* After \C in UTF mode, pp might be in the middle of a Unicode - character. Use <= pp to ensure backtracking doesn't go too far. */ - - for(;;) - { - if (eptr <= pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM34); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - BACKCHAR(eptr); - } - } - else -#endif - /* Not UTF mode */ - { - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (fc == *eptr) break; - eptr++; - } - if (possessive) continue; /* No backtracking */ - for (;;) - { - if (eptr == pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM35); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - } - } - /* Control never gets here */ - } - } - /* Control never gets here */ - - /* Match a single character type repeatedly; several different opcodes - share code. This is very similar to the code for single characters, but we - repeat it in the interests of efficiency. */ - - case OP_TYPEEXACT: - min = max = GET2(ecode, 1); - minimize = TRUE; - ecode += 1 + IMM2_SIZE; - goto REPEATTYPE; - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - min = 0; - max = GET2(ecode, 1); - minimize = *ecode == OP_TYPEMINUPTO; - ecode += 1 + IMM2_SIZE; - goto REPEATTYPE; - - case OP_TYPEPOSSTAR: - possessive = TRUE; - min = 0; - max = INT_MAX; - ecode++; - goto REPEATTYPE; - - case OP_TYPEPOSPLUS: - possessive = TRUE; - min = 1; - max = INT_MAX; - ecode++; - goto REPEATTYPE; - - case OP_TYPEPOSQUERY: - possessive = TRUE; - min = 0; - max = 1; - ecode++; - goto REPEATTYPE; - - case OP_TYPEPOSUPTO: - possessive = TRUE; - min = 0; - max = GET2(ecode, 1); - ecode += 1 + IMM2_SIZE; - goto REPEATTYPE; - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - c = *ecode++ - OP_TYPESTAR; - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - - /* Common code for all repeated single character type matches. Note that - in UTF-8 mode, '.' matches a character of any length, but for the other - character types, the valid characters are all one-byte long. */ - - REPEATTYPE: - ctype = *ecode++; /* Code for the character type */ - -#ifdef SUPPORT_UNICODE - if (ctype == OP_PROP || ctype == OP_NOTPROP) - { - prop_fail_result = ctype == OP_NOTPROP; - prop_type = *ecode++; - prop_value = *ecode++; - } - else prop_type = -1; -#endif - - /* First, ensure the minimum number of matches are present. Use inline - code for maximizing the speed, and do the type test once at the start - (i.e. keep it out of the loop). Separate the UTF-8 code completely as that - is tidier. Also separate the UCP code, which can be the same for both UTF-8 - and single-bytes. */ - - if (min > 0) - { -#ifdef SUPPORT_UNICODE - if (prop_type >= 0) - { - switch(prop_type) - { - case PT_ANY: - if (prop_fail_result) RRETURN(MATCH_NOMATCH); - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - } - break; - - case PT_LAMP: - for (i = 1; i <= min; i++) - { - int chartype; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - chartype = UCD_CHARTYPE(c); - if ((chartype == ucp_Lu || - chartype == ucp_Ll || - chartype == ucp_Lt) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - case PT_GC: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - case PT_PC: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - case PT_SC: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - case PT_ALNUM: - for (i = 1; i <= min; i++) - { - int category; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - category = UCD_CATEGORY(c); - if ((category == ucp_L || category == ucp_N) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - if (prop_fail_result) RRETURN(MATCH_NOMATCH); - break; - - default: - if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - break; - } - } - break; - - case PT_WORD: - for (i = 1; i <= min; i++) - { - int category; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - category = UCD_CATEGORY(c); - if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - case PT_CLIST: - for (i = 1; i <= min; i++) - { - const uint32_t *cp; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } - if (c == *cp++) - { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } - } - } - break; - - case PT_UCNC: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; - - /* This should not occur */ - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - } - - /* Match extended Unicode sequences. We will get here only if the - support is in the binary; otherwise a compile-time error occurs. */ - - else if (ctype == OP_EXTUNI) - { - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - else - { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < mb->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } - } - CHECK_PARTIAL(); - } - } - - else -#endif /* SUPPORT_UNICODE */ - -/* Handle all other cases when the coding is UTF-8 */ - -#ifdef SUPPORT_UNICODE - if (utf) switch(ctype) - { - case OP_ANY: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); - if (mb->partial != 0 && - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - UCHAR21(eptr) == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - break; - - case OP_ALLANY: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - break; - - case OP_ANYBYTE: - if (eptr > mb->end_subject - min) RRETURN(MATCH_NOMATCH); - eptr += min; - break; - - case OP_ANYNL: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - - case CHAR_CR: - if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; - break; - - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); - break; - } - } - break; - - case OP_NOT_HSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - switch(c) - { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ - default: break; - } - } - break; - - case OP_HSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - switch(c) - { - HSPACE_CASES: break; /* Byte and multibyte cases */ - default: RRETURN(MATCH_NOMATCH); - } - } - break; - - case OP_NOT_VSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - switch(c) - { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); - default: break; - } - } - break; - - case OP_VSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - switch(c) - { - VSPACE_CASES: break; - default: RRETURN(MATCH_NOMATCH); - } - } - break; - - case OP_NOT_DIGIT: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINC(c, eptr); - if (c < 128 && (mb->ctypes[c] & ctype_digit) != 0) - RRETURN(MATCH_NOMATCH); - } - break; - - case OP_DIGIT: - for (i = 1; i <= min; i++) - { - uint32_t cc; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21(eptr); - if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - /* No need to skip more bytes - we know it's a 1-byte character */ - } - break; - - case OP_NOT_WHITESPACE: - for (i = 1; i <= min; i++) - { - uint32_t cc; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21(eptr); - if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0) - RRETURN(MATCH_NOMATCH); - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - break; - - case OP_WHITESPACE: - for (i = 1; i <= min; i++) - { - uint32_t cc; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21(eptr); - if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - /* No need to skip more bytes - we know it's a 1-byte character */ - } - break; - - case OP_NOT_WORDCHAR: - for (i = 1; i <= min; i++) - { - uint32_t cc; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21(eptr); - if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0) - RRETURN(MATCH_NOMATCH); - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - break; - - case OP_WORDCHAR: - for (i = 1; i <= min; i++) - { - uint32_t cc; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - cc = UCHAR21(eptr); - if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - /* No need to skip more bytes - we know it's a 1-byte character */ - } - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } /* End switch(ctype) */ - - else -#endif /* SUPPORT_UNICODE */ - - /* Code for the non-UTF-8 case for minimum matching of operators other - than OP_PROP and OP_NOTPROP. */ - - switch(ctype) - { - case OP_ANY: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); - if (mb->partial != 0 && - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - *eptr == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - eptr++; - } - break; - - case OP_ALLANY: - if (eptr > mb->end_subject - min) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr += min; - break; - - case OP_ANYBYTE: - if (eptr > mb->end_subject - min) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - eptr += min; - break; - - case OP_ANYNL: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - switch(*eptr++) - { - default: RRETURN(MATCH_NOMATCH); - - case CHAR_CR: - if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++; - break; - - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#if PCRE2_CODE_UNIT_WIDTH != 8 - case 0x2028: - case 0x2029: -#endif - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); - break; - } - } - break; - - case OP_NOT_HSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - switch(*eptr++) - { - default: break; - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - RRETURN(MATCH_NOMATCH); - } - } - break; - - case OP_HSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - switch(*eptr++) - { - default: RRETURN(MATCH_NOMATCH); - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - break; - } - } - break; - - case OP_NOT_VSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - switch(*eptr++) - { - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - RRETURN(MATCH_NOMATCH); - default: break; - } - } - break; - - case OP_VSPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - switch(*eptr++) - { - default: RRETURN(MATCH_NOMATCH); - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - break; - } - } - break; - - case OP_NOT_DIGIT: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - case OP_DIGIT: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - case OP_NOT_WHITESPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - case OP_WHITESPACE: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - case OP_NOT_WORDCHAR: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - case OP_WORDCHAR: - for (i = 1; i <= min; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) - RRETURN(MATCH_NOMATCH); - eptr++; - } - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - } - - /* If min = max, continue at the same level without recursing */ - - if (min == max) continue; - - /* If minimizing, we have to test the rest of the pattern before each - subsequent match. Again, separate the UTF-8 case for speed, and also - separate the UCP cases. */ - - if (minimize) - { -#ifdef SUPPORT_UNICODE - if (prop_type >= 0) - { - switch(prop_type) - { - case PT_ANY: - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM36); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if (prop_fail_result) RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_LAMP: - for (fi = min;; fi++) - { - int chartype; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM37); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - chartype = UCD_CHARTYPE(c); - if ((chartype == ucp_Lu || - chartype == ucp_Ll || - chartype == ucp_Lt) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_GC: - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM38); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_PC: - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM39); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_SC: - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM40); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_ALNUM: - for (fi = min;; fi++) - { - int category; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM59); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - category = UCD_CATEGORY(c); - if ((category == ucp_L || category == ucp_N) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM61); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - if (prop_fail_result) RRETURN(MATCH_NOMATCH); - break; - - default: - if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - break; - } - } - /* Control never gets here */ - - case PT_WORD: - for (fi = min;; fi++) - { - int category; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM62); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - category = UCD_CATEGORY(c); - if ((category == ucp_L || - category == ucp_N || - c == CHAR_UNDERSCORE) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - case PT_CLIST: - for (fi = min;; fi++) - { - const uint32_t *cp; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM67); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } - if (c == *cp++) - { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } - } - } - /* Control never gets here */ - - case PT_UCNC: - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM60); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000) == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - - /* This should never occur */ - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - } - - /* Match extended Unicode sequences. We will get here only if the - support is in the binary; otherwise a compile-time error occurs. */ - - else if (ctype == OP_EXTUNI) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM41); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - else - { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < mb->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } - } - CHECK_PARTIAL(); - } - } - else -#endif /* SUPPORT_UNICODE */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM42); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (ctype == OP_ANY && IS_NEWLINE(eptr)) - RRETURN(MATCH_NOMATCH); - GETCHARINC(c, eptr); - switch(ctype) - { - case OP_ANY: /* This is the non-NL case */ - if (mb->partial != 0 && /* Take care with CRLF partial */ - eptr >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - break; - - case OP_ALLANY: - case OP_ANYBYTE: - break; - - case OP_ANYNL: - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; - break; - - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC - case 0x2028: - case 0x2029: -#endif /* Not EBCDIC */ - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); - break; - } - break; - - case OP_NOT_HSPACE: - switch(c) - { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); - default: break; - } - break; - - case OP_HSPACE: - switch(c) - { - HSPACE_CASES: break; - default: RRETURN(MATCH_NOMATCH); - } - break; - - case OP_NOT_VSPACE: - switch(c) - { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); - default: break; - } - break; - - case OP_VSPACE: - switch(c) - { - VSPACE_CASES: break; - default: RRETURN(MATCH_NOMATCH); - } - break; - - case OP_NOT_DIGIT: - if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) - RRETURN(MATCH_NOMATCH); - break; - - case OP_DIGIT: - if (c >= 256 || (mb->ctypes[c] & ctype_digit) == 0) - RRETURN(MATCH_NOMATCH); - break; - - case OP_NOT_WHITESPACE: - if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) - RRETURN(MATCH_NOMATCH); - break; - - case OP_WHITESPACE: - if (c >= 256 || (mb->ctypes[c] & ctype_space) == 0) - RRETURN(MATCH_NOMATCH); - break; - - case OP_NOT_WORDCHAR: - if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) - RRETURN(MATCH_NOMATCH); - break; - - case OP_WORDCHAR: - if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) - RRETURN(MATCH_NOMATCH); - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - } - } - else -#endif - /* Not UTF mode */ - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM43); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - if (ctype == OP_ANY && IS_NEWLINE(eptr)) - RRETURN(MATCH_NOMATCH); - c = *eptr++; - switch(ctype) - { - case OP_ANY: /* This is the non-NL case */ - if (mb->partial != 0 && /* Take care with CRLF partial */ - eptr >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - c == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - break; - - case OP_ALLANY: - case OP_ANYBYTE: - break; - - case OP_ANYNL: - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++; - break; - - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#if PCRE2_CODE_UNIT_WIDTH != 8 - case 0x2028: - case 0x2029: -#endif - if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH); - break; - } - break; - - case OP_NOT_HSPACE: - switch(c) - { - default: break; - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - RRETURN(MATCH_NOMATCH); - } - break; - - case OP_HSPACE: - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - break; - } - break; - - case OP_NOT_VSPACE: - switch(c) - { - default: break; - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - RRETURN(MATCH_NOMATCH); - } - break; - - case OP_VSPACE: - switch(c) - { - default: RRETURN(MATCH_NOMATCH); - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - break; - } - break; - - case OP_NOT_DIGIT: - if (MAX_255(c) && (mb->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); - break; - - case OP_DIGIT: - if (!MAX_255(c) || (mb->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); - break; - - case OP_NOT_WHITESPACE: - if (MAX_255(c) && (mb->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); - break; - - case OP_WHITESPACE: - if (!MAX_255(c) || (mb->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); - break; - - case OP_NOT_WORDCHAR: - if (MAX_255(c) && (mb->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); - break; - - case OP_WORDCHAR: - if (!MAX_255(c) || (mb->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - } - } - /* Control never gets here */ - } - - /* If maximizing, it is worth using inline code for speed, doing the type - test once at the start (i.e. keep it out of the loop). Again, keep the - UTF-8 and UCP stuff separate. */ - - else - { - pp = eptr; /* Remember where we started */ - -#ifdef SUPPORT_UNICODE - if (prop_type >= 0) - { - switch(prop_type) - { - case PT_ANY: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if (prop_fail_result) break; - eptr+= len; - } - break; - - case PT_LAMP: - for (i = min; i < max; i++) - { - int chartype; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - chartype = UCD_CHARTYPE(c); - if ((chartype == ucp_Lu || - chartype == ucp_Ll || - chartype == ucp_Lt) == prop_fail_result) - break; - eptr+= len; - } - break; - - case PT_GC: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; - eptr+= len; - } - break; - - case PT_PC: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; - eptr+= len; - } - break; - - case PT_SC: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; - eptr+= len; - } - break; - - case PT_ALNUM: - for (i = min; i < max; i++) - { - int category; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - category = UCD_CATEGORY(c); - if ((category == ucp_L || category == ucp_N) == prop_fail_result) - break; - eptr+= len; - } - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - if (prop_fail_result) goto ENDLOOP99; /* Break the loop */ - break; - - default: - if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) - goto ENDLOOP99; /* Break the loop */ - break; - } - eptr+= len; - } - ENDLOOP99: - break; - - case PT_WORD: - for (i = min; i < max; i++) - { - int category; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - category = UCD_CATEGORY(c); - if ((category == ucp_L || category == ucp_N || - c == CHAR_UNDERSCORE) == prop_fail_result) - break; - eptr+= len; - } - break; - - case PT_CLIST: - for (i = min; i < max; i++) - { - const uint32_t *cp; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else goto GOT_MAX; } - if (c == *cp++) - { if (prop_fail_result) goto GOT_MAX; else break; } - } - eptr += len; - } - GOT_MAX: - break; - - case PT_UCNC: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || - c >= 0xe000) == prop_fail_result) - break; - eptr += len; - } - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - - /* eptr is now past the end of the maximum run */ - - if (possessive) continue; /* No backtracking */ - - /* After \C in UTF mode, pp might be in the middle of a Unicode - character. Use <= pp to ensure backtracking doesn't go too far. */ - - for(;;) - { - if (eptr <= pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM44); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - if (utf) BACKCHAR(eptr); - } - } - - /* Match extended Unicode grapheme clusters. We will get here only if the - support is in the binary; otherwise a compile-time error occurs. */ - - else if (ctype == OP_EXTUNI) - { - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - else - { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < mb->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } - } - CHECK_PARTIAL(); - } - - /* eptr is now past the end of the maximum run */ - - if (possessive) continue; /* No backtracking */ - - /* We use <= pp rather than == pp to detect the start of the run while - backtracking because the use of \C in UTF mode can cause BACKCHAR to - move back past pp. This is just palliative; the use of \C in UTF mode - is fraught with danger. */ - - for(;;) - { - int lgb, rgb; - PCRE2_SPTR fptr; - - if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */ - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM45); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - - /* Backtracking over an extended grapheme cluster involves inspecting - the previous two characters (if present) to see if a break is - permitted between them. */ - - eptr--; - if (!utf) c = *eptr; else - { - BACKCHAR(eptr); - GETCHAR(c, eptr); - } - rgb = UCD_GRAPHBREAK(c); - - for (;;) - { - if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */ - fptr = eptr - 1; - if (!utf) c = *fptr; else - { - BACKCHAR(fptr); - GETCHAR(c, fptr); - } - lgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - eptr = fptr; - rgb = lgb; - } - } - } - - else -#endif /* SUPPORT_UNICODE */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - switch(ctype) - { - case OP_ANY: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (IS_NEWLINE(eptr)) break; - if (mb->partial != 0 && /* Take care with CRLF partial */ - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - UCHAR21(eptr) == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - break; - - case OP_ALLANY: - if (max < INT_MAX) - { - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - eptr++; - ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++); - } - } - else - { - eptr = mb->end_subject; /* Unlimited UTF-8 repeat */ - SCHECK_PARTIAL(); - } - break; - - /* The byte case is the same as non-UTF8 */ - - case OP_ANYBYTE: - c = max - min; - if (c > (uint32_t)(mb->end_subject - eptr)) - { - eptr = mb->end_subject; - SCHECK_PARTIAL(); - } - else eptr += c; - break; - - case OP_ANYNL: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c == CHAR_CR) - { - if (++eptr >= mb->end_subject) break; - if (UCHAR21(eptr) == CHAR_LF) eptr++; - } - else - { - if (c != CHAR_LF && - (mb->bsr_convention == PCRE2_BSR_ANYCRLF || - (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL -#ifndef EBCDIC - && c != 0x2028 && c != 0x2029 -#endif /* Not EBCDIC */ - ))) - break; - eptr += len; - } - } - break; - - case OP_NOT_HSPACE: - case OP_HSPACE: - for (i = min; i < max; i++) - { - BOOL gotspace; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - switch(c) - { - HSPACE_CASES: gotspace = TRUE; break; - default: gotspace = FALSE; break; - } - if (gotspace == (ctype == OP_NOT_HSPACE)) break; - eptr += len; - } - break; - - case OP_NOT_VSPACE: - case OP_VSPACE: - for (i = min; i < max; i++) - { - BOOL gotspace; - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - switch(c) - { - VSPACE_CASES: gotspace = TRUE; break; - default: gotspace = FALSE; break; - } - if (gotspace == (ctype == OP_NOT_VSPACE)) break; - eptr += len; - } - break; - - case OP_NOT_DIGIT: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) break; - eptr+= len; - } - break; - - case OP_DIGIT: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c >= 256 ||(mb->ctypes[c] & ctype_digit) == 0) break; - eptr+= len; - } - break; - - case OP_NOT_WHITESPACE: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) break; - eptr+= len; - } - break; - - case OP_WHITESPACE: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c >= 256 ||(mb->ctypes[c] & ctype_space) == 0) break; - eptr+= len; - } - break; - - case OP_NOT_WORDCHAR: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) break; - eptr+= len; - } - break; - - case OP_WORDCHAR: - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLEN(c, eptr, len); - if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) break; - eptr+= len; - } - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - - if (possessive) continue; /* No backtracking */ - - /* After \C in UTF mode, pp might be in the middle of a Unicode - character. Use <= pp to ensure backtracking doesn't go too far. */ - - for(;;) - { - if (eptr <= pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM46); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - BACKCHAR(eptr); - if (ctype == OP_ANYNL && eptr > pp && UCHAR21(eptr) == CHAR_NL && - UCHAR21(eptr - 1) == CHAR_CR) eptr--; - } - } - else -#endif /* SUPPORT_UNICODE */ - /* Not UTF mode */ - { - switch(ctype) - { - case OP_ANY: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (IS_NEWLINE(eptr)) break; - if (mb->partial != 0 && /* Take care with CRLF partial */ - eptr + 1 >= mb->end_subject && - NLBLOCK->nltype == NLTYPE_FIXED && - NLBLOCK->nllen == 2 && - *eptr == NLBLOCK->nl[0]) - { - mb->hitend = TRUE; - if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); - } - eptr++; - } - break; - - case OP_ALLANY: - case OP_ANYBYTE: - c = max - min; - if (c > (uint32_t)(mb->end_subject - eptr)) - { - eptr = mb->end_subject; - SCHECK_PARTIAL(); - } - else eptr += c; - break; - - case OP_ANYNL: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - c = *eptr; - if (c == CHAR_CR) - { - if (++eptr >= mb->end_subject) break; - if (*eptr == CHAR_LF) eptr++; - } - else - { - if (c != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF || - (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL -#if PCRE2_CODE_UNIT_WIDTH != 8 - && c != 0x2028 && c != 0x2029 -#endif - ))) break; - eptr++; - } - } - break; - - case OP_NOT_HSPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - switch(*eptr) - { - default: eptr++; break; - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - goto ENDLOOP00; - } - } - ENDLOOP00: - break; - - case OP_HSPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - switch(*eptr) - { - default: goto ENDLOOP01; - HSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - HSPACE_MULTIBYTE_CASES: -#endif - eptr++; break; - } - } - ENDLOOP01: - break; - - case OP_NOT_VSPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - switch(*eptr) - { - default: eptr++; break; - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - goto ENDLOOP02; - } - } - ENDLOOP02: - break; - - case OP_VSPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - switch(*eptr) - { - default: goto ENDLOOP03; - VSPACE_BYTE_CASES: -#if PCRE2_CODE_UNIT_WIDTH != 8 - VSPACE_MULTIBYTE_CASES: -#endif - eptr++; break; - } - } - ENDLOOP03: - break; - - case OP_NOT_DIGIT: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) break; - eptr++; - } - break; - - case OP_DIGIT: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) break; - eptr++; - } - break; - - case OP_NOT_WHITESPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) break; - eptr++; - } - break; - - case OP_WHITESPACE: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) break; - eptr++; - } - break; - - case OP_NOT_WORDCHAR: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) break; - eptr++; - } - break; - - case OP_WORDCHAR: - for (i = min; i < max; i++) - { - if (eptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) break; - eptr++; - } - break; - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - - if (possessive) continue; /* No backtracking */ - for (;;) - { - if (eptr == pp) goto TAIL_RECURSE; - RMATCH(eptr, ecode, offset_top, mb, eptrb, RM47); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr--; - if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF && - eptr[-1] == CHAR_CR) eptr--; - } - } - - /* Control never gets here */ - } - - /* There's been some horrible disaster. Arrival here can only mean there is - something seriously wrong in the code above or the OP_xxx definitions. */ - - default: - RRETURN(PCRE2_ERROR_INTERNAL); - } - - /* Do not stick any code in here without much thought; it is assumed - that "continue" in the code above comes out to here to repeat the main - loop. */ - - } /* End of main loop */ -/* Control never reaches here */ - - -/* When compiling to use the heap rather than the stack for recursive calls to -match(), the RRETURN() macro jumps here. The number that is saved in -frame->Xwhere indicates which label we actually want to return to. */ - -#ifdef HEAP_MATCH_RECURSE -#define LBL(val) case val: goto L_RM##val; -HEAP_RETURN: -switch (frame->Xwhere) - { - LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8) - LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) - LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) - LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) - LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) - LBL(65) LBL(66) LBL(68) -#ifdef SUPPORT_WIDE_CHARS - LBL(20) LBL(21) -#endif -#ifdef SUPPORT_UNICODE - LBL(16) LBL(18) - LBL(22) LBL(23) LBL(28) LBL(30) - LBL(32) LBL(34) LBL(42) LBL(46) - LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) - LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) -#endif /* SUPPORT_UNICODE */ - default: - return PCRE2_ERROR_INTERNAL; - } -#undef LBL -#endif /* HEAP_MATCH_RECURSE */ -} - - -/*************************************************************************** -**************************************************************************** - RECURSION IN THE match() FUNCTION - -Undefine all the macros that were defined above to handle this. */ - -#ifdef HEAP_MATCH_RECURSE -#undef eptr -#undef ecode -#undef mstart -#undef offset_top -#undef eptrb -#undef flags - -#undef callpat -#undef charptr -#undef data -#undef next_ecode -#undef pp -#undef prev -#undef saved_eptr - -#undef new_recursive - -#undef cur_is_word -#undef condition -#undef prev_is_word - -#undef ctype -#undef length -#undef max -#undef min -#undef number -#undef offset -#undef op -#undef save_capture_last -#undef save_offset1 -#undef save_offset2 -#undef save_offset3 - -#undef newptrb -#endif /* HEAP_MATCH_RECURSE */ - -/* These two are defined as macros in both cases */ - -#undef fc -#undef fi - -/*************************************************************************** -***************************************************************************/ - - -#ifdef HEAP_MATCH_RECURSE -/************************************************* -* Release allocated heap frames * -*************************************************/ - -/* This function releases all the allocated frames. The base frame is on the -machine stack, and so must not be freed. - -Argument: - frame_base the address of the base frame - mb the match block - -Returns: nothing -*/ - -static void -release_match_heapframes (heapframe *frame_base, match_block *mb) -{ -heapframe *nextframe = frame_base->Xnextframe; -while (nextframe != NULL) - { - heapframe *oldframe = nextframe; - nextframe = nextframe->Xnextframe; - mb->stack_memctl.free(oldframe, mb->stack_memctl.memory_data); - } -} -#endif /* HEAP_MATCH_RECURSE */ - - - -/************************************************* -* Match a Regular Expression * -*************************************************/ - -/* This function applies a compiled pattern to a subject string and picks out -portions of the string if it matches. Two elements in the vector are set for -each substring: the offsets to the start and end of the substring. - -Arguments: - code points to the compiled expression - subject points to the subject string - length length of subject string (may contain binary zeros) - start_offset where to start in the subject string - options option bits - match_data points to a match_data block - mcontext points a PCRE2 context - -Returns: > 0 => success; value is the number of ovector pairs filled - = 0 => success, but ovector is not big enough - -1 => failed to match (PCRE2_ERROR_NOMATCH) - -2 => partial match (PCRE2_ERROR_PARTIAL) - < -2 => some kind of unexpected problem -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, - PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, - pcre2_match_context *mcontext) -{ -int rc; -int ocount; - -const uint8_t *start_bits = NULL; - -const pcre2_real_code *re = (const pcre2_real_code *)code; - -BOOL anchored; -BOOL firstline; -BOOL has_first_cu = FALSE; -BOOL has_req_cu = FALSE; -BOOL startline; -BOOL using_temporary_offsets = FALSE; -BOOL utf; - -PCRE2_UCHAR first_cu = 0; -PCRE2_UCHAR first_cu2 = 0; -PCRE2_UCHAR req_cu = 0; -PCRE2_UCHAR req_cu2 = 0; - -PCRE2_SPTR bumpalong_limit; -PCRE2_SPTR end_subject; -PCRE2_SPTR start_match = subject + start_offset; -PCRE2_SPTR req_cu_ptr = start_match - 1; -PCRE2_SPTR start_partial = NULL; -PCRE2_SPTR match_partial = NULL; - -/* We need to have mb pointing to a match block, because the IS_NEWLINE macro -is used below, and it expects NLBLOCK to be defined as a pointer. */ - -match_block actual_match_block; -match_block *mb = &actual_match_block; - -#ifdef HEAP_MATCH_RECURSE -heapframe frame_zero; -frame_zero.Xprevframe = NULL; /* Marks the top level */ -frame_zero.Xnextframe = NULL; /* None are allocated yet */ -mb->match_frames_base = &frame_zero; -#endif - -/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated -subject string. */ - -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); -end_subject = subject + length; - -/* Plausibility checks */ - -if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION; -if (code == NULL || subject == NULL || match_data == NULL) - return PCRE2_ERROR_NULL; -if (start_offset > length) return PCRE2_ERROR_BADOFFSET; - -/* Check that the first field in the block is the magic number. */ - -if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; - -/* Check the code unit width. */ - -if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) - return PCRE2_ERROR_BADMODE; - -/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the -options variable for this function. Users of PCRE2 who are not calling the -function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with -constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and -(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be -transferred to the options for this function. The bits are guaranteed to be -adjacent, but do not have the same values. This bit of Boolean trickery assumes -that the match-time bits are not more significant than the flag bits. If by -accident this is not the case, a compile-time division by zero error will -occur. */ - -#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET) -#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART) -options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1))); -#undef FF -#undef OO - -/* A NULL match context means "use a default context" */ - -if (mcontext == NULL) - mcontext = (pcre2_match_context *)(&PRIV(default_match_context)); - -/* These two settings are used in the code for checking a UTF string that -follows immediately afterwards. Other values in the mb block are used only -during interpretive pcre_match() processing, not when the JIT support is in -use, so they are set up later. */ - -utf = (re->overall_options & PCRE2_UTF) != 0; -mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 : - ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0; - -/* Check a UTF string for validity if required. For 8-bit and 16-bit strings, -we must also check that a starting offset does not point into the middle of a -multiunit character. We check only the portion of the subject that is going to -be inspected during matching - from the offset minus the maximum back reference -to the given length. This saves time when a small part of a large subject is -being matched by the use of a starting offset. Note that the maximum lookbehind -is a number of characters, not code units. */ - -#ifdef SUPPORT_UNICODE -if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) - { - PCRE2_SPTR check_subject = start_match; /* start_match includes offset */ - - if (start_offset > 0) - { -#if PCRE2_CODE_UNIT_WIDTH != 32 - unsigned int i; - if (start_match < end_subject && NOT_FIRSTCU(*start_match)) - return PCRE2_ERROR_BADUTFOFFSET; - for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--) - { - check_subject--; - while (check_subject > subject && -#if PCRE2_CODE_UNIT_WIDTH == 8 - (*check_subject & 0xc0) == 0x80) -#else /* 16-bit */ - (*check_subject & 0xfc00) == 0xdc00) -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - check_subject--; - } -#else - /* In the 32-bit library, one code unit equals one character. However, - we cannot just subtract the lookbehind and then compare pointers, because - a very large lookbehind could create an invalid pointer. */ - - if (start_offset >= re->max_lookbehind) - check_subject -= re->max_lookbehind; - else - check_subject = subject; -#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - } - - /* Validate the relevant portion of the subject. After an error, adjust the - offset to be an absolute offset in the whole string. */ - - match_data->rc = PRIV(valid_utf)(check_subject, - length - (check_subject - subject), &(match_data->startchar)); - if (match_data->rc != 0) - { - match_data->startchar += check_subject - subject; - return match_data->rc; - } - } -#endif /* SUPPORT_UNICODE */ - -/* It is an error to set an offset limit without setting the flag at compile -time. */ - -if (mcontext->offset_limit != PCRE2_UNSET && - (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) - return PCRE2_ERROR_BADOFFSETLIMIT; - -/* If the pattern was successfully studied with JIT support, run the JIT -executable instead of the rest of this function. Most options must be set at -compile time for the JIT code to be usable. Fallback to the normal code path if -an unsupported option is set or if JIT returns BADOPTION (which means that the -selected normal or partial matching mode was not compiled). */ - -#ifdef SUPPORT_JIT -if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0) - { - rc = pcre2_jit_match(code, subject, length, start_offset, options, - match_data, mcontext); - if (rc != PCRE2_ERROR_JIT_BADOPTION) return rc; - } -#endif - -/* Carry on with non-JIT matching. */ - -anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; -startline = (re->flags & PCRE2_STARTLINE) != 0; -bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? - end_subject : subject + mcontext->offset_limit; - -/* Fill in the fields in the match block. */ - -mb->callout = mcontext->callout; -mb->callout_data = mcontext->callout_data; -mb->memctl = mcontext->memctl; -#ifdef HEAP_MATCH_RECURSE -mb->stack_memctl = mcontext->stack_memctl; -#endif - -mb->start_subject = subject; -mb->start_offset = start_offset; -mb->end_subject = end_subject; -mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0; - -mb->moptions = options; /* Match options */ -mb->poptions = re->overall_options; /* Pattern options */ - -mb->ignore_skip_arg = 0; -mb->mark = mb->nomatch_mark = NULL; /* In case never set */ -mb->recursive = NULL; /* No recursion at top level */ -mb->ovecsave_chain = NULL; /* No ovecsave blocks yet */ -mb->hitend = FALSE; - -/* The name table is needed for finding all the numbers associated with a -given name, for condition testing. The code follows the name table. */ - -mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); -mb->name_count = re->name_count; -mb->name_entry_size = re->name_entry_size; -mb->start_code = mb->name_table + re->name_count * re->name_entry_size; - -/* Limits set in the pattern override the match context only if they are -smaller. */ - -mb->match_limit = (mcontext->match_limit < re->limit_match)? - mcontext->match_limit : re->limit_match; -mb->match_limit_recursion = (mcontext->recursion_limit < re->limit_recursion)? - mcontext->recursion_limit : re->limit_recursion; - -/* Pointers to the individual character tables */ - -mb->lcc = re->tables + lcc_offset; -mb->fcc = re->tables + fcc_offset; -mb->ctypes = re->tables + ctypes_offset; - -/* Process the \R and newline settings. */ - -mb->bsr_convention = re->bsr_convention; -mb->nltype = NLTYPE_FIXED; -switch(re->newline_convention) - { - case PCRE2_NEWLINE_CR: - mb->nllen = 1; - mb->nl[0] = CHAR_CR; - break; - - case PCRE2_NEWLINE_LF: - mb->nllen = 1; - mb->nl[0] = CHAR_NL; - break; - - case PCRE2_NEWLINE_CRLF: - mb->nllen = 2; - mb->nl[0] = CHAR_CR; - mb->nl[1] = CHAR_NL; - break; - - case PCRE2_NEWLINE_ANY: - mb->nltype = NLTYPE_ANY; - break; - - case PCRE2_NEWLINE_ANYCRLF: - mb->nltype = NLTYPE_ANYCRLF; - break; - - default: return PCRE2_ERROR_INTERNAL; - } - -/* If the expression has got more back references than the offsets supplied can -hold, we get a temporary chunk of memory to use during the matching. Otherwise, -we can use the vector supplied. The size of the ovector is three times the -value in the oveccount field. Two-thirds of it is pairs for storing matching -offsets, and the top third is working space. */ - -if (re->top_backref >= match_data->oveccount) - { - ocount = re->top_backref * 3 + 3; - mb->ovector = (PCRE2_SIZE *)(mb->memctl.malloc(ocount * sizeof(PCRE2_SIZE), - mb->memctl.memory_data)); - if (mb->ovector == NULL) return PCRE2_ERROR_NOMEMORY; - using_temporary_offsets = TRUE; - } -else - { - ocount = 3 * match_data->oveccount; - mb->ovector = match_data->ovector; - } - -mb->offset_end = ocount; -mb->offset_max = (2*ocount)/3; - -/* Reset the working variable associated with each extraction. These should -never be used unless previously set, but they get saved and restored, and so we -initialize them to avoid reading uninitialized locations. Also, unset the -offsets for the matched string. This is really just for tidiness with callouts, -in case they inspect these fields. */ - -if (ocount > 0) - { - register PCRE2_SIZE *iptr = mb->ovector + ocount; - register PCRE2_SIZE *iend = iptr - re->top_bracket; - if (iend < mb->ovector + 2) iend = mb->ovector + 2; - while (--iptr >= iend) *iptr = PCRE2_UNSET; - mb->ovector[0] = mb->ovector[1] = PCRE2_UNSET; - } - -/* Set up the first code unit to match, if available. The first_codeunit value -is never set for an anchored regular expression, but the anchoring may be -forced at run time, so we have to test for anchoring. The first code unit may -be unset for an unanchored pattern, of course. If there's no first code unit -there may be a bitmap of possible first characters. */ - -if (!anchored) - { - if ((re->flags & PCRE2_FIRSTSET) != 0) - { - has_first_cu = TRUE; - first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit); - if ((re->flags & PCRE2_FIRSTCASELESS) != 0) - { - first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); -#endif - } - } - else - if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0) - start_bits = re->start_bitmap; - } - -/* For anchored or unanchored matches, there may be a "last known required -character" set. */ - -if ((re->flags & PCRE2_LASTSET) != 0) - { - has_req_cu = TRUE; - req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit); - if ((re->flags & PCRE2_LASTCASELESS) != 0) - { - req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); -#endif - } - } - - -/* ==========================================================================*/ - -/* Loop for handling unanchored repeated matching attempts; for anchored regexs -the loop runs just once. */ - -for(;;) - { - PCRE2_SPTR new_start_match; - mb->capture_last = 0; - - /* ----------------- Start of match optimizations ---------------- */ - - /* There are some optimizations that avoid running the match if a known - starting point is not found, or if a known later code unit is not present. - However, there is an option (settable at compile time) that disables these, - for testing and for ensuring that all callouts do actually occur. */ - - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - PCRE2_SPTR save_end_subject = end_subject; - - /* If firstline is TRUE, the start of the match is constrained to the first - line of a multiline string. That is, the match must be before or at the - first newline. Implement this by temporarily adjusting end_subject so that - we stop the optimization scans at a newline. If the match fails at the - newline, later code breaks this loop. */ - - if (firstline) - { - PCRE2_SPTR t = start_match; -#ifdef SUPPORT_UNICODE - if (utf) - { - while (t < mb->end_subject && !IS_NEWLINE(t)) - { - t++; - ACROSSCHAR(t < end_subject, *t, t++); - } - } - else -#endif - while (t < mb->end_subject && !IS_NEWLINE(t)) t++; - end_subject = t; - } - - /* Advance to a unique first code unit if there is one. In 8-bit mode, the - use of memchr() gives a big speed up. */ - - if (has_first_cu) - { - PCRE2_UCHAR smc; - if (first_cu != first_cu2) - while (start_match < end_subject && - (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) - start_match++; - else - { -#if PCRE2_CODE_UNIT_WIDTH != 8 - while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu) - start_match++; -#else - start_match = memchr(start_match, first_cu, end_subject - start_match); - if (start_match == NULL) start_match = end_subject; -#endif - } - } - - /* Or to just after a linebreak for a multiline match */ - - else if (startline) - { - if (start_match > mb->start_subject + start_offset) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - while (start_match < end_subject && !WAS_NEWLINE(start_match)) - { - start_match++; - ACROSSCHAR(start_match < end_subject, *start_match, - start_match++); - } - } - else -#endif - while (start_match < end_subject && !WAS_NEWLINE(start_match)) - start_match++; - - /* If we have just passed a CR and the newline option is ANY or - ANYCRLF, and we are now at a LF, advance the match position by one more - code unit. */ - - if (start_match[-1] == CHAR_CR && - (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) && - start_match < end_subject && - UCHAR21TEST(start_match) == CHAR_NL) - start_match++; - } - } - - /* Or to a non-unique first code unit if any have been identified. The - bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all - code units greater than 254 set the 255 bit. */ - - else if (start_bits != NULL) - { - while (start_match < end_subject) - { - register uint32_t c = UCHAR21TEST(start_match); -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) c = 255; -#endif - if ((start_bits[c/8] & (1 << (c&7))) != 0) break; - start_match++; - } - } - - /* Restore fudged end_subject */ - - end_subject = save_end_subject; - - /* The following two optimizations are disabled for partial matching. */ - - if (!mb->partial) - { - /* The minimum matching length is a lower bound; no actual string of that - length may actually match the pattern. Although the value is, strictly, - in characters, we treat it as code units to avoid spending too much time - in this optimization. */ - - if (end_subject - start_match < re->minlength) - { - rc = MATCH_NOMATCH; - break; - } - - /* If req_cu is set, we know that that code unit must appear in the - subject for the match to succeed. If the first code unit is set, req_cu - must be later in the subject; otherwise the test starts at the match - point. This optimization can save a huge amount of backtracking in - patterns with nested unlimited repeats that aren't going to match. - Writing separate code for cased/caseless versions makes it go faster, as - does using an autoincrement and backing off on a match. - - HOWEVER: when the subject string is very, very long, searching to its end - can take a long time, and give bad performance on quite ordinary - patterns. This showed up when somebody was matching something like - /^\d+C/ on a 32-megabyte string... so we don't do this when the string is - sufficiently long. */ - - if (has_req_cu && end_subject - start_match < REQ_CU_MAX) - { - register PCRE2_SPTR p = start_match + (has_first_cu? 1:0); - - /* We don't need to repeat the search if we haven't yet reached the - place we found it at last time. */ - - if (p > req_cu_ptr) - { - if (req_cu != req_cu2) - { - while (p < end_subject) - { - register uint32_t pp = UCHAR21INCTEST(p); - if (pp == req_cu || pp == req_cu2) { p--; break; } - } - } - else - { - while (p < end_subject) - { - if (UCHAR21INCTEST(p) == req_cu) { p--; break; } - } - } - - /* If we can't find the required code unit, break the matching loop, - forcing a match failure. */ - - if (p >= end_subject) - { - rc = MATCH_NOMATCH; - break; - } - - /* If we have found the required code unit, save the point where we - found it, so that we don't search again next time round the loop if - the start hasn't passed this code unit yet. */ - - req_cu_ptr = p; - } - } - } - } - - /* ------------ End of start of match optimizations ------------ */ - - /* Give no match if we have passed the bumpalong limit. */ - - if (start_match > bumpalong_limit) - { - rc = MATCH_NOMATCH; - break; - } - - /* OK, we can now run the match. If "hitend" is set afterwards, remember the - first starting point for which a partial match was found. */ - - mb->start_match_ptr = start_match; - mb->start_used_ptr = start_match; - mb->last_used_ptr = start_match; - mb->match_call_count = 0; - mb->match_function_type = 0; - mb->end_offset_top = 0; - mb->skip_arg_count = 0; - rc = match(start_match, mb->start_code, start_match, 2, mb, NULL, 0); - - if (mb->hitend && start_partial == NULL) - { - start_partial = mb->start_used_ptr; - match_partial = start_match; - } - - switch(rc) - { - /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched - the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP - entirely. The only way we can do that is to re-do the match at the same - point, with a flag to force SKIP with an argument to be ignored. Just - treating this case as NOMATCH does not work because it does not check other - alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */ - - case MATCH_SKIP_ARG: - new_start_match = start_match; - mb->ignore_skip_arg = mb->skip_arg_count; - break; - - /* SKIP passes back the next starting point explicitly, but if it is no - greater than the match we have just done, treat it as NOMATCH. */ - - case MATCH_SKIP: - if (mb->start_match_ptr > start_match) - { - new_start_match = mb->start_match_ptr; - break; - } - /* Fall through */ - - /* NOMATCH and PRUNE advance by one character. THEN at this level acts - exactly like PRUNE. Unset ignore SKIP-with-argument. */ - - case MATCH_NOMATCH: - case MATCH_PRUNE: - case MATCH_THEN: - mb->ignore_skip_arg = 0; - new_start_match = start_match + 1; -#ifdef SUPPORT_UNICODE - if (utf) - ACROSSCHAR(new_start_match < end_subject, *new_start_match, - new_start_match++); -#endif - break; - - /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */ - - case MATCH_COMMIT: - rc = MATCH_NOMATCH; - goto ENDLOOP; - - /* Any other return is either a match, or some kind of error. */ - - default: - goto ENDLOOP; - } - - /* Control reaches here for the various types of "no match at this point" - result. Reset the code to MATCH_NOMATCH for subsequent checking. */ - - rc = MATCH_NOMATCH; - - /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first - newline in the subject (though it may continue over the newline). Therefore, - if we have just failed to match, starting at a newline, do not continue. */ - - if (firstline && IS_NEWLINE(start_match)) break; - - /* Advance to new matching position */ - - start_match = new_start_match; - - /* Break the loop if the pattern is anchored or if we have passed the end of - the subject. */ - - if (anchored || start_match > end_subject) break; - - /* If we have just passed a CR and we are now at a LF, and the pattern does - not contain any explicit matches for \r or \n, and the newline option is CRLF - or ANY or ANYCRLF, advance the match position by one more code unit. In - normal matching start_match will aways be greater than the first position at - this stage, but a failed *SKIP can cause a return at the same point, which is - why the first test exists. */ - - if (start_match > subject + start_offset && - start_match[-1] == CHAR_CR && - start_match < end_subject && - *start_match == CHAR_NL && - (re->flags & PCRE2_HASCRORLF) == 0 && - (mb->nltype == NLTYPE_ANY || - mb->nltype == NLTYPE_ANYCRLF || - mb->nllen == 2)) - start_match++; - - mb->mark = NULL; /* Reset for start of next match attempt */ - } /* End of for(;;) "bumpalong" loop */ - -/* ==========================================================================*/ - -/* When we reach here, one of the stopping conditions is true: - -(1) The match succeeded, either completely, or partially; - -(2) The pattern is anchored or the match was failed by (*COMMIT); - -(3) We are past the end of the subject or the bumpalong limit; - -(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because - this option requests that a match occur at or before the first newline in - the subject. - -(5) Some kind of error occurred. - -*/ - -ENDLOOP: - -#ifdef HEAP_MATCH_RECURSE -release_match_heapframes(&frame_zero, mb); -#endif - -/* Release any frames that were saved from recursions. */ - -while (mb->ovecsave_chain != NULL) - { - ovecsave_frame *this = mb->ovecsave_chain; - mb->ovecsave_chain = this->next; - mb->memctl.free(this, mb->memctl.memory_data); - } - -/* Fill in fields that are always returned in the match data. */ - -match_data->code = re; -match_data->subject = subject; -match_data->mark = mb->mark; -match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER; - -/* Handle a fully successful match. */ - -if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) - { - uint32_t arg_offset_max = 2 * match_data->oveccount; - - /* When the offset vector is big enough to deal with any backreferences, - captured substring offsets will already be set up. In the case where we had - to get some local memory to hold offsets for backreference processing, copy - those that we can. In this case there need not be overflow if certain parts - of the pattern were not used, even though there are more capturing - parentheses than vector slots. */ - - if (using_temporary_offsets) - { - if (arg_offset_max >= 4) - { - memcpy(match_data->ovector + 2, mb->ovector + 2, - (arg_offset_max - 2) * sizeof(PCRE2_SIZE)); - } - if (mb->end_offset_top > arg_offset_max) mb->capture_last |= OVFLBIT; - mb->memctl.free(mb->ovector, mb->memctl.memory_data); - } - - /* Set the return code to the number of captured strings, or 0 if there were - too many to fit into the ovector. */ - - match_data->rc = ((mb->capture_last & OVFLBIT) != 0)? - 0 : mb->end_offset_top/2; - - /* If there is space in the offset vector, set any pairs that follow the - highest-numbered captured string but are less than the number of capturing - groups in the pattern (and are within the ovector) to PCRE2_UNSET. It is - documented that this happens. In earlier versions, the whole set of potential - capturing offsets was initialized each time round the loop, but this is - handled differently now. "Gaps" are set to PCRE2_UNSET dynamically instead - (this fixed a bug). Thus, it is only those at the end that need setting here. - We can't just mark them all unset at the start of the whole thing because - they may get set in one branch that is not the final matching branch. */ - - if (mb->end_offset_top/2 <= re->top_bracket) - { - register PCRE2_SIZE *iptr, *iend; - int resetcount = re->top_bracket + 1; - if (resetcount > match_data->oveccount) resetcount = match_data->oveccount; - iptr = match_data->ovector + mb->end_offset_top; - iend = match_data->ovector + 2 * resetcount; - while (iptr < iend) *iptr++ = PCRE2_UNSET; - } - - /* If there is space, set up the whole thing as substring 0. The value of - mb->start_match_ptr might be modified if \K was encountered on the success - matching path. */ - - if (match_data->oveccount < 1) rc = 0; else - { - match_data->ovector[0] = mb->start_match_ptr - mb->start_subject; - match_data->ovector[1] = mb->end_match_ptr - mb->start_subject; - } - - /* Set the remaining returned values */ - - match_data->startchar = start_match - subject; - match_data->leftchar = mb->start_used_ptr - subject; - match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)? - mb->last_used_ptr : mb->end_match_ptr) - subject; - return match_data->rc; - } - -/* Control gets here if there has been a partial match, an error, or if the -overall match attempt has failed at all permitted starting positions. Any mark -data is in the nomatch_mark field. */ - -match_data->mark = mb->nomatch_mark; - -/* For anything other than nomatch or partial match, just return the code. */ - -if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) - match_data->rc = rc; - -/* Else handle a partial match. */ - -else if (match_partial != NULL) - { - if (match_data->oveccount > 0) - { - match_data->ovector[0] = match_partial - subject; - match_data->ovector[1] = end_subject - subject; - } - match_data->startchar = match_partial - subject; - match_data->leftchar = start_partial - subject; - match_data->rightchar = end_subject - subject; - match_data->rc = PCRE2_ERROR_PARTIAL; - } - -/* Else this is the classic nomatch case. */ - -else match_data->rc = PCRE2_ERROR_NOMATCH; - -/* Free any temporary offsets. */ - -if (using_temporary_offsets) - mb->memctl.free(mb->ovector, mb->memctl.memory_data); -return match_data->rc; -} - -/* End of pcre2_match.c */ diff --git a/pcre2/src/pcre2_match_data.c b/pcre2/src/pcre2_match_data.c deleted file mode 100644 index 85ac99834..000000000 --- a/pcre2/src/pcre2_match_data.c +++ /dev/null @@ -1,147 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - - -/************************************************* -* Create a match data block given ovector size * -*************************************************/ - -/* A minimum of 1 is imposed on the number of ovector triplets. */ - -PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION -pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext) -{ -pcre2_match_data *yield; -if (oveccount < 1) oveccount = 1; -yield = PRIV(memctl_malloc)( - sizeof(pcre2_match_data) + 3*oveccount*sizeof(PCRE2_SIZE), - (pcre2_memctl *)gcontext); -if (yield == NULL) return NULL; -yield->oveccount = oveccount; -return yield; -} - - - -/************************************************* -* Create a match data block using pattern data * -*************************************************/ - -/* If no context is supplied, use the memory allocator from the code. */ - -PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION -pcre2_match_data_create_from_pattern(const pcre2_code *code, - pcre2_general_context *gcontext) -{ -if (gcontext == NULL) gcontext = (pcre2_general_context *)code; -return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1, - gcontext); -} - - - -/************************************************* -* Free a match data block * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_match_data_free(pcre2_match_data *match_data) -{ -if (match_data != NULL) - match_data->memctl.free(match_data, match_data->memctl.memory_data); -} - - - -/************************************************* -* Get last mark in match * -*************************************************/ - -PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION -pcre2_get_mark(pcre2_match_data *match_data) -{ -return match_data->mark; -} - - - -/************************************************* -* Get pointer to ovector * -*************************************************/ - -PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION -pcre2_get_ovector_pointer(pcre2_match_data *match_data) -{ -return match_data->ovector; -} - - - -/************************************************* -* Get number of ovector slots * -*************************************************/ - -PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION -pcre2_get_ovector_count(pcre2_match_data *match_data) -{ -return match_data->oveccount; -} - - - -/************************************************* -* Get starting code unit in match * -*************************************************/ - -PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION -pcre2_get_startchar(pcre2_match_data *match_data) -{ -return match_data->startchar; -} - -/* End of pcre2_match_data.c */ diff --git a/pcre2/src/pcre2_newline.c b/pcre2/src/pcre2_newline.c deleted file mode 100644 index 6e9366db9..000000000 --- a/pcre2/src/pcre2_newline.c +++ /dev/null @@ -1,243 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains internal functions for testing newlines when more than -one kind of newline is to be recognized. When a newline is found, its length is -returned. In principle, we could implement several newline "types", each -referring to a different set of newline characters. At present, PCRE2 supports -only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, -and NLTYPE_ANY. The full list of Unicode newline characters is taken from -http://unicode.org/unicode/reports/tr18/. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - - -/************************************************* -* Check for newline at given position * -*************************************************/ - -/* This function is called only via the IS_NEWLINE macro, which does so only -when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed -newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit -pointed to by ptr is less than the end of the string. - -Arguments: - ptr pointer to possible newline - type the newline type - endptr pointer to the end of the string - lenptr where to return the length - utf TRUE if in utf mode - -Returns: TRUE or FALSE -*/ - -BOOL -PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr, - uint32_t *lenptr, BOOL utf) -{ -uint32_t c; - -#ifdef SUPPORT_UNICODE -if (utf) { GETCHAR(c, ptr); } else c = *ptr; -#else -(void)utf; -c = *ptr; -#endif /* SUPPORT_UNICODE */ - -if (type == NLTYPE_ANYCRLF) switch(c) - { - case CHAR_LF: - *lenptr = 1; - return TRUE; - - case CHAR_CR: - *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; - return TRUE; - - default: - return FALSE; - } - -/* NLTYPE_ANY */ - -else switch(c) - { -#ifdef EBCDIC - case CHAR_NEL: -#endif - case CHAR_LF: - case CHAR_VT: - case CHAR_FF: - *lenptr = 1; - return TRUE; - - case CHAR_CR: - *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; - return TRUE; - -#ifndef EBCDIC -#if PCRE2_CODE_UNIT_WIDTH == 8 - case CHAR_NEL: - *lenptr = utf? 2 : 1; - return TRUE; - - case 0x2028: /* LS */ - case 0x2029: /* PS */ - *lenptr = 3; - return TRUE; - -#else /* 16-bit or 32-bit code units */ - case CHAR_NEL: - case 0x2028: /* LS */ - case 0x2029: /* PS */ - *lenptr = 1; - return TRUE; -#endif -#endif /* Not EBCDIC */ - - default: - return FALSE; - } -} - - - -/************************************************* -* Check for newline at previous position * -*************************************************/ - -/* This function is called only via the WAS_NEWLINE macro, which does so only -when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed -newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial -value of ptr is greater than the start of the string that is being processed. - -Arguments: - ptr pointer to possible newline - type the newline type - startptr pointer to the start of the string - lenptr where to return the length - utf TRUE if in utf mode - -Returns: TRUE or FALSE -*/ - -BOOL -PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr, - uint32_t *lenptr, BOOL utf) -{ -uint32_t c; -ptr--; - -#ifdef SUPPORT_UNICODE -if (utf) - { - BACKCHAR(ptr); - GETCHAR(c, ptr); - } -else c = *ptr; -#else -(void)utf; -c = *ptr; -#endif /* SUPPORT_UNICODE */ - -if (type == NLTYPE_ANYCRLF) switch(c) - { - case CHAR_LF: - *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; - return TRUE; - - case CHAR_CR: - *lenptr = 1; - return TRUE; - - default: - return FALSE; - } - -/* NLTYPE_ANY */ - -else switch(c) - { - case CHAR_LF: - *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; - return TRUE; - -#ifdef EBCDIC - case CHAR_NEL: -#endif - case CHAR_VT: - case CHAR_FF: - case CHAR_CR: - *lenptr = 1; - return TRUE; - -#ifndef EBCDIC -#if PCRE2_CODE_UNIT_WIDTH == 8 - case CHAR_NEL: - *lenptr = utf? 2 : 1; - return TRUE; - - case 0x2028: /* LS */ - case 0x2029: /* PS */ - *lenptr = 3; - return TRUE; - -#else /* 16-bit or 32-bit code units */ - case CHAR_NEL: - case 0x2028: /* LS */ - case 0x2029: /* PS */ - *lenptr = 1; - return TRUE; -#endif -#endif /* Not EBCDIC */ - - default: - return FALSE; - } -} - -/* End of pcre2_newline.c */ diff --git a/pcre2/src/pcre2_ord2utf.c b/pcre2/src/pcre2_ord2utf.c deleted file mode 100644 index 75252b763..000000000 --- a/pcre2/src/pcre2_ord2utf.c +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This file contains a function that converts a Unicode character code point -into a UTF string. The behaviour is different for each code unit width. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - -/* If SUPPORT_UNICODE is not defined, this function will never be called. -Supply a dummy function because some compilers do not like empty source -modules. */ - -#ifndef SUPPORT_UNICODE -unsigned int -PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) -{ -(void)(cvalue); -(void)(buffer); -return 0; -} -#else /* SUPPORT_UNICODE */ - - -/************************************************* -* Convert code point to UTF * -*************************************************/ - -/* -Arguments: - cvalue the character value - buffer pointer to buffer for result - -Returns: number of code units placed in the buffer -*/ - -unsigned int -PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer) -{ -/* Convert to UTF-8 */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -register int i, j; -for (i = 0; i < PRIV(utf8_table1_size); i++) - if ((int)cvalue <= PRIV(utf8_table1)[i]) break; -buffer += i; -for (j = i; j > 0; j--) - { - *buffer-- = 0x80 | (cvalue & 0x3f); - cvalue >>= 6; - } -*buffer = PRIV(utf8_table2)[i] | cvalue; -return i + 1; - -/* Convert to UTF-16 */ - -#elif PCRE2_CODE_UNIT_WIDTH == 16 -if (cvalue <= 0xffff) - { - *buffer = (PCRE2_UCHAR)cvalue; - return 1; - } -cvalue -= 0x10000; -*buffer++ = 0xd800 | (cvalue >> 10); -*buffer = 0xdc00 | (cvalue & 0x3ff); -return 2; - -/* Convert to UTF-32 */ - -#else -*buffer = (PCRE2_UCHAR)cvalue; -return 1; -#endif -} -#endif /* SUPPORT_UNICODE */ - -/* End of pcre_ord2utf.c */ diff --git a/pcre2/src/pcre2_pattern_info.c b/pcre2/src/pcre2_pattern_info.c deleted file mode 100644 index 5b32a905b..000000000 --- a/pcre2/src/pcre2_pattern_info.c +++ /dev/null @@ -1,410 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - -/************************************************* -* Return info about compiled pattern * -*************************************************/ - -/* -Arguments: - code points to compiled code - what what information is required - where where to put the information; if NULL, return length - -Returns: 0 when data returned - > 0 when length requested - < 0 on error or unset value -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where) -{ -const pcre2_real_code *re = (pcre2_real_code *)code; - -if (where == NULL) /* Requests field length */ - { - switch(what) - { - case PCRE2_INFO_ALLOPTIONS: - case PCRE2_INFO_ARGOPTIONS: - case PCRE2_INFO_BACKREFMAX: - case PCRE2_INFO_BSR: - case PCRE2_INFO_CAPTURECOUNT: - case PCRE2_INFO_FIRSTCODETYPE: - case PCRE2_INFO_FIRSTCODEUNIT: - case PCRE2_INFO_HASBACKSLASHC: - case PCRE2_INFO_HASCRORLF: - case PCRE2_INFO_JCHANGED: - case PCRE2_INFO_LASTCODETYPE: - case PCRE2_INFO_LASTCODEUNIT: - case PCRE2_INFO_MATCHEMPTY: - case PCRE2_INFO_MATCHLIMIT: - case PCRE2_INFO_MAXLOOKBEHIND: - case PCRE2_INFO_MINLENGTH: - case PCRE2_INFO_NAMEENTRYSIZE: - case PCRE2_INFO_NAMECOUNT: - case PCRE2_INFO_NEWLINE: - case PCRE2_INFO_RECURSIONLIMIT: - return sizeof(uint32_t); - - case PCRE2_INFO_FIRSTBITMAP: - return sizeof(const uint8_t *); - - case PCRE2_INFO_JITSIZE: - case PCRE2_INFO_SIZE: - return sizeof(size_t); - - case PCRE2_INFO_NAMETABLE: - return sizeof(PCRE2_SPTR); - } - } - -if (re == NULL) return PCRE2_ERROR_NULL; - -/* Check that the first field in the block is the magic number. If it is not, -return with PCRE2_ERROR_BADMAGIC. */ - -if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; - -/* Check that this pattern was compiled in the correct bit mode */ - -if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; - -switch(what) - { - case PCRE2_INFO_ALLOPTIONS: - *((uint32_t *)where) = re->overall_options; - break; - - case PCRE2_INFO_ARGOPTIONS: - *((uint32_t *)where) = re->compile_options; - break; - - case PCRE2_INFO_BACKREFMAX: - *((uint32_t *)where) = re->top_backref; - break; - - case PCRE2_INFO_BSR: - *((uint32_t *)where) = re->bsr_convention; - break; - - case PCRE2_INFO_CAPTURECOUNT: - *((uint32_t *)where) = re->top_bracket; - break; - - case PCRE2_INFO_FIRSTCODETYPE: - *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 : - ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0; - break; - - case PCRE2_INFO_FIRSTCODEUNIT: - *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? - re->first_codeunit : 0; - break; - - case PCRE2_INFO_FIRSTBITMAP: - *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)? - &(re->start_bitmap[0]) : NULL; - break; - - case PCRE2_INFO_HASBACKSLASHC: - *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0; - break; - - case PCRE2_INFO_HASCRORLF: - *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0; - break; - - case PCRE2_INFO_JCHANGED: - *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0; - break; - - case PCRE2_INFO_JITSIZE: -#ifdef SUPPORT_JIT - *((size_t *)where) = (re->executable_jit != NULL)? - PRIV(jit_get_size)(re->executable_jit) : 0; -#else - *((size_t *)where) = 0; -#endif - break; - - case PCRE2_INFO_LASTCODETYPE: - *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0; - break; - - case PCRE2_INFO_LASTCODEUNIT: - *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? - re->last_codeunit : 0; - break; - - case PCRE2_INFO_MATCHEMPTY: - *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0; - break; - - case PCRE2_INFO_MATCHLIMIT: - *((uint32_t *)where) = re->limit_match; - if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET; - break; - - case PCRE2_INFO_MAXLOOKBEHIND: - *((uint32_t *)where) = re->max_lookbehind; - break; - - case PCRE2_INFO_MINLENGTH: - *((uint32_t *)where) = re->minlength; - break; - - case PCRE2_INFO_NAMEENTRYSIZE: - *((uint32_t *)where) = re->name_entry_size; - break; - - case PCRE2_INFO_NAMECOUNT: - *((uint32_t *)where) = re->name_count; - break; - - case PCRE2_INFO_NAMETABLE: - *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code)); - break; - - case PCRE2_INFO_NEWLINE: - *((uint32_t *)where) = re->newline_convention; - break; - - case PCRE2_INFO_RECURSIONLIMIT: - *((uint32_t *)where) = re->limit_recursion; - if (re->limit_recursion == UINT32_MAX) return PCRE2_ERROR_UNSET; - break; - - case PCRE2_INFO_SIZE: - *((size_t *)where) = re->blocksize; - break; - - default: return PCRE2_ERROR_BADOPTION; - } - -return 0; -} - - - -/************************************************* -* Callout enumerator * -*************************************************/ - -/* -Arguments: - code points to compiled code - callback function called for each callout block - callout_data user data passed to the callback - -Returns: 0 when successfully completed - < 0 on local error - != 0 for callback error -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_callout_enumerate(const pcre2_code *code, - int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data) -{ -pcre2_real_code *re = (pcre2_real_code *)code; -pcre2_callout_enumerate_block cb; -PCRE2_SPTR cc; -#ifdef SUPPORT_UNICODE -BOOL utf = (re->overall_options & PCRE2_UTF) != 0; -#endif - -if (re == NULL) return PCRE2_ERROR_NULL; - -/* Check that the first field in the block is the magic number. If it is not, -return with PCRE2_ERROR_BADMAGIC. */ - -if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; - -/* Check that this pattern was compiled in the correct bit mode */ - -if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; - -cb.version = 0; -cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) - + re->name_count * re->name_entry_size; - -while (TRUE) - { - int rc; - switch (*cc) - { - case OP_END: - return 0; - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_UPTO: - case OP_MINUPTO: - case OP_EXACT: - case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSQUERY: - case OP_POSUPTO: - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_EXACTI: - case OP_POSSTARI: - case OP_POSPLUSI: - case OP_POSQUERYI: - case OP_POSUPTOI: - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTEXACT: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: - case OP_NOTPOSQUERY: - case OP_NOTPOSUPTO: - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTEXACTI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERYI: - case OP_NOTPOSUPTOI: - cc += PRIV(OP_lengths)[*cc]; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEEXACT: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - case OP_TYPEPOSUPTO: - cc += PRIV(OP_lengths)[*cc]; -#ifdef SUPPORT_UNICODE - if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2; -#endif - break; - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - cc += GET(cc, 1); - break; -#endif - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - cc += PRIV(OP_lengths)[*cc] + cc[1]; - break; - - case OP_CALLOUT: - cb.pattern_position = GET(cc, 1); - cb.next_item_length = GET(cc, 1 + LINK_SIZE); - cb.callout_number = cc[1 + 2*LINK_SIZE]; - cb.callout_string_offset = 0; - cb.callout_string_length = 0; - cb.callout_string = NULL; - rc = callback(&cb, callout_data); - if (rc != 0) return rc; - cc += PRIV(OP_lengths)[*cc]; - break; - - case OP_CALLOUT_STR: - cb.pattern_position = GET(cc, 1); - cb.next_item_length = GET(cc, 1 + LINK_SIZE); - cb.callout_number = 0; - cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE); - cb.callout_string_length = - GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2; - cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1; - rc = callback(&cb, callout_data); - if (rc != 0) return rc; - cc += GET(cc, 1 + 2*LINK_SIZE); - break; - - default: - cc += PRIV(OP_lengths)[*cc]; - break; - } - } -} - -/* End of pcre2_pattern_info.c */ diff --git a/pcre2/src/pcre2_printint.c b/pcre2/src/pcre2_printint.c deleted file mode 100644 index 40a633cfd..000000000 --- a/pcre2/src/pcre2_printint.c +++ /dev/null @@ -1,832 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains a PCRE private debugging function for printing out the -internal form of a compiled regular expression, along with some supporting -local functions. This source file is #included in pcre2test.c at each supported -code unit width, with PCRE2_SUFFIX set appropriately, just like the functions -that comprise the library. It can also optionally be included in -pcre2_compile.c for detailed debugging in error situations. */ - - -/* Tables of operator names. The same 8-bit table is used for all code unit -widths, so it must be defined only once. The list itself is defined in -pcre2_internal.h, which is #included by pcre2test before this file. */ - -#ifndef OP_LISTS_DEFINED -static const char *OP_names[] = { OP_NAME_LIST }; -#define OP_LISTS_DEFINED -#endif - -/* The functions and tables herein must all have mode-dependent names. */ - -#define OP_lengths PCRE2_SUFFIX(OP_lengths_) -#define get_ucpname PCRE2_SUFFIX(get_ucpname_) -#define pcre2_printint PCRE2_SUFFIX(pcre2_printint_) -#define print_char PCRE2_SUFFIX(print_char_) -#define print_custring PCRE2_SUFFIX(print_custring_) -#define print_custring_bylen PCRE2_SUFFIX(print_custring_bylen_) -#define print_prop PCRE2_SUFFIX(print_prop_) - -/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that -the definition is next to the definition of the opcodes in pcre2_internal.h. -The contents of the table are, however, mode-dependent. */ - -static const uint8_t OP_lengths[] = { OP_LENGTHS }; - - - -/************************************************* -* Print one character from a string * -*************************************************/ - -/* In UTF mode the character may occupy more than one code unit. - -Arguments: - f file to write to - ptr pointer to first code unit of the character - utf TRUE if string is UTF (will be FALSE if UTF is not supported) - -Returns: number of additional code units used -*/ - -static unsigned int -print_char(FILE *f, PCRE2_SPTR ptr, BOOL utf) -{ -uint32_t c = *ptr; -BOOL one_code_unit = !utf; - -/* If UTF is supported and requested, check for a valid single code unit. */ - -#ifdef SUPPORT_UNICODE -if (utf) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - one_code_unit = c < 0x80; -#elif PCRE2_CODE_UNIT_WIDTH == 16 - one_code_unit = (c & 0xfc00) != 0xd800; -#else - one_code_unit = (c & 0xfffff800u) != 0xd800u; -#endif /* CODE_UNIT_WIDTH */ - } -#endif /* SUPPORT_UNICODE */ - -/* Handle a valid one-code-unit character at any width. */ - -if (one_code_unit) - { - if (PRINTABLE(c)) fprintf(f, "%c", (char)c); - else if (c < 0x80) fprintf(f, "\\x%02x", c); - else fprintf(f, "\\x{%02x}", c); - return 0; - } - -/* Code for invalid UTF code units and multi-unit UTF characters is different -for each width. If UTF is not supported, control should never get here, but we -need a return statement to keep the compiler happy. */ - -#ifndef SUPPORT_UNICODE -return 0; -#else - -/* Malformed UTF-8 should occur only if the sanity check has been turned off. -Rather than swallow random bytes, just stop if we hit a bad one. Print it with -\X instead of \x as an indication. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -if ((c & 0xc0) != 0xc0) - { - fprintf(f, "\\X{%x}", c); /* Invalid starting byte */ - return 0; - } -else - { - int i; - int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ - int s = 6*a; - c = (c & PRIV(utf8_table3)[a]) << s; - for (i = 1; i <= a; i++) - { - if ((ptr[i] & 0xc0) != 0x80) - { - fprintf(f, "\\X{%x}", c); /* Invalid secondary byte */ - return i - 1; - } - s -= 6; - c |= (ptr[i] & 0x3f) << s; - } - fprintf(f, "\\x{%x}", c); - return a; -} -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - -/* UTF-16: rather than swallow a low surrogate, just stop if we hit a bad one. -Print it with \X instead of \x as an indication. */ - -#if PCRE2_CODE_UNIT_WIDTH == 16 -if ((ptr[1] & 0xfc00) != 0xdc00) - { - fprintf(f, "\\X{%x}", c); - return 0; - } -c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000; -fprintf(f, "\\x{%x}", c); -return 1; -#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */ - -/* For UTF-32 we get here only for a malformed code unit, which should only -occur if the sanity check has been turned off. Print it with \X instead of \x -as an indication. */ - -#if PCRE2_CODE_UNIT_WIDTH == 32 -fprintf(f, "\\X{%x}", c); -return 0; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ -#endif /* SUPPORT_UNICODE */ -} - - - -/************************************************* -* Print string as a list of code units * -*************************************************/ - -/* These take no account of UTF as they always print each individual code unit. -The string is zero-terminated for print_custring(); the length is given for -print_custring_bylen(). - -Arguments: - f file to write to - ptr point to the string - len length for print_custring_bylen() - -Returns: nothing -*/ - -static void -print_custring(FILE *f, PCRE2_SPTR ptr) -{ -while (*ptr != '\0') - { - register uint32_t c = *ptr++; - if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); - } -} - -static void -print_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len) -{ -while (len-- > 0) - { - register uint32_t c = *ptr++; - if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); - } -} - - - -/************************************************* -* Find Unicode property name * -*************************************************/ - -/* When there is no UTF/UCP support, the table of names does not exist. This -function should not be called in such configurations, because a pattern that -tries to use Unicode properties won't compile. Rather than put lots of #ifdefs -into the main code, however, we just put one into this function. */ - -static const char * -get_ucpname(unsigned int ptype, unsigned int pvalue) -{ -#ifdef SUPPORT_UNICODE -int i; -for (i = PRIV(utt_size) - 1; i >= 0; i--) - { - if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break; - } -return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??"; -#else /* No UTF support */ -(void)ptype; -(void)pvalue; -return "??"; -#endif /* SUPPORT_UNICODE */ -} - - - -/************************************************* -* Print Unicode property value * -*************************************************/ - -/* "Normal" properties can be printed from tables. The PT_CLIST property is a -pseudo-property that contains a pointer to a list of case-equivalent -characters. - -Arguments: - f file to write to - code pointer in the compiled code - before text to print before - after text to print after - -Returns: nothing -*/ - -static void -print_prop(FILE *f, PCRE2_SPTR code, const char *before, const char *after) -{ -if (code[1] != PT_CLIST) - { - fprintf(f, "%s%s %s%s", before, OP_names[*code], get_ucpname(code[1], - code[2]), after); - } -else - { - const char *not = (*code == OP_PROP)? "" : "not "; - const uint32_t *p = PRIV(ucd_caseless_sets) + code[2]; - fprintf (f, "%s%sclist", before, not); - while (*p < NOTACHAR) fprintf(f, " %04x", *p++); - fprintf(f, "%s", after); - } -} - - - -/************************************************* -* Print compiled pattern * -*************************************************/ - -/* The print_lengths flag controls whether offsets and lengths of items are -printed. Lenths can be turned off from pcre2test so that automatic tests on -bytecode can be written that do not depend on the value of LINK_SIZE. - -Arguments: - re a compiled pattern - f the file to write to - print_lengths show various lengths - -Returns: nothing -*/ - -static void -pcre2_printint(pcre2_code *re, FILE *f, BOOL print_lengths) -{ -PCRE2_SPTR codestart, nametable, code; -uint32_t nesize = re->name_entry_size; -BOOL utf = (re->overall_options & PCRE2_UTF) != 0; - -nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -code = codestart = nametable + re->name_count * re->name_entry_size; - -for(;;) - { - PCRE2_SPTR ccode; - uint32_t c; - int i; - const char *flag = " "; - unsigned int extra = 0; - - if (print_lengths) - fprintf(f, "%3d ", (int)(code - codestart)); - else - fprintf(f, " "); - - switch(*code) - { -/* ========================================================================== */ - /* These cases are never obeyed. This is a fudge that causes a compile- - time error if the vectors OP_names or OP_lengths, which are indexed - by opcode, are not the correct length. It seems to be the only way to do - such a check at compile time, as the sizeof() operator does not work in - the C preprocessor. */ - - case OP_TABLE_LENGTH: - case OP_TABLE_LENGTH + - ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && - (sizeof(OP_lengths) == OP_TABLE_LENGTH)): - break; -/* ========================================================================== */ - - case OP_END: - fprintf(f, " %s\n", OP_names[*code]); - fprintf(f, "------------------------------------------------------------------\n"); - return; - - case OP_CHAR: - fprintf(f, " "); - do - { - code++; - code += 1 + print_char(f, code, utf); - } - while (*code == OP_CHAR); - fprintf(f, "\n"); - continue; - - case OP_CHARI: - fprintf(f, " /i "); - do - { - code++; - code += 1 + print_char(f, code, utf); - } - while (*code == OP_CHARI); - fprintf(f, "\n"); - continue; - - case OP_CBRA: - case OP_CBRAPOS: - case OP_SCBRA: - case OP_SCBRAPOS: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE)); - break; - - case OP_BRA: - case OP_BRAPOS: - case OP_SBRA: - case OP_SBRAPOS: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - case OP_ALT: - case OP_KET: - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_ONCE_NC: - case OP_COND: - case OP_SCOND: - case OP_REVERSE: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_CLOSE: - fprintf(f, " %s %d", OP_names[*code], GET2(code, 1)); - break; - - case OP_CREF: - fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); - break; - - case OP_DNCREF: - { - PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; - fprintf(f, " %s Cond ref <", flag); - print_custring(f, entry); - fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); - } - break; - - case OP_RREF: - c = GET2(code, 1); - if (c == RREF_ANY) - fprintf(f, " Cond recurse any"); - else - fprintf(f, " Cond recurse %d", c); - break; - - case OP_DNRREF: - { - PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; - fprintf(f, " %s Cond recurse <", flag); - print_custring(f, entry); - fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); - } - break; - - case OP_FALSE: - fprintf(f, " Cond false"); - break; - - case OP_TRUE: - fprintf(f, " Cond true"); - break; - - case OP_STARI: - case OP_MINSTARI: - case OP_POSSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_POSQUERYI: - flag = "/i"; - /* Fall through */ - case OP_STAR: - case OP_MINSTAR: - case OP_POSSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_POSQUERY: - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPOSSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSQUERY: - fprintf(f, " %s ", flag); - - if (*code >= OP_TYPESTAR) - { - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) - { - print_prop(f, code + 1, "", " "); - extra = 2; - } - else fprintf(f, "%s", OP_names[code[1]]); - } - else extra = print_char(f, code+1, utf); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_EXACTI: - case OP_UPTOI: - case OP_MINUPTOI: - case OP_POSUPTOI: - flag = "/i"; - /* Fall through */ - case OP_EXACT: - case OP_UPTO: - case OP_MINUPTO: - case OP_POSUPTO: - fprintf(f, " %s ", flag); - extra = print_char(f, code + 1 + IMM2_SIZE, utf); - fprintf(f, "{"); - if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?"); - else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+"); - break; - - case OP_TYPEEXACT: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - { - print_prop(f, code + IMM2_SIZE + 1, " ", " "); - extra = 2; - } - else fprintf(f, " %s", OP_names[code[1 + IMM2_SIZE]]); - fprintf(f, "{"); - if (*code != OP_TYPEEXACT) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); - else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); - break; - - case OP_NOTI: - flag = "/i"; - /* Fall through */ - case OP_NOT: - fprintf(f, " %s [^", flag); - extra = print_char(f, code + 1, utf); - fprintf(f, "]"); - break; - - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPOSSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTPOSPLUSI: - case OP_NOTQUERYI: - case OP_NOTMINQUERYI: - case OP_NOTPOSQUERYI: - flag = "/i"; - /* Fall through */ - - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPOSSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTPOSPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTPOSQUERY: - fprintf(f, " %s [^", flag); - extra = print_char(f, code + 1, utf); - fprintf(f, "]%s", OP_names[*code]); - break; - - case OP_NOTEXACTI: - case OP_NOTUPTOI: - case OP_NOTMINUPTOI: - case OP_NOTPOSUPTOI: - flag = "/i"; - /* Fall through */ - - case OP_NOTEXACT: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTPOSUPTO: - fprintf(f, " %s [^", flag); - extra = print_char(f, code + 1 + IMM2_SIZE, utf); - fprintf(f, "]{"); - if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); - else - if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); - break; - - case OP_RECURSE: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_REFI: - flag = "/i"; - /* Fall through */ - case OP_REF: - fprintf(f, " %s \\%d", flag, GET2(code,1)); - ccode = code + OP_lengths[*code]; - goto CLASS_REF_REPEAT; - - case OP_DNREFI: - flag = "/i"; - /* Fall through */ - case OP_DNREF: - { - PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; - fprintf(f, " %s \\k<", flag); - print_custring(f, entry); - fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); - } - ccode = code + OP_lengths[*code]; - goto CLASS_REF_REPEAT; - - case OP_CALLOUT: - fprintf(f, " %s %d %d %d", OP_names[*code], code[1 + 2*LINK_SIZE], - GET(code, 1), GET(code, 1 + LINK_SIZE)); - break; - - case OP_CALLOUT_STR: - c = code[1 + 4*LINK_SIZE]; - fprintf(f, " %s %c", OP_names[*code], c); - extra = GET(code, 1 + 2*LINK_SIZE); - print_custring_bylen(f, code + 2 + 4*LINK_SIZE, extra - 3 - 4*LINK_SIZE); - for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) - if (c == PRIV(callout_start_delims)[i]) - { - c = PRIV(callout_end_delims)[i]; - break; - } - fprintf(f, "%c %d %d %d", c, GET(code, 1 + 3*LINK_SIZE), GET(code, 1), - GET(code, 1 + LINK_SIZE)); - break; - - case OP_PROP: - case OP_NOTPROP: - print_prop(f, code, " ", ""); - break; - - /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm - in having this code always here, and it makes it less messy without all - those #ifdefs. */ - - case OP_CLASS: - case OP_NCLASS: - case OP_XCLASS: - { - unsigned int min, max; - BOOL printmap; - BOOL invertmap = FALSE; - uint8_t *map; - uint8_t inverted_map[32]; - - fprintf(f, " ["); - - if (*code == OP_XCLASS) - { - extra = GET(code, 1); - ccode = code + LINK_SIZE + 1; - printmap = (*ccode & XCL_MAP) != 0; - if ((*ccode & XCL_NOT) != 0) - { - invertmap = (*ccode & XCL_HASPROP) == 0; - fprintf(f, "^"); - } - ccode++; - } - else - { - printmap = TRUE; - ccode = code + 1; - } - - /* Print a bit map */ - - if (printmap) - { - map = (uint8_t *)ccode; - if (invertmap) - { - for (i = 0; i < 32; i++) inverted_map[i] = ~map[i]; - map = inverted_map; - } - - for (i = 0; i < 256; i++) - { - if ((map[i/8] & (1 << (i&7))) != 0) - { - int j; - for (j = i+1; j < 256; j++) - if ((map[j/8] & (1 << (j&7))) == 0) break; - if (i == '-' || i == ']') fprintf(f, "\\"); - if (PRINTABLE(i)) fprintf(f, "%c", i); - else fprintf(f, "\\x%02x", i); - if (--j > i) - { - if (j != i + 1) fprintf(f, "-"); - if (j == '-' || j == ']') fprintf(f, "\\"); - if (PRINTABLE(j)) fprintf(f, "%c", j); - else fprintf(f, "\\x%02x", j); - } - i = j; - } - } - ccode += 32 / sizeof(PCRE2_UCHAR); - } - - /* For an XCLASS there is always some additional data */ - - if (*code == OP_XCLASS) - { - PCRE2_UCHAR ch; - while ((ch = *ccode++) != XCL_END) - { - BOOL not = FALSE; - const char *notch = ""; - - switch(ch) - { - case XCL_NOTPROP: - not = TRUE; - notch = "^"; - /* Fall through */ - - case XCL_PROP: - { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; - - switch(ptype) - { - case PT_PXGRAPH: - fprintf(f, "[:%sgraph:]", notch); - break; - - case PT_PXPRINT: - fprintf(f, "[:%sprint:]", notch); - break; - - case PT_PXPUNCT: - fprintf(f, "[:%spunct:]", notch); - break; - - default: - fprintf(f, "\\%c{%s}", (not? 'P':'p'), - get_ucpname(ptype, pvalue)); - break; - } - } - break; - - default: - ccode += 1 + print_char(f, ccode, utf); - if (ch == XCL_RANGE) - { - fprintf(f, "-"); - ccode += 1 + print_char(f, ccode, utf); - } - break; - } - } - } - - /* Indicate a non-UTF class which was created by negation */ - - fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); - - /* Handle repeats after a class or a back reference */ - - CLASS_REF_REPEAT: - switch(*ccode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - fprintf(f, "%s", OP_names[*ccode]); - extra += OP_lengths[*ccode]; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - min = GET2(ccode,1); - max = GET2(ccode,1 + IMM2_SIZE); - if (max == 0) fprintf(f, "{%u,}", min); - else fprintf(f, "{%u,%u}", min, max); - if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); - else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+"); - extra += OP_lengths[*ccode]; - break; - - /* Do nothing if it's not a repeat; this code stops picky compilers - warning about the lack of a default code path. */ - - default: - break; - } - } - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - fprintf(f, " %s ", OP_names[*code]); - print_custring_bylen(f, code + 2, code[1]); - extra += code[1]; - break; - - case OP_THEN: - fprintf(f, " %s", OP_names[*code]); - break; - - case OP_CIRCM: - case OP_DOLLM: - flag = "/m"; - /* Fall through */ - - /* Anything else is just an item with no data, but possibly a flag. */ - - default: - fprintf(f, " %s %s", flag, OP_names[*code]); - break; - } - - code += OP_lengths[*code] + extra; - fprintf(f, "\n"); - } -} - -/* End of pcre2_printint.c */ diff --git a/pcre2/src/pcre2_serialize.c b/pcre2/src/pcre2_serialize.c deleted file mode 100644 index 8c44acfdc..000000000 --- a/pcre2/src/pcre2_serialize.c +++ /dev/null @@ -1,258 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains functions for serializing and deserializing -a sequence of compiled codes. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -#include "pcre2_internal.h" - -/* Magic number to provide a small check against being handed junk. */ - -#define SERIALIZED_DATA_MAGIC 0x50523253u - -/* Deserialization is limited to the current PCRE version and -character width. */ - -#define SERIALIZED_DATA_VERSION \ - ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16)) - -#define SERIALIZED_DATA_CONFIG \ - (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16)) - - - -/************************************************* -* Serialize compiled patterns * -*************************************************/ - -PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION -pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes, - uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size, - pcre2_general_context *gcontext) -{ -uint8_t *bytes; -uint8_t *dst_bytes; -int32_t i; -PCRE2_SIZE total_size; -const pcre2_real_code *re; -const uint8_t *tables; -pcre2_serialized_data *data; - -const pcre2_memctl *memctl = (gcontext != NULL) ? - &gcontext->memctl : &PRIV(default_compile_context).memctl; - -if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL) - return PCRE2_ERROR_NULL; - -if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; - -/* Compute total size. */ -total_size = sizeof(pcre2_serialized_data) + tables_length; -tables = NULL; - -for (i = 0; i < number_of_codes; i++) - { - if (codes[i] == NULL) return PCRE2_ERROR_NULL; - re = (const pcre2_real_code *)(codes[i]); - if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; - if (tables == NULL) - tables = re->tables; - else if (tables != re->tables) - return PCRE2_ERROR_MIXEDTABLES; - total_size += re->blocksize; - } - -/* Initialize the byte stream. */ -bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data); -if (bytes == NULL) return PCRE2_ERROR_NOMEMORY; - -/* The controller is stored as a hidden parameter. */ -memcpy(bytes, memctl, sizeof(pcre2_memctl)); -bytes += sizeof(pcre2_memctl); - -data = (pcre2_serialized_data *)bytes; -data->magic = SERIALIZED_DATA_MAGIC; -data->version = SERIALIZED_DATA_VERSION; -data->config = SERIALIZED_DATA_CONFIG; -data->number_of_codes = number_of_codes; - -/* Copy all compiled code data. */ -dst_bytes = bytes + sizeof(pcre2_serialized_data); -memcpy(dst_bytes, tables, tables_length); -dst_bytes += tables_length; - -for (i = 0; i < number_of_codes; i++) - { - re = (const pcre2_real_code *)(codes[i]); - memcpy(dst_bytes, (char *)re, re->blocksize); - dst_bytes += re->blocksize; - } - -*serialized_bytes = bytes; -*serialized_size = total_size; -return number_of_codes; -} - - -/************************************************* -* Deserialize compiled patterns * -*************************************************/ - -PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION -pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes, - const uint8_t *bytes, pcre2_general_context *gcontext) -{ -const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; -const pcre2_memctl *memctl = (gcontext != NULL) ? - &gcontext->memctl : &PRIV(default_compile_context).memctl; - -const uint8_t *src_bytes; -pcre2_real_code *dst_re; -uint8_t *tables; -int32_t i, j; - -/* Sanity checks. */ - -if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL; -if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; -if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; -if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; -if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; - -if (number_of_codes > data->number_of_codes) - number_of_codes = data->number_of_codes; - -src_bytes = bytes + sizeof(pcre2_serialized_data); - -/* Decode tables. The reference count for the tables is stored immediately -following them. */ - -tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data); -if (tables == NULL) return PCRE2_ERROR_NOMEMORY; - -memcpy(tables, src_bytes, tables_length); -*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes; -src_bytes += tables_length; - -/* Decode the byte stream. We must not try to read the size from the compiled -code block in the stream, because it might be unaligned, which causes errors on -hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type -of the blocksize field is given its own name to ensure that it is the same here -as in the block. */ - -for (i = 0; i < number_of_codes; i++) - { - CODE_BLOCKSIZE_TYPE blocksize; - memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize), - sizeof(CODE_BLOCKSIZE_TYPE)); - - /* The allocator provided by gcontext replaces the original one. */ - - dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize, - (pcre2_memctl *)gcontext); - if (dst_re == NULL) - { - memctl->free(tables, memctl->memory_data); - for (j = 0; j < i; j++) - { - memctl->free(codes[j], memctl->memory_data); - codes[j] = NULL; - } - return PCRE2_ERROR_NOMEMORY; - } - - /* The new allocator must be preserved. */ - - memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl), - src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl)); - - /* At the moment only one table is supported. */ - - dst_re->tables = tables; - dst_re->executable_jit = NULL; - dst_re->flags |= PCRE2_DEREF_TABLES; - - codes[i] = dst_re; - src_bytes += blocksize; - } - -return number_of_codes; -} - - -/************************************************* -* Get the number of serialized patterns * -*************************************************/ - -PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION -pcre2_serialize_get_number_of_codes(const uint8_t *bytes) -{ -const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes; - -if (data == NULL) return PCRE2_ERROR_NULL; -if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; -if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; -if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; - -return data->number_of_codes; -} - - -/************************************************* -* Free the allocated stream * -*************************************************/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_serialize_free(uint8_t *bytes) -{ -if (bytes != NULL) - { - pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl)); - memctl->free(memctl, memctl->memory_data); - } -} - -/* End of pcre2_serialize.c */ diff --git a/pcre2/src/pcre2_string_utils.c b/pcre2/src/pcre2_string_utils.c deleted file mode 100644 index 2a1f28262..000000000 --- a/pcre2/src/pcre2_string_utils.c +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains internal functions for comparing and finding the length -of strings. These are used instead of strcmp() etc because the standard -functions work only on 8-bit data. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - -/************************************************* -* Compare two zero-terminated PCRE2 strings * -*************************************************/ - -/* -Arguments: - str1 first string - str2 second string - -Returns: 0, 1, or -1 -*/ - -int -PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2) -{ -PCRE2_UCHAR c1, c2; -while (*str1 != '\0' || *str2 != '\0') - { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) return ((c1 > c2) << 1) - 1; - } -return 0; -} - - -/************************************************* -* Compare zero-terminated PCRE2 & 8-bit strings * -*************************************************/ - -/* As the 8-bit string is almost always a literal, its type is specified as -const char *. - -Arguments: - str1 first string - str2 second string - -Returns: 0, 1, or -1 -*/ - -int -PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2) -{ -PCRE2_UCHAR c1, c2; -while (*str1 != '\0' || *str2 != '\0') - { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) return ((c1 > c2) << 1) - 1; - } -return 0; -} - - -/************************************************* -* Compare two PCRE2 strings, given a length * -*************************************************/ - -/* -Arguments: - str1 first string - str2 second string - len the length - -Returns: 0, 1, or -1 -*/ - -int -PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len) -{ -PCRE2_UCHAR c1, c2; -for (; len > 0; len--) - { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) return ((c1 > c2) << 1) - 1; - } -return 0; -} - - -/************************************************* -* Compare PCRE2 string to 8-bit string by length * -*************************************************/ - -/* As the 8-bit string is almost always a literal, its type is specified as -const char *. - -Arguments: - str1 first string - str2 second string - len the length - -Returns: 0, 1, or -1 -*/ - -int -PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len) -{ -PCRE2_UCHAR c1, c2; -for (; len > 0; len--) - { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) return ((c1 > c2) << 1) - 1; - } -return 0; -} - - -/************************************************* -* Find the length of a PCRE2 string * -*************************************************/ - -/* -Argument: the string -Returns: the length -*/ - -PCRE2_SIZE -PRIV(strlen)(PCRE2_SPTR str) -{ -PCRE2_SIZE c = 0; -while (*str++ != 0) c++; -return c; -} - - -/************************************************* -* Copy 8-bit 0-terminated string to PCRE2 string * -*************************************************/ - -/* Arguments: - str1 buffer to receive the string - str2 8-bit string to be copied - -Returns: the number of code units used (excluding trailing zero) -*/ - -PCRE2_SIZE -PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2) -{ -PCRE2_UCHAR *t = str1; -while (*str2 != 0) *t++ = *str2++; -*t = 0; -return t - str1; -} - -/* End of pcre2_string_utils.c */ diff --git a/pcre2/src/pcre2_study.c b/pcre2/src/pcre2_study.c deleted file mode 100644 index 18932adef..000000000 --- a/pcre2/src/pcre2_study.c +++ /dev/null @@ -1,1575 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains functions for scanning a compiled pattern and -collecting data (e.g. minimum matching length). */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -#include "pcre2_internal.h" - - -/* Set a bit in the starting code unit bit map. */ - -#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1 << ((c)&7)) - -/* Returns from set_start_bits() */ - -enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; - - -/************************************************* -* Find the minimum subject length for a group * -*************************************************/ - -/* Scan a parenthesized group and compute the minimum length of subject that -is needed to match it. This is a lower bound; it does not mean there is a -string of that length that matches. In UTF mode, the result is in characters -rather than code units. The field in a compiled pattern for storing the minimum -length is 16-bits long (on the grounds that anything longer than that is -pathological), so we give up when we reach that amount. This also means that -integer overflow for really crazy patterns cannot happen. - -Arguments: - re compiled pattern block - code pointer to start of group (the bracket) - startcode pointer to start of the whole pattern's code - utf UTF flag - recurses chain of recurse_check to catch mutual recursion - countptr pointer to call count (to catch over complexity) - -Returns: the minimum length - -1 \C in UTF-8 mode - or (*ACCEPT) - or pattern too complicated - or back reference to duplicate name/number - -2 internal error (missing capturing bracket) - -3 internal error (opcode not listed) -*/ - -static int -find_minlength(const pcre2_real_code *re, PCRE2_SPTR code, - PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr) -{ -int length = -1; -int prev_cap_recno = -1; -int prev_cap_d = 0; -int prev_recurse_recno = -1; -int prev_recurse_d = 0; -uint32_t once_fudge = 0; -BOOL had_recurse = FALSE; -BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0; -recurse_check this_recurse; -register int branchlength = 0; -register PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE; - -/* If this is a "could be empty" group, its minimum length is 0. */ - -if (*code >= OP_SBRA && *code <= OP_SCOND) return 0; - -/* Skip over capturing bracket number */ - -if (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE; - -/* A large and/or complex regex can take too long to process. */ - -if ((*countptr)++ > 1000) return -1; - -/* Scan along the opcodes for this branch. If we get to the end of the branch, -check the length against that of the other branches. If the accumulated length -passes 16-bits, stop. */ - -for (;;) - { - int d, min, recno; - PCRE2_UCHAR *cs, *ce; - register PCRE2_UCHAR op = *cc; - - if (branchlength >= UINT16_MAX) return UINT16_MAX; - - switch (op) - { - case OP_COND: - case OP_SCOND: - - /* If there is only one branch in a condition, the implied branch has zero - length, so we don't add anything. This covers the DEFINE "condition" - automatically. If there are two branches we can treat it the same as any - other non-capturing subpattern. */ - - cs = cc + GET(cc, 1); - if (*cs != OP_ALT) - { - cc = cs + 1 + LINK_SIZE; - break; - } - goto PROCESS_NON_CAPTURE; - - /* There's a special case of OP_ONCE, when it is wrapped round an - OP_RECURSE. We'd like to process the latter at this level so that - remembering the value works for repeated cases. So we do nothing, but - set a fudge value to skip over the OP_KET after the recurse. */ - - case OP_ONCE: - if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET) - { - once_fudge = 1 + LINK_SIZE; - cc += 1 + LINK_SIZE; - break; - } - /* Fall through */ - - case OP_ONCE_NC: - case OP_BRA: - case OP_SBRA: - case OP_BRAPOS: - case OP_SBRAPOS: - PROCESS_NON_CAPTURE: - d = find_minlength(re, cc, startcode, utf, recurses, countptr); - if (d < 0) return d; - branchlength += d; - do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += 1 + LINK_SIZE; - break; - - /* To save time for repeated capturing subpatterns, we remember the - length of the previous one. Unfortunately we can't do the same for - the unnumbered ones above. Nor can we do this if (?| is present in the - pattern because captures with the same number are not then identical. */ - - case OP_CBRA: - case OP_SCBRA: - case OP_CBRAPOS: - case OP_SCBRAPOS: - recno = dupcapused? prev_cap_recno - 1 : (int)GET2(cc, 1+LINK_SIZE); - if (recno != prev_cap_recno) - { - prev_cap_recno = recno; - prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr); - if (prev_cap_d < 0) return prev_cap_d; - } - branchlength += prev_cap_d; - do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += 1 + LINK_SIZE; - break; - - /* ACCEPT makes things far too complicated; we have to give up. */ - - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - return -1; - - /* Reached end of a branch; if it's a ket it is the end of a nested - call. If it's ALT it is an alternation in a nested call. If it is END it's - the end of the outer call. All can be handled by the same code. If an - ACCEPT was previously encountered, use the length that was in force at that - time, and pass back the shortest ACCEPT length. */ - - case OP_ALT: - case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - case OP_END: - if (length < 0 || (!had_recurse && branchlength < length)) - length = branchlength; - if (op != OP_ALT) return length; - cc += 1 + LINK_SIZE; - branchlength = 0; - had_recurse = FALSE; - break; - - /* Skip over assertive subpatterns */ - - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - do cc += GET(cc, 1); while (*cc == OP_ALT); - /* Fall through */ - - /* Skip over things that don't match chars */ - - case OP_REVERSE: - case OP_CREF: - case OP_DNCREF: - case OP_RREF: - case OP_DNRREF: - case OP_FALSE: - case OP_TRUE: - case OP_CALLOUT: - case OP_SOD: - case OP_SOM: - case OP_EOD: - case OP_EODN: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - cc += PRIV(OP_lengths)[*cc]; - break; - - case OP_CALLOUT_STR: - cc += GET(cc, 1 + 2*LINK_SIZE); - break; - - /* Skip over a subpattern that has a {0} or {0,x} quantifier */ - - case OP_BRAZERO: - case OP_BRAMINZERO: - case OP_BRAPOSZERO: - case OP_SKIPZERO: - cc += PRIV(OP_lengths)[*cc]; - do cc += GET(cc, 1); while (*cc == OP_ALT); - cc += 1 + LINK_SIZE; - break; - - /* Handle literal characters and + repetitions */ - - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_PLUS: - case OP_PLUSI: - case OP_MINPLUS: - case OP_MINPLUSI: - case OP_POSPLUS: - case OP_POSPLUSI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - branchlength++; - cc += 2; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - branchlength++; - cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2; - break; - - /* Handle exact repetitions. The count is already in characters, but we - may need to skip over a multibyte character in UTF mode. */ - - case OP_EXACT: - case OP_EXACTI: - case OP_NOTEXACT: - case OP_NOTEXACTI: - branchlength += GET2(cc,1); - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - case OP_TYPEEXACT: - branchlength += GET2(cc,1); - cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP - || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); - break; - - /* Handle single-char non-literal matchers */ - - case OP_PROP: - case OP_NOTPROP: - cc += 2; - /* Fall through */ - - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_EXTUNI: - case OP_HSPACE: - case OP_NOT_HSPACE: - case OP_VSPACE: - case OP_NOT_VSPACE: - branchlength++; - cc++; - break; - - /* "Any newline" might match two characters, but it also might match just - one. */ - - case OP_ANYNL: - branchlength += 1; - cc++; - break; - - /* The single-byte matcher means we can't proceed in UTF mode. (In - non-UTF mode \C will actually be turned into OP_ALLANY, so won't ever - appear, but leave the code, just in case.) */ - - case OP_ANYBYTE: -#ifdef SUPPORT_UNICODE - if (utf) return -1; -#endif - branchlength++; - cc++; - break; - - /* For repeated character types, we have to test for \p and \P, which have - an extra two bytes of parameters. */ - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSQUERY: - if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; - cc += PRIV(OP_lengths)[op]; - break; - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - if (cc[1 + IMM2_SIZE] == OP_PROP - || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; - cc += PRIV(OP_lengths)[op]; - break; - - /* Check a class for variable quantification */ - - case OP_CLASS: - case OP_NCLASS: -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - /* The original code caused an unsigned overflow in 64 bit systems, - so now we use a conditional statement. */ - if (op == OP_XCLASS) - cc += GET(cc, 1); - else - cc += PRIV(OP_lengths)[OP_CLASS]; -#else - cc += PRIV(OP_lengths)[OP_CLASS]; -#endif - - switch (*cc) - { - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - branchlength++; - /* Fall through */ - - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSQUERY: - cc++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - branchlength += GET2(cc,1); - cc += 1 + 2 * IMM2_SIZE; - break; - - default: - branchlength++; - break; - } - break; - - /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same - way: we find the minimum length for the subpattern. A recursion - (backreference or subroutine) causes an a flag to be set that causes the - length of this branch to be ignored. The logic is that a recursion can only - make sense if there is another alternative that stops the recursing. That - will provide the minimum length (when no recursion happens). - - If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket - matches an empty string (by default it causes a matching failure), so in - that case we must set the minimum length to zero. */ - - /* Duplicate named pattern back reference. We cannot reliably find a length - for this if duplicate numbers are present in the pattern. */ - - case OP_DNREF: - case OP_DNREFI: - if (dupcapused) return -1; - if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) - { - int count = GET2(cc, 1+IMM2_SIZE); - PCRE2_UCHAR *slot = - (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + - GET2(cc, 1) * re->name_entry_size; - - d = INT_MAX; - - /* Scan all groups with the same name */ - - while (count-- > 0) - { - ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0)); - if (cs == NULL) return -2; - do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) /* Simple recursion */ - { - d = 0; - had_recurse = TRUE; - break; - } - else - { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; - if (r != NULL) /* Mutual recursion */ - { - d = 0; - had_recurse = TRUE; - break; - } - else - { - int dd; - this_recurse.prev = recurses; - this_recurse.group = cs; - dd = find_minlength(re, cs, startcode, utf, &this_recurse, countptr); - if (dd < d) d = dd; - } - } - slot += re->name_entry_size; - } - } - else d = 0; - cc += 1 + 2*IMM2_SIZE; - goto REPEAT_BACK_REFERENCE; - - /* Single back reference. We cannot find a length for this if duplicate - numbers are present in the pattern. */ - - case OP_REF: - case OP_REFI: - if (dupcapused) return -1; - if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) - { - ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); - if (cs == NULL) return -2; - do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) /* Simple recursion */ - { - d = 0; - had_recurse = TRUE; - } - else - { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; - if (r != NULL) /* Mutual recursion */ - { - d = 0; - had_recurse = TRUE; - } - else - { - this_recurse.prev = recurses; - this_recurse.group = cs; - d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr); - } - } - } - else d = 0; - cc += 1 + IMM2_SIZE; - - /* Handle repeated back references */ - - REPEAT_BACK_REFERENCE: - switch (*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSQUERY: - min = 0; - cc++; - break; - - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSPLUS: - min = 1; - cc++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - min = GET2(cc, 1); - cc += 1 + 2 * IMM2_SIZE; - break; - - default: - min = 1; - break; - } - - /* Take care not to overflow: (1) min and d are ints, so check that their - product is not greater than INT_MAX. (2) branchlength is limited to - UINT16_MAX (checked at the top of the loop). */ - - if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d) - branchlength = UINT16_MAX; - else branchlength += min * d; - break; - - /* Recursion always refers to the first occurrence of a subpattern with a - given number. Therefore, we can always make use of caching, even when the - pattern contains multiple subpatterns with the same number. */ - - case OP_RECURSE: - cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1); - recno = GET2(cs, 1+LINK_SIZE); - if (recno == prev_recurse_recno) - { - branchlength += prev_recurse_d; - } - else - { - do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) /* Simple recursion */ - had_recurse = TRUE; - else - { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; - if (r != NULL) /* Mutual recursion */ - had_recurse = TRUE; - else - { - this_recurse.prev = recurses; - this_recurse.group = cs; - prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse, - countptr); - if (prev_recurse_d < 0) return prev_recurse_d; - prev_recurse_recno = recno; - branchlength += prev_recurse_d; - } - } - } - cc += 1 + LINK_SIZE + once_fudge; - once_fudge = 0; - break; - - /* Anything else does not or need not match a character. We can get the - item's length from the table, but for those that can match zero occurrences - of a character, we must take special action for UTF-8 characters. As it - happens, the "NOT" versions of these opcodes are used at present only for - ASCII characters, so they could be omitted from this list. However, in - future that may change, so we include them here so as not to leave a - gotcha for a future maintainer. */ - - case OP_UPTO: - case OP_UPTOI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_MINUPTO: - case OP_MINUPTOI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - - case OP_STAR: - case OP_STARI: - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_MINSTAR: - case OP_MINSTARI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_POSSTAR: - case OP_POSSTARI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - - case OP_QUERY: - case OP_QUERYI: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_MINQUERY: - case OP_MINQUERYI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - case OP_POSQUERY: - case OP_POSQUERYI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - - cc += PRIV(OP_lengths)[op]; -#ifdef SUPPORT_UNICODE - if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - /* Skip these, but we need to add in the name length. */ - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - case OP_THEN_ARG: - cc += PRIV(OP_lengths)[op] + cc[1]; - break; - - /* The remaining opcodes are just skipped over. */ - - case OP_CLOSE: - case OP_COMMIT: - case OP_FAIL: - case OP_PRUNE: - case OP_SET_SOM: - case OP_SKIP: - case OP_THEN: - cc += PRIV(OP_lengths)[op]; - break; - - /* This should not occur: we list all opcodes explicitly so that when - new ones get added they are properly considered. */ - - default: - return -3; - } - } -/* Control never gets here */ -} - - - -/************************************************* -* Set a bit and maybe its alternate case * -*************************************************/ - -/* Given a character, set its first code unit's bit in the table, and also the -corresponding bit for the other version of a letter if we are caseless. - -Arguments: - re points to the regex block - p points to the first code unit of the character - caseless TRUE if caseless - utf TRUE for UTF mode - -Returns: pointer after the character -*/ - -static PCRE2_SPTR -set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf) -{ -uint32_t c = *p++; /* First code unit */ -(void)utf; /* Stop compiler warning when UTF not supported */ - -/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for -0xff. */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 -if (c > 0xff) SET_BIT(0xff); else -#endif - -SET_BIT(c); - -/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find -the end of the character, even when caseless. */ - -#ifdef SUPPORT_UNICODE -if (utf) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (c >= 0xc0) GETUTF8INC(c, p); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p); -#endif - } -#endif /* SUPPORT_UNICODE */ - -/* If caseless, handle the other case of the character. */ - -if (caseless) - { - if (utf) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - PCRE2_UCHAR buff[6]; - c = UCD_OTHERCASE(c); - (void)PRIV(ord2utf)(c, buff); - SET_BIT(buff[0]); -#else /* 16-bit or 32-bit mode */ - c = UCD_OTHERCASE(c); - if (c > 0xff) SET_BIT(0xff); else SET_BIT(c); -#endif - } - - /* Not UTF */ - - else if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]); - } - -return p; -} - - - -/************************************************* -* Set bits for a positive character type * -*************************************************/ - -/* This function sets starting bits for a character type. In UTF-8 mode, we can -only do a direct setting for bytes less than 128, as otherwise there can be -confusion with bytes in the middle of UTF-8 characters. In a "traditional" -environment, the tables will only recognize ASCII characters anyway, but in at -least one Windows environment, some higher bytes bits were set in the tables. -So we deal with that case by considering the UTF-8 encoding. - -Arguments: - re the regex block - cbit type the type of character wanted - table_limit 32 for non-UTF-8; 16 for UTF-8 - -Returns: nothing -*/ - -static void -set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit) -{ -register uint32_t c; -for (c = 0; c < table_limit; c++) - re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type]; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -if (table_limit == 32) return; -for (c = 128; c < 256; c++) - { - if ((re->tables[cbits_offset + c/8] & (1 << (c&7))) != 0) - { - PCRE2_UCHAR buff[6]; - (void)PRIV(ord2utf)(c, buff); - SET_BIT(buff[0]); - } - } -#endif /* UTF-8 */ -} - - -/************************************************* -* Set bits for a negative character type * -*************************************************/ - -/* This function sets starting bits for a negative character type such as \D. -In UTF-8 mode, we can only do a direct setting for bytes less than 128, as -otherwise there can be confusion with bytes in the middle of UTF-8 characters. -Unlike in the positive case, where we can set appropriate starting bits for -specific high-valued UTF-8 characters, in this case we have to set the bits for -all high-valued characters. The lowest is 0xc2, but we overkill by starting at -0xc0 (192) for simplicity. - -Arguments: - re the regex block - cbit type the type of character wanted - table_limit 32 for non-UTF-8; 16 for UTF-8 - -Returns: nothing -*/ - -static void -set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit) -{ -register uint32_t c; -for (c = 0; c < table_limit; c++) - re->start_bitmap[c] |= ~(re->tables[c+cbits_offset+cbit_type]); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff; -#endif -} - - - -/************************************************* -* Create bitmap of starting bytes * -*************************************************/ - -/* This function scans a compiled unanchored expression recursively and -attempts to build a bitmap of the set of possible starting code units whose -values are less than 256. In 16-bit and 32-bit mode, values above 255 all cause -the 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode -we pass a value of 16 rather than 32 as the final argument. (See comments in -those functions for the reason.) - -The SSB_CONTINUE return is useful for parenthesized groups in patterns such as -(a*)b where the group provides some optional starting code units but scanning -must continue at the outer level to find at least one mandatory code unit. At -the outermost level, this function fails unless the result is SSB_DONE. - -Arguments: - re points to the compiled regex block - code points to an expression - utf TRUE if in UTF mode - -Returns: SSB_FAIL => Failed to find any starting code units - SSB_DONE => Found mandatory starting code units - SSB_CONTINUE => Found optional starting code units - SSB_UNKNOWN => Hit an unrecognized opcode -*/ - -static int -set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf) -{ -register uint32_t c; -int yield = SSB_DONE; - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -int table_limit = utf? 16:32; -#else -int table_limit = 32; -#endif - -do - { - BOOL try_next = TRUE; - PCRE2_SPTR tcode = code + 1 + LINK_SIZE; - - if (*code == OP_CBRA || *code == OP_SCBRA || - *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE; - - while (try_next) /* Loop for items in this branch */ - { - int rc; - uint8_t *classmap = NULL; - - switch(*tcode) - { - /* If we reach something we don't understand, it means a new opcode has - been created that hasn't been added to this function. Hopefully this - problem will be discovered during testing. */ - - default: - return SSB_UNKNOWN; - - /* Fail for a valid opcode that implies no starting bits. */ - - case OP_ACCEPT: - case OP_ASSERT_ACCEPT: - case OP_ALLANY: - case OP_ANY: - case OP_ANYBYTE: - case OP_CIRC: - case OP_CIRCM: - case OP_CLOSE: - case OP_COMMIT: - case OP_COND: - case OP_CREF: - case OP_FALSE: - case OP_TRUE: - case OP_DNCREF: - case OP_DNREF: - case OP_DNREFI: - case OP_DNRREF: - case OP_DOLL: - case OP_DOLLM: - case OP_END: - case OP_EOD: - case OP_EODN: - case OP_EXTUNI: - case OP_FAIL: - case OP_MARK: - case OP_NOT: - case OP_NOTEXACT: - case OP_NOTEXACTI: - case OP_NOTI: - case OP_NOTMINPLUS: - case OP_NOTMINPLUSI: - case OP_NOTMINQUERY: - case OP_NOTMINQUERYI: - case OP_NOTMINSTAR: - case OP_NOTMINSTARI: - case OP_NOTMINUPTO: - case OP_NOTMINUPTOI: - case OP_NOTPLUS: - case OP_NOTPLUSI: - case OP_NOTPOSPLUS: - case OP_NOTPOSPLUSI: - case OP_NOTPOSQUERY: - case OP_NOTPOSQUERYI: - case OP_NOTPOSSTAR: - case OP_NOTPOSSTARI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - case OP_NOTPROP: - case OP_NOTQUERY: - case OP_NOTQUERYI: - case OP_NOTSTAR: - case OP_NOTSTARI: - case OP_NOTUPTO: - case OP_NOTUPTOI: - case OP_NOT_HSPACE: - case OP_NOT_VSPACE: - case OP_PRUNE: - case OP_PRUNE_ARG: - case OP_RECURSE: - case OP_REF: - case OP_REFI: - case OP_REVERSE: - case OP_RREF: - case OP_SCOND: - case OP_SET_SOM: - case OP_SKIP: - case OP_SKIP_ARG: - case OP_SOD: - case OP_SOM: - case OP_THEN: - case OP_THEN_ARG: - return SSB_FAIL; - - /* A "real" property test implies no starting bits, but the fake property - PT_CLIST identifies a list of characters. These lists are short, as they - are used for characters with more than one "other case", so there is no - point in recognizing them for OP_NOTPROP. */ - - case OP_PROP: - if (tcode[1] != PT_CLIST) return SSB_FAIL; - { - const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2]; - while ((c = *p++) < NOTACHAR) - { -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) - { - PCRE2_UCHAR buff[6]; - (void)PRIV(ord2utf)(c, buff); - c = buff[0]; - } -#endif - if (c > 0xff) SET_BIT(0xff); else SET_BIT(c); - } - } - try_next = FALSE; - break; - - /* We can ignore word boundary tests. */ - - case OP_WORD_BOUNDARY: - case OP_NOT_WORD_BOUNDARY: - tcode++; - break; - - /* If we hit a bracket or a positive lookahead assertion, recurse to set - bits from within the subpattern. If it can't find anything, we have to - give up. If it finds some mandatory character(s), we are done for this - branch. Otherwise, carry on scanning after the subpattern. */ - - case OP_BRA: - case OP_SBRA: - case OP_CBRA: - case OP_SCBRA: - case OP_BRAPOS: - case OP_SBRAPOS: - case OP_CBRAPOS: - case OP_SCBRAPOS: - case OP_ONCE: - case OP_ONCE_NC: - case OP_ASSERT: - rc = set_start_bits(re, tcode, utf); - if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; - if (rc == SSB_DONE) try_next = FALSE; else - { - do tcode += GET(tcode, 1); while (*tcode == OP_ALT); - tcode += 1 + LINK_SIZE; - } - break; - - /* If we hit ALT or KET, it means we haven't found anything mandatory in - this branch, though we might have found something optional. For ALT, we - continue with the next alternative, but we have to arrange that the final - result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET, - return SSB_CONTINUE: if this is the top level, that indicates failure, - but after a nested subpattern, it causes scanning to continue. */ - - case OP_ALT: - yield = SSB_CONTINUE; - try_next = FALSE; - break; - - case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_KETRPOS: - return SSB_CONTINUE; - - /* Skip over callout */ - - case OP_CALLOUT: - tcode += PRIV(OP_lengths)[OP_CALLOUT]; - break; - - case OP_CALLOUT_STR: - tcode += GET(tcode, 1 + 2*LINK_SIZE); - break; - - /* Skip over lookbehind and negative lookahead assertions */ - - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - do tcode += GET(tcode, 1); while (*tcode == OP_ALT); - tcode += 1 + LINK_SIZE; - break; - - /* BRAZERO does the bracket, but carries on. */ - - case OP_BRAZERO: - case OP_BRAMINZERO: - case OP_BRAPOSZERO: - rc = set_start_bits(re, ++tcode, utf); - if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; - do tcode += GET(tcode,1); while (*tcode == OP_ALT); - tcode += 1 + LINK_SIZE; - break; - - /* SKIPZERO skips the bracket. */ - - case OP_SKIPZERO: - tcode++; - do tcode += GET(tcode,1); while (*tcode == OP_ALT); - tcode += 1 + LINK_SIZE; - break; - - /* Single-char * or ? sets the bit and tries the next item */ - - case OP_STAR: - case OP_MINSTAR: - case OP_POSSTAR: - case OP_QUERY: - case OP_MINQUERY: - case OP_POSQUERY: - tcode = set_table_bit(re, tcode + 1, FALSE, utf); - break; - - case OP_STARI: - case OP_MINSTARI: - case OP_POSSTARI: - case OP_QUERYI: - case OP_MINQUERYI: - case OP_POSQUERYI: - tcode = set_table_bit(re, tcode + 1, TRUE, utf); - break; - - /* Single-char upto sets the bit and tries the next */ - - case OP_UPTO: - case OP_MINUPTO: - case OP_POSUPTO: - tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf); - break; - - case OP_UPTOI: - case OP_MINUPTOI: - case OP_POSUPTOI: - tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf); - break; - - /* At least one single char sets the bit and stops */ - - case OP_EXACT: - tcode += IMM2_SIZE; - /* Fall through */ - case OP_CHAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - (void)set_table_bit(re, tcode + 1, FALSE, utf); - try_next = FALSE; - break; - - case OP_EXACTI: - tcode += IMM2_SIZE; - /* Fall through */ - case OP_CHARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - (void)set_table_bit(re, tcode + 1, TRUE, utf); - try_next = FALSE; - break; - - /* Special spacing and line-terminating items. These recognize specific - lists of characters. The difference between VSPACE and ANYNL is that the - latter can match the two-character CRLF sequence, but that is not - relevant for finding the first character, so their code here is - identical. */ - - case OP_HSPACE: - SET_BIT(CHAR_HT); - SET_BIT(CHAR_SPACE); - - /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set - the bits for 0xA0 and for code units >= 255, independently of UTF. */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 - SET_BIT(0xA0); - SET_BIT(0xFF); -#else - /* For the 8-bit library in UTF-8 mode, set the bits for the first code - units of horizontal space characters. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - SET_BIT(0xC2); /* For U+00A0 */ - SET_BIT(0xE1); /* For U+1680, U+180E */ - SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ - SET_BIT(0xE3); /* For U+3000 */ - } - else -#endif - /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless - the code is EBCDIC. */ - { -#ifndef EBCDIC - SET_BIT(0xA0); -#endif /* Not EBCDIC */ - } -#endif /* 8-bit support */ - - try_next = FALSE; - break; - - case OP_ANYNL: - case OP_VSPACE: - SET_BIT(CHAR_LF); - SET_BIT(CHAR_VT); - SET_BIT(CHAR_FF); - SET_BIT(CHAR_CR); - - /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set - the bits for NEL and for code units >= 255, independently of UTF. */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 - SET_BIT(CHAR_NEL); - SET_BIT(0xFF); -#else - /* For the 8-bit library in UTF-8 mode, set the bits for the first code - units of vertical space characters. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - SET_BIT(0xC2); /* For U+0085 (NEL) */ - SET_BIT(0xE2); /* For U+2028, U+2029 */ - } - else -#endif - /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */ - { - SET_BIT(CHAR_NEL); - } -#endif /* 8-bit support */ - - try_next = FALSE; - break; - - /* Single character types set the bits and stop. Note that if PCRE2_UCP - is set, we do not see these op codes because \d etc are converted to - properties. Therefore, these apply in the case when only characters less - than 256 are recognized to match the types. */ - - case OP_NOT_DIGIT: - set_nottype_bits(re, cbit_digit, table_limit); - try_next = FALSE; - break; - - case OP_DIGIT: - set_type_bits(re, cbit_digit, table_limit); - try_next = FALSE; - break; - - case OP_NOT_WHITESPACE: - set_nottype_bits(re, cbit_space, table_limit); - try_next = FALSE; - break; - - case OP_WHITESPACE: - set_type_bits(re, cbit_space, table_limit); - try_next = FALSE; - break; - - case OP_NOT_WORDCHAR: - set_nottype_bits(re, cbit_word, table_limit); - try_next = FALSE; - break; - - case OP_WORDCHAR: - set_type_bits(re, cbit_word, table_limit); - try_next = FALSE; - break; - - /* One or more character type fudges the pointer and restarts, knowing - it will hit a single character type and stop there. */ - - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - tcode++; - break; - - case OP_TYPEEXACT: - tcode += 1 + IMM2_SIZE; - break; - - /* Zero or more repeats of character types set the bits and then - try again. */ - - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; /* Fall through */ - - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPOSSTAR: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSQUERY: - switch(tcode[1]) - { - default: - case OP_ANY: - case OP_ALLANY: - return SSB_FAIL; - - case OP_HSPACE: - SET_BIT(CHAR_HT); - SET_BIT(CHAR_SPACE); - - /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set - the bits for 0xA0 and for code units >= 255, independently of UTF. */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 - SET_BIT(0xA0); - SET_BIT(0xFF); -#else - /* For the 8-bit library in UTF-8 mode, set the bits for the first code - units of horizontal space characters. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - SET_BIT(0xC2); /* For U+00A0 */ - SET_BIT(0xE1); /* For U+1680, U+180E */ - SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ - SET_BIT(0xE3); /* For U+3000 */ - } - else -#endif - /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless - the code is EBCDIC. */ - { -#ifndef EBCDIC - SET_BIT(0xA0); -#endif /* Not EBCDIC */ - } -#endif /* 8-bit support */ - break; - - case OP_ANYNL: - case OP_VSPACE: - SET_BIT(CHAR_LF); - SET_BIT(CHAR_VT); - SET_BIT(CHAR_FF); - SET_BIT(CHAR_CR); - - /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set - the bits for NEL and for code units >= 255, independently of UTF. */ - -#if PCRE2_CODE_UNIT_WIDTH != 8 - SET_BIT(CHAR_NEL); - SET_BIT(0xFF); -#else - /* For the 8-bit library in UTF-8 mode, set the bits for the first code - units of vertical space characters. */ - -#ifdef SUPPORT_UNICODE - if (utf) - { - SET_BIT(0xC2); /* For U+0085 (NEL) */ - SET_BIT(0xE2); /* For U+2028, U+2029 */ - } - else -#endif - /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */ - { - SET_BIT(CHAR_NEL); - } -#endif /* 8-bit support */ - break; - - case OP_NOT_DIGIT: - set_nottype_bits(re, cbit_digit, table_limit); - break; - - case OP_DIGIT: - set_type_bits(re, cbit_digit, table_limit); - break; - - case OP_NOT_WHITESPACE: - set_nottype_bits(re, cbit_space, table_limit); - break; - - case OP_WHITESPACE: - set_type_bits(re, cbit_space, table_limit); - break; - - case OP_NOT_WORDCHAR: - set_nottype_bits(re, cbit_word, table_limit); - break; - - case OP_WORDCHAR: - set_type_bits(re, cbit_word, table_limit); - break; - } - - tcode += 2; - break; - - /* Extended class: if there are any property checks, or if this is a - negative XCLASS without a map, give up. If there are no property checks, - there must be wide characters on the XCLASS list, because otherwise an - XCLASS would not have been created. This means that code points >= 255 - are always potential starters. */ - -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: - if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0 || - (tcode[1 + LINK_SIZE] & (XCL_MAP|XCL_NOT)) == XCL_NOT) - return SSB_FAIL; - - /* We have a positive XCLASS or a negative one without a map. Set up the - map pointer if there is one, and fall through. */ - - classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL : - (uint8_t *)(tcode + 1 + LINK_SIZE + 1); -#endif - - /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are - in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter - because it starts a character with a value > 255. In 8-bit non-UTF mode, - there is no difference between CLASS and NCLASS. In all other wide - character modes, set the 0xFF bit to indicate code units >= 255. */ - - case OP_NCLASS: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) - { - re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ - memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ - } -#elif PCRE2_CODE_UNIT_WIDTH != 8 - SET_BIT(0xFF); /* For characters >= 255 */ -#endif - /* Fall through */ - - /* Enter here for a positive non-XCLASS. If we have fallen through from - an XCLASS, classmap will already be set; just advance the code pointer. - Otherwise, set up classmap for a a non-XCLASS and advance past it. */ - - case OP_CLASS: - if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else - { - classmap = (uint8_t *)(++tcode); - tcode += 32 / sizeof(PCRE2_UCHAR); - } - - /* When wide characters are supported, classmap may be NULL. In UTF-8 - (sic) mode, the bits in a class bit map correspond to character values, - not to byte values. However, the bit map we are constructing is for byte - values. So we have to do a conversion for characters whose code point is - greater than 127. In fact, there are only two possible starting bytes for - characters in the range 128 - 255. */ - - if (classmap != NULL) - { -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) - { - for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c]; - for (c = 128; c < 256; c++) - { - if ((classmap[c/8] && (1 << (c&7))) != 0) - { - int d = (c >> 6) | 0xc0; /* Set bit for this starter */ - re->start_bitmap[d/8] |= (1 << (d&7)); /* and then skip on to the */ - c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ - } - } - } - else -#endif - /* In all modes except UTF-8, the two bit maps are compatible. */ - - { - for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c]; - } - } - - /* Act on what follows the class. For a zero minimum repeat, continue; - otherwise stop processing. */ - - switch (*tcode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSQUERY: - tcode++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; - else try_next = FALSE; - break; - - default: - try_next = FALSE; - break; - } - break; /* End of class handling case */ - } /* End of switch for opcodes */ - } /* End of try_next loop */ - - code += GET(code, 1); /* Advance to next branch */ - } -while (*code == OP_ALT); - -return yield; -} - - - -/************************************************* -* Study a compiled expression * -*************************************************/ - -/* This function is handed a compiled expression that it must study to produce -information that will speed up the matching. - -Argument: points to the compiled expression -Returns: 0 normally; non-zero should never normally occur - 1 unknown opcode in set_start_bits - 2 missing capturing bracket - 3 unknown opcode in find_minlength -*/ - -int -PRIV(study)(pcre2_real_code *re) -{ -int min; -int count = 0; -PCRE2_UCHAR *code; -BOOL utf = (re->overall_options & PCRE2_UTF) != 0; - -/* Find start of compiled code */ - -code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_entry_size * re->name_count; - -/* For an anchored pattern, or an unanchored pattern that has a first code -unit, or a multiline pattern that matches only at "line start", there is no -point in seeking a list of starting code units. */ - -if ((re->overall_options & PCRE2_ANCHORED) == 0 && - (re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) - { - int rc = set_start_bits(re, code, utf); - if (rc == SSB_UNKNOWN) return 1; - if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET; - } - -/* Find the minimum length of subject string. If it can match an empty string, -the minimum length is already known. */ - -if ((re->flags & PCRE2_MATCH_EMPTY) == 0) - { - switch(min = find_minlength(re, code, code, utf, NULL, &count)) - { - case -1: /* \C in UTF mode or (*ACCEPT) or over-complex regex */ - break; /* Leave minlength unchanged (will be zero) */ - - case -2: - return 2; /* missing capturing bracket */ - - case -3: - return 3; /* unrecognized opcode */ - - default: - if (min > UINT16_MAX) min = UINT16_MAX; - re->minlength = min; - break; - } - } - -return 0; -} - -/* End of pcre2_study.c */ diff --git a/pcre2/src/pcre2_substitute.c b/pcre2/src/pcre2_substitute.c deleted file mode 100644 index 0bf781efc..000000000 --- a/pcre2/src/pcre2_substitute.c +++ /dev/null @@ -1,850 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - -#define PTR_STACK_SIZE 20 - -#define SUBSTITUTE_OPTIONS \ - (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \ - PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \ - PCRE2_SUBSTITUTE_UNSET_EMPTY) - - - -/************************************************* -* Find end of substitute text * -*************************************************/ - -/* In extended mode, we recognize ${name:+set text:unset text} and similar -constructions. This requires the identification of unescaped : and } -characters. This function scans for such. It must deal with nested ${ -constructions. The pointer to the text is updated, either to the required end -character, or to where an error was detected. - -Arguments: - code points to the compiled expression (for options) - ptrptr points to the pointer to the start of the text (updated) - ptrend end of the whole string - last TRUE if the last expected string (only } recognized) - -Returns: 0 on success - negative error code on failure -*/ - -static int -find_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, - BOOL last) -{ -int rc = 0; -uint32_t nestlevel = 0; -BOOL literal = FALSE; -PCRE2_SPTR ptr = *ptrptr; - -for (; ptr < ptrend; ptr++) - { - if (literal) - { - if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E) - { - literal = FALSE; - ptr += 1; - } - } - - else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) - { - if (nestlevel == 0) goto EXIT; - nestlevel--; - } - - else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT; - - else if (*ptr == CHAR_DOLLAR_SIGN) - { - if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET) - { - nestlevel++; - ptr += 1; - } - } - - else if (*ptr == CHAR_BACKSLASH) - { - int erc; - int errorcode = 0; - uint32_t ch; - - if (ptr < ptrend - 1) switch (ptr[1]) - { - case CHAR_L: - case CHAR_l: - case CHAR_U: - case CHAR_u: - ptr += 1; - continue; - } - - erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode, - code->overall_options, FALSE, NULL); - if (errorcode != 0) - { - rc = errorcode; - goto EXIT; - } - - switch(erc) - { - case 0: /* Data character */ - case ESC_E: /* Isolated \E is ignored */ - break; - - case ESC_Q: - literal = TRUE; - break; - - default: - rc = PCRE2_ERROR_BADREPESCAPE; - goto EXIT; - } - } - } - -rc = PCRE2_ERROR_REPMISSINGBRACE; /* Terminator not found */ - -EXIT: -*ptrptr = ptr; -return rc; -} - - - -/************************************************* -* Match and substitute * -*************************************************/ - -/* This function applies a compiled re to a subject string and creates a new -string with substitutions. The first 7 arguments are the same as for -pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED. - -Arguments: - code points to the compiled expression - subject points to the subject string - length length of subject string (may contain binary zeros) - start_offset where to start in the subject string - options option bits - match_data points to a match_data block, or is NULL - context points a PCRE2 context - replacement points to the replacement string - rlength length of replacement string - buffer where to put the substituted string - blength points to length of buffer; updated to length of string - -Returns: >= 0 number of substitutions made - < 0 an error code - PCRE2_ERROR_BADREPLACEMENT means invalid use of $ -*/ - -/* This macro checks for space in the buffer before copying into it. On -overflow, either give an error immediately, or keep on, accumulating the -length. */ - -#define CHECKMEMCPY(from,length) \ - if (!overflowed && lengthleft < length) \ - { \ - if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ - overflowed = TRUE; \ - extra_needed = length - lengthleft; \ - } \ - else if (overflowed) \ - { \ - extra_needed += length; \ - } \ - else \ - { \ - memcpy(buffer + buff_offset, from, CU2BYTES(length)); \ - buff_offset += length; \ - lengthleft -= length; \ - } - -/* Here's the function */ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, - PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, - pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength, - PCRE2_UCHAR *buffer, PCRE2_SIZE *blength) -{ -int rc; -int subs; -int forcecase = 0; -int forcecasereset = 0; -uint32_t ovector_count; -uint32_t goptions = 0; -uint32_t suboptions; -BOOL match_data_created = FALSE; -BOOL literal = FALSE; -BOOL overflowed = FALSE; -#ifdef SUPPORT_UNICODE -BOOL utf = (code->overall_options & PCRE2_UTF) != 0; -#endif -PCRE2_UCHAR temp[6]; -PCRE2_SPTR ptr; -PCRE2_SPTR repend; -PCRE2_SIZE extra_needed = 0; -PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; -PCRE2_SIZE *ovector; - -buff_offset = 0; -lengthleft = buff_length = *blength; -*blength = PCRE2_UNSET; - -/* Partial matching is not valid. */ - -if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0) - return PCRE2_ERROR_BADOPTION; - -/* If no match data block is provided, create one. */ - -if (match_data == NULL) - { - pcre2_general_context *gcontext = (mcontext == NULL)? - (pcre2_general_context *)code : - (pcre2_general_context *)mcontext; - match_data = pcre2_match_data_create_from_pattern(code, gcontext); - if (match_data == NULL) return PCRE2_ERROR_NOMEMORY; - match_data_created = TRUE; - } -ovector = pcre2_get_ovector_pointer(match_data); -ovector_count = pcre2_get_ovector_count(match_data); - -/* Find lengths of zero-terminated strings and the end of the replacement. */ - -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); -if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement); -repend = replacement + rlength; - -/* Check UTF replacement string if necessary. */ - -#ifdef SUPPORT_UNICODE -if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) - { - rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar)); - if (rc != 0) - { - match_data->leftchar = 0; - goto EXIT; - } - } -#endif /* SUPPORT_UNICODE */ - -/* Save the substitute options and remove them from the match options. */ - -suboptions = options & SUBSTITUTE_OPTIONS; -options &= ~SUBSTITUTE_OPTIONS; - -/* Copy up to the start offset */ - -CHECKMEMCPY(subject, start_offset); - -/* Loop for global substituting. */ - -subs = 0; -do - { - PCRE2_SPTR ptrstack[PTR_STACK_SIZE]; - uint32_t ptrstackptr = 0; - - rc = pcre2_match(code, subject, length, start_offset, options|goptions, - match_data, mcontext); - -#ifdef SUPPORT_UNICODE - if (utf) options |= PCRE2_NO_UTF_CHECK; /* Only need to check once */ -#endif - - /* Any error other than no match returns the error code. No match when not - doing the special after-empty-match global rematch, or when at the end of the - subject, breaks the global loop. Otherwise, advance the starting point by one - character, copying it to the output, and try again. */ - - if (rc < 0) - { - PCRE2_SIZE save_start; - - if (rc != PCRE2_ERROR_NOMATCH) goto EXIT; - if (goptions == 0 || start_offset >= length) break; - - /* Advance by one code point. Then, if CRLF is a valid newline sequence and - we have advanced into the middle of it, advance one more code point. In - other words, do not start in the middle of CRLF, even if CR and LF on their - own are valid newlines. */ - - save_start = start_offset++; - if (subject[start_offset-1] == CHAR_CR && - code->newline_convention != PCRE2_NEWLINE_CR && - code->newline_convention != PCRE2_NEWLINE_LF && - start_offset < length && - subject[start_offset] == CHAR_LF) - start_offset++; - - /* Otherwise, in UTF mode, advance past any secondary code points. */ - - else if ((code->overall_options & PCRE2_UTF) != 0) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80) - start_offset++; -#elif PCRE2_CODE_UNIT_WIDTH == 16 - while (start_offset < length && - (subject[start_offset] & 0xfc00) == 0xdc00) - start_offset++; -#endif - } - - /* Copy what we have advanced past, reset the special global options, and - continue to the next match. */ - - fraglength = start_offset - save_start; - CHECKMEMCPY(subject + save_start, fraglength); - goptions = 0; - continue; - } - - /* Handle a successful match. Matches that use \K to end before they start - are not supported. */ - - if (ovector[1] < ovector[0]) - { - rc = PCRE2_ERROR_BADSUBSPATTERN; - goto EXIT; - } - - /* Count substitutions with a paranoid check for integer overflow; surely no - real call to this function would ever hit this! */ - - if (subs == INT_MAX) - { - rc = PCRE2_ERROR_TOOMANYREPLACE; - goto EXIT; - } - subs++; - - /* Copy the text leading up to the match. */ - - if (rc == 0) rc = ovector_count; - fraglength = ovector[0] - start_offset; - CHECKMEMCPY(subject + start_offset, fraglength); - - /* Process the replacement string. Literal mode is set by \Q, but only in - extended mode when backslashes are being interpreted. In extended mode we - must handle nested substrings that are to be reprocessed. */ - - ptr = replacement; - for (;;) - { - uint32_t ch; - unsigned int chlen; - - /* If at the end of a nested substring, pop the stack. */ - - if (ptr >= repend) - { - if (ptrstackptr <= 0) break; /* End of replacement string */ - repend = ptrstack[--ptrstackptr]; - ptr = ptrstack[--ptrstackptr]; - continue; - } - - /* Handle the next character */ - - if (literal) - { - if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E) - { - literal = FALSE; - ptr += 2; - continue; - } - goto LOADLITERAL; - } - - /* Not in literal mode. */ - - if (*ptr == CHAR_DOLLAR_SIGN) - { - int group, n; - uint32_t special = 0; - BOOL inparens; - BOOL star; - PCRE2_SIZE sublength; - PCRE2_SPTR text1_start = NULL; - PCRE2_SPTR text1_end = NULL; - PCRE2_SPTR text2_start = NULL; - PCRE2_SPTR text2_end = NULL; - PCRE2_UCHAR next; - PCRE2_UCHAR name[33]; - - if (++ptr >= repend) goto BAD; - if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL; - - group = -1; - n = 0; - inparens = FALSE; - star = FALSE; - - if (next == CHAR_LEFT_CURLY_BRACKET) - { - if (++ptr >= repend) goto BAD; - next = *ptr; - inparens = TRUE; - } - - if (next == CHAR_ASTERISK) - { - if (++ptr >= repend) goto BAD; - next = *ptr; - star = TRUE; - } - - if (!star && next >= CHAR_0 && next <= CHAR_9) - { - group = next - CHAR_0; - while (++ptr < repend) - { - next = *ptr; - if (next < CHAR_0 || next > CHAR_9) break; - group = group * 10 + next - CHAR_0; - - /* A check for a number greater than the hightest captured group - is sufficient here; no need for a separate overflow check. If unknown - groups are to be treated as unset, just skip over any remaining - digits and carry on. */ - - if (group > code->top_bracket) - { - if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) - { - while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9); - break; - } - else - { - rc = PCRE2_ERROR_NOSUBSTRING; - goto PTREXIT; - } - } - } - } - else - { - const uint8_t *ctypes = code->tables + ctypes_offset; - while (MAX_255(next) && (ctypes[next] & ctype_word) != 0) - { - name[n++] = next; - if (n > 32) goto BAD; - if (++ptr >= repend) break; - next = *ptr; - } - if (n == 0) goto BAD; - name[n] = 0; - } - - /* In extended mode we recognize ${name:+set text:unset text} and - ${name:-default text}. */ - - if (inparens) - { - if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && - !star && ptr < repend - 2 && next == CHAR_COLON) - { - special = *(++ptr); - if (special != CHAR_PLUS && special != CHAR_MINUS) - { - rc = PCRE2_ERROR_BADSUBSTITUTION; - goto PTREXIT; - } - - text1_start = ++ptr; - rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS); - if (rc != 0) goto PTREXIT; - text1_end = ptr; - - if (special == CHAR_PLUS && *ptr == CHAR_COLON) - { - text2_start = ++ptr; - rc = find_text_end(code, &ptr, repend, TRUE); - if (rc != 0) goto PTREXIT; - text2_end = ptr; - } - } - - else - { - if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET) - { - rc = PCRE2_ERROR_REPMISSINGBRACE; - goto PTREXIT; - } - } - - ptr++; - } - - /* Have found a syntactically correct group number or name, or *name. - Only *MARK is currently recognized. */ - - if (star) - { - if (PRIV(strcmp_c8)(name, STRING_MARK) == 0) - { - PCRE2_SPTR mark = pcre2_get_mark(match_data); - if (mark != NULL) - { - PCRE2_SPTR mark_start = mark; - while (*mark != 0) mark++; - fraglength = mark - mark_start; - CHECKMEMCPY(mark_start, fraglength); - } - } - else goto BAD; - } - - /* Substitute the contents of a group. We don't use substring_copy - functions any more, in order to support case forcing. */ - - else - { - PCRE2_SPTR subptr, subptrend; - - /* Find a number for a named group. In case there are duplicate names, - search for the first one that is set. If the name is not found when - PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a - non-existent group. */ - - if (group < 0) - { - PCRE2_SPTR first, last, entry; - rc = pcre2_substring_nametable_scan(code, name, &first, &last); - if (rc == PCRE2_ERROR_NOSUBSTRING && - (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) - { - group = code->top_bracket + 1; - } - else - { - if (rc < 0) goto PTREXIT; - for (entry = first; entry <= last; entry += rc) - { - uint32_t ng = GET2(entry, 0); - if (ng < ovector_count) - { - if (group < 0) group = ng; /* First in ovector */ - if (ovector[ng*2] != PCRE2_UNSET) - { - group = ng; /* First that is set */ - break; - } - } - } - - /* If group is still negative, it means we did not find a group - that is in the ovector. Just set the first group. */ - - if (group < 0) group = GET2(first, 0); - } - } - - /* We now have a group that is identified by number. Find the length of - the captured string. If a group in a non-special substitution is unset - when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */ - - rc = pcre2_substring_length_bynumber(match_data, group, &sublength); - if (rc < 0) - { - if (rc == PCRE2_ERROR_NOSUBSTRING && - (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0) - { - rc = PCRE2_ERROR_UNSET; - } - if (rc != PCRE2_ERROR_UNSET) goto PTREXIT; /* Non-unset errors */ - if (special == 0) /* Plain substitution */ - { - if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue; - goto PTREXIT; /* Else error */ - } - } - - /* If special is '+' we have a 'set' and possibly an 'unset' text, - both of which are reprocessed when used. If special is '-' we have a - default text for when the group is unset; it must be reprocessed. */ - - if (special != 0) - { - if (special == CHAR_MINUS) - { - if (rc == 0) goto LITERAL_SUBSTITUTE; - text2_start = text1_start; - text2_end = text1_end; - } - - if (ptrstackptr >= PTR_STACK_SIZE) goto BAD; - ptrstack[ptrstackptr++] = ptr; - ptrstack[ptrstackptr++] = repend; - - if (rc == 0) - { - ptr = text1_start; - repend = text1_end; - } - else - { - ptr = text2_start; - repend = text2_end; - } - continue; - } - - /* Otherwise we have a literal substitution of a group's contents. */ - - LITERAL_SUBSTITUTE: - subptr = subject + ovector[group*2]; - subptrend = subject + ovector[group*2 + 1]; - - /* Substitute a literal string, possibly forcing alphabetic case. */ - - while (subptr < subptrend) - { - GETCHARINCTEST(ch, subptr); - if (forcecase != 0) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - uint32_t type = UCD_CHARTYPE(ch); - if (PRIV(ucp_gentype)[type] == ucp_L && - type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) - ch = UCD_OTHERCASE(ch); - } - else -#endif - { - if (((code->tables + cbits_offset + - ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1 << (ch%8))) == 0) - ch = (code->tables + fcc_offset)[ch]; - } - forcecase = forcecasereset; - } - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - CHECKMEMCPY(temp, chlen); - } - } - } - - /* Handle an escape sequence in extended mode. We can use check_escape() - to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but - the case-forcing escapes are not supported in pcre2_compile() so must be - recognized here. */ - - else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && - *ptr == CHAR_BACKSLASH) - { - int errorcode = 0; - - if (ptr < repend - 1) switch (ptr[1]) - { - case CHAR_L: - forcecase = forcecasereset = -1; - ptr += 2; - continue; - - case CHAR_l: - forcecase = -1; - forcecasereset = 0; - ptr += 2; - continue; - - case CHAR_U: - forcecase = forcecasereset = 1; - ptr += 2; - continue; - - case CHAR_u: - forcecase = 1; - forcecasereset = 0; - ptr += 2; - continue; - - default: - break; - } - - rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode, - code->overall_options, FALSE, NULL); - if (errorcode != 0) goto BADESCAPE; - ptr++; - - switch(rc) - { - case ESC_E: - forcecase = forcecasereset = 0; - continue; - - case ESC_Q: - literal = TRUE; - continue; - - case 0: /* Data character */ - goto LITERAL; - - default: - goto BADESCAPE; - } - } - - /* Handle a literal code unit */ - - else - { - LOADLITERAL: - GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */ - - LITERAL: - if (forcecase != 0) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - uint32_t type = UCD_CHARTYPE(ch); - if (PRIV(ucp_gentype)[type] == ucp_L && - type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) - ch = UCD_OTHERCASE(ch); - } - else -#endif - { - if (((code->tables + cbits_offset + - ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1 << (ch%8))) == 0) - ch = (code->tables + fcc_offset)[ch]; - } - forcecase = forcecasereset; - } - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - CHECKMEMCPY(temp, chlen); - } /* End handling a literal code unit */ - } /* End of loop for scanning the replacement. */ - - /* The replacement has been copied to the output. Update the start offset to - point to the rest of the subject string. If we matched an empty string, - do the magic for global matches. */ - - start_offset = ovector[1]; - goptions = (ovector[0] != ovector[1])? 0 : - PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART; - } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */ - -/* Copy the rest of the subject. */ - -fraglength = length - start_offset; -CHECKMEMCPY(subject + start_offset, fraglength); -temp[0] = 0; -CHECKMEMCPY(temp , 1); - -/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set, -and matching has carried on after a full buffer, in order to compute the length -needed. Otherwise, an overflow generates an immediate error return. */ - -if (overflowed) - { - rc = PCRE2_ERROR_NOMEMORY; - *blength = buff_length + extra_needed; - } - -/* After a successful execution, return the number of substitutions and set the -length of buffer used, excluding the trailing zero. */ - -else - { - rc = subs; - *blength = buff_offset - 1; - } - -EXIT: -if (match_data_created) pcre2_match_data_free(match_data); - else match_data->rc = rc; -return rc; - -NOROOM: -rc = PCRE2_ERROR_NOMEMORY; -goto EXIT; - -BAD: -rc = PCRE2_ERROR_BADREPLACEMENT; -goto PTREXIT; - -BADESCAPE: -rc = PCRE2_ERROR_BADREPESCAPE; - -PTREXIT: -*blength = (PCRE2_SIZE)(ptr - replacement); -goto EXIT; -} - -/* End of pcre2_substitute.c */ diff --git a/pcre2/src/pcre2_substring.c b/pcre2/src/pcre2_substring.c deleted file mode 100644 index 58b504d5c..000000000 --- a/pcre2/src/pcre2_substring.c +++ /dev/null @@ -1,536 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_internal.h" - - - -/************************************************* -* Copy named captured string to given buffer * -*************************************************/ - -/* This function copies a single captured substring into a given buffer, -identifying it by name. If the regex permits duplicate names, the first -substring that is set is chosen. - -Arguments: - match_data points to the match data - stringname the name of the required substring - buffer where to put the substring - sizeptr the size of the buffer, updated to the size of the substring - -Returns: if successful: zero - if not successful, a negative error code: - (1) an error from nametable_scan() - (2) an error from copy_bynumber() - (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector - (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname, - PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr) -{ -PCRE2_SPTR first, last, entry; -int failrc, entrysize; -if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) - return PCRE2_ERROR_DFA_UFUNC; -entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, - &first, &last); -if (entrysize < 0) return entrysize; -failrc = PCRE2_ERROR_UNAVAILABLE; -for (entry = first; entry <= last; entry += entrysize) - { - uint32_t n = GET2(entry, 0); - if (n < match_data->oveccount) - { - if (match_data->ovector[n*2] != PCRE2_UNSET) - return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr); - failrc = PCRE2_ERROR_UNSET; - } - } -return failrc; -} - - - -/************************************************* -* Copy numbered captured string to given buffer * -*************************************************/ - -/* This function copies a single captured substring into a given buffer, -identifying it by number. - -Arguments: - match_data points to the match data - stringnumber the number of the required substring - buffer where to put the substring - sizeptr the size of the buffer, updated to the size of the substring - -Returns: if successful: 0 - if not successful, a negative error code: - PCRE2_ERROR_NOMEMORY: buffer too small - PCRE2_ERROR_NOSUBSTRING: no such substring - PCRE2_ERROR_UNAVAILABLE: ovector too small - PCRE2_ERROR_UNSET: substring is not set -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_copy_bynumber(pcre2_match_data *match_data, - uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr) -{ -int rc; -PCRE2_SIZE size; -rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size); -if (rc < 0) return rc; -if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY; -memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2], - CU2BYTES(size)); -buffer[size] = 0; -*sizeptr = size; -return 0; -} - - - -/************************************************* -* Extract named captured string * -*************************************************/ - -/* This function copies a single captured substring, identified by name, into -new memory. If the regex permits duplicate names, the first substring that is -set is chosen. - -Arguments: - match_data pointer to match_data - stringname the name of the required substring - stringptr where to put the pointer to the new memory - sizeptr where to put the length of the substring - -Returns: if successful: zero - if not successful, a negative value: - (1) an error from nametable_scan() - (2) an error from get_bynumber() - (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector - (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_get_byname(pcre2_match_data *match_data, - PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr) -{ -PCRE2_SPTR first, last, entry; -int failrc, entrysize; -if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) - return PCRE2_ERROR_DFA_UFUNC; -entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, - &first, &last); -if (entrysize < 0) return entrysize; -failrc = PCRE2_ERROR_UNAVAILABLE; -for (entry = first; entry <= last; entry += entrysize) - { - uint32_t n = GET2(entry, 0); - if (n < match_data->oveccount) - { - if (match_data->ovector[n*2] != PCRE2_UNSET) - return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr); - failrc = PCRE2_ERROR_UNSET; - } - } -return failrc; -} - - - -/************************************************* -* Extract captured string to new memory * -*************************************************/ - -/* This function copies a single captured substring into a piece of new -memory. - -Arguments: - match_data points to match data - stringnumber the number of the required substring - stringptr where to put a pointer to the new memory - sizeptr where to put the size of the substring - -Returns: if successful: 0 - if not successful, a negative error code: - PCRE2_ERROR_NOMEMORY: failed to get memory - PCRE2_ERROR_NOSUBSTRING: no such substring - PCRE2_ERROR_UNAVAILABLE: ovector too small - PCRE2_ERROR_UNSET: substring is not set -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_get_bynumber(pcre2_match_data *match_data, - uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr) -{ -int rc; -PCRE2_SIZE size; -PCRE2_UCHAR *yield; -rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size); -if (rc < 0) return rc; -yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) + - (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data); -if (yield == NULL) return PCRE2_ERROR_NOMEMORY; -yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl)); -memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2], - CU2BYTES(size)); -yield[size] = 0; -*stringptr = yield; -*sizeptr = size; -return 0; -} - - - -/************************************************* -* Free memory obtained by get_substring * -*************************************************/ - -/* -Argument: the result of a previous pcre2_substring_get_byxxx() -Returns: nothing -*/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_substring_free(PCRE2_UCHAR *string) -{ -pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl)); -memctl->free(memctl, memctl->memory_data); -} - - - -/************************************************* -* Get length of a named substring * -*************************************************/ - -/* This function returns the length of a named captured substring. If the regex -permits duplicate names, the first substring that is set is chosen. - -Arguments: - match_data pointer to match data - stringname the name of the required substring - sizeptr where to put the length - -Returns: 0 if successful, else a negative error number -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_length_byname(pcre2_match_data *match_data, - PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr) -{ -PCRE2_SPTR first, last, entry; -int failrc, entrysize; -if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER) - return PCRE2_ERROR_DFA_UFUNC; -entrysize = pcre2_substring_nametable_scan(match_data->code, stringname, - &first, &last); -if (entrysize < 0) return entrysize; -failrc = PCRE2_ERROR_UNAVAILABLE; -for (entry = first; entry <= last; entry += entrysize) - { - uint32_t n = GET2(entry, 0); - if (n < match_data->oveccount) - { - if (match_data->ovector[n*2] != PCRE2_UNSET) - return pcre2_substring_length_bynumber(match_data, n, sizeptr); - failrc = PCRE2_ERROR_UNSET; - } - } -return failrc; -} - - - -/************************************************* -* Get length of a numbered substring * -*************************************************/ - -/* This function returns the length of a captured substring. If the start is -beyond the end (which can happen when \K is used in an assertion), it sets the -length to zero. - -Arguments: - match_data pointer to match data - stringnumber the number of the required substring - sizeptr where to put the length, if not NULL - -Returns: if successful: 0 - if not successful, a negative error code: - PCRE2_ERROR_NOSUBSTRING: no such substring - PCRE2_ERROR_UNAVAILABLE: ovector is too small - PCRE2_ERROR_UNSET: substring is not set -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_length_bynumber(pcre2_match_data *match_data, - uint32_t stringnumber, PCRE2_SIZE *sizeptr) -{ -PCRE2_SIZE left, right; -int count = match_data->rc; -if (count == PCRE2_ERROR_PARTIAL) - { - if (stringnumber > 0) return PCRE2_ERROR_PARTIAL; - count = 0; - } -else if (count < 0) return count; /* Match failed */ - -if (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER) - { - if (stringnumber > match_data->code->top_bracket) - return PCRE2_ERROR_NOSUBSTRING; - if (stringnumber >= match_data->oveccount) - return PCRE2_ERROR_UNAVAILABLE; - if (match_data->ovector[stringnumber*2] == PCRE2_UNSET) - return PCRE2_ERROR_UNSET; - } -else /* Matched using pcre2_dfa_match() */ - { - if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE; - if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET; - } - -left = match_data->ovector[stringnumber*2]; -right = match_data->ovector[stringnumber*2+1]; -if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left; -return 0; -} - - - -/************************************************* -* Extract all captured strings to new memory * -*************************************************/ - -/* This function gets one chunk of memory and builds a list of pointers and all -the captured substrings in it. A NULL pointer is put on the end of the list. -The substrings are zero-terminated, but also, if the final argument is -non-NULL, a list of lengths is also returned. This allows binary data to be -handled. - -Arguments: - match_data points to the match data - listptr set to point to the list of pointers - lengthsptr set to point to the list of lengths (may be NULL) - -Returns: if successful: 0 - if not successful, a negative error code: - PCRE2_ERROR_NOMEMORY: failed to get memory, - or a match failure code -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr, - PCRE2_SIZE **lengthsptr) -{ -int i, count, count2; -PCRE2_SIZE size; -PCRE2_SIZE *lensp; -pcre2_memctl *memp; -PCRE2_UCHAR **listp; -PCRE2_UCHAR *sp; -PCRE2_SIZE *ovector; - -if ((count = match_data->rc) < 0) return count; /* Match failed */ -if (count == 0) count = match_data->oveccount; /* Ovector too small */ - -count2 = 2*count; -ovector = match_data->ovector; -size = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *); /* For final NULL */ -if (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count; /* For lengths */ - -for (i = 0; i < count2; i += 2) - { - size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1); - if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]); - } - -memp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data); -if (memp == NULL) return PCRE2_ERROR_NOMEMORY; - -*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl)); -lensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1)); - -if (lengthsptr == NULL) - { - sp = (PCRE2_UCHAR *)lensp; - lensp = NULL; - } -else - { - *lengthsptr = lensp; - sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count); - } - -for (i = 0; i < count2; i += 2) - { - size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0; - memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size)); - *listp++ = sp; - if (lensp != NULL) *lensp++ = size; - sp += size; - *sp++ = 0; - } - -*listp = NULL; -return 0; -} - - - -/************************************************* -* Free memory obtained by substring_list_get * -*************************************************/ - -/* -Argument: the result of a previous pcre2_substring_list_get() -Returns: nothing -*/ - -PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_substring_list_free(PCRE2_SPTR *list) -{ -pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl)); -memctl->free(memctl, memctl->memory_data); -} - - - -/************************************************* -* Find (multiple) entries for named string * -*************************************************/ - -/* This function scans the nametable for a given name, using binary chop. It -returns either two pointers to the entries in the table, or, if no pointers are -given, the number of a unique group with the given name. If duplicate names are -permitted, and the name is not unique, an error is generated. - -Arguments: - code the compiled regex - stringname the name whose entries required - firstptr where to put the pointer to the first entry - lastptr where to put the pointer to the last entry - -Returns: PCRE2_ERROR_NOSUBSTRING if the name is not found - otherwise, if firstptr and lastptr are NULL: - a group number for a unique substring - else PCRE2_ERROR_NOUNIQUESUBSTRING - otherwise: - the length of each entry, having set firstptr and lastptr -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname, - PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr) -{ -uint16_t bot = 0; -uint16_t top = code->name_count; -uint16_t entrysize = code->name_entry_size; -PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code)); - -while (top > bot) - { - uint16_t mid = (top + bot) / 2; - PCRE2_SPTR entry = nametable + entrysize*mid; - int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE); - if (c == 0) - { - PCRE2_SPTR first; - PCRE2_SPTR last; - PCRE2_SPTR lastentry; - lastentry = nametable + entrysize * (code->name_count - 1); - first = last = entry; - while (first > nametable) - { - if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break; - first -= entrysize; - } - while (last < lastentry) - { - if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break; - last += entrysize; - } - if (firstptr == NULL) return (first == last)? - (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING; - *firstptr = first; - *lastptr = last; - return entrysize; - } - if (c > 0) bot = mid + 1; else top = mid; - } - -return PCRE2_ERROR_NOSUBSTRING; -} - - -/************************************************* -* Find number for named string * -*************************************************/ - -/* This function is a convenience wrapper for pcre2_substring_nametable_scan() -when it is known that names are unique. If there are duplicate names, it is not -defined which number is returned. - -Arguments: - code the compiled regex - stringname the name whose number is required - -Returns: the number of the named parenthesis, or a negative number - PCRE2_ERROR_NOSUBSTRING if not found - PCRE2_ERROR_NOUNIQUESUBSTRING if not unique -*/ - -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_substring_number_from_name(const pcre2_code *code, - PCRE2_SPTR stringname) -{ -return pcre2_substring_nametable_scan(code, stringname, NULL, NULL); -} - -/* End of pcre2_substring.c */ diff --git a/pcre2/src/pcre2_tables.c b/pcre2/src/pcre2_tables.c deleted file mode 100644 index b945ed7a7..000000000 --- a/pcre2/src/pcre2_tables.c +++ /dev/null @@ -1,765 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains some fixed tables that are used by more than one of the -PCRE code modules. The tables are also #included by the pcre2test program, -which uses macros to change their names from _pcre2_xxx to xxxx, thereby -avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is -defined. */ - -#ifndef PCRE2_PCRE2TEST /* We're compiling the library */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "pcre2_internal.h" -#endif /* PCRE2_PCRE2TEST */ - - -/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that -the definition is next to the definition of the opcodes in pcre2_internal.h. -This is mode-dependent, so is skipped when this file is included by pcre2test. */ - -#ifndef PCRE2_PCRE2TEST -const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS }; -#endif - -/* Tables of horizontal and vertical whitespace characters, suitable for -adding to classes. */ - -const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST }; -const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST }; - -/* These tables are the pairs of delimiters that are valid for callout string -arguments. For each starting delimiter there must be a matching ending -delimiter, which in fact is different only for bracket-like delimiters. */ - -const uint32_t PRIV(callout_start_delims)[] = { - CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, - CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, - CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 }; - -const uint32_t PRIV(callout_end_delims[]) = { - CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK, - CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN, - CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 }; - - -/************************************************* -* Tables for UTF-8 support * -*************************************************/ - -/* These tables are required by pcre2test in 16- or 32-bit mode, as well -as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for -handling wide characters. */ - -#if defined PCRE2_PCRE2TEST || \ - (defined SUPPORT_UNICODE && \ - defined PCRE2_CODE_UNIT_WIDTH && \ - PCRE2_CODE_UNIT_WIDTH == 8) - -/* These are the breakpoints for different numbers of bytes in a UTF-8 -character. */ - -const int PRIV(utf8_table1)[] = - { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; - -const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); - -/* These are the indicator bits and the mask for the data bits to set in the -first byte of a character, indexed by the number of additional bytes. */ - -const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; -const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; - -/* Table of the number of extra bytes, indexed by the first byte masked with -0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ - -const uint8_t PRIV(utf8_table4)[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; - -#endif /* UTF-8 support needed */ - - -#ifdef SUPPORT_UNICODE - -/* Table to translate from particular type value to the general value. */ - -const uint32_t PRIV(ucp_gentype)[] = { - ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ - ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ - ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ - ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ - ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ - ucp_P, ucp_P, /* Ps, Po */ - ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ - ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ -}; - -/* This table encodes the rules for finding the end of an extended grapheme -cluster. Every code point has a grapheme break property which is one of the -ucp_gbXX values defined in pcre2_ucp.h. The 2-dimensional table is indexed by -the properties of two adjacent code points. The left property selects a word -from the table, and the right property selects a bit from that word like this: - - PRIV(ucp_gbtable)[left-property] & (1 << right-property) - -The value is non-zero if a grapheme break is NOT permitted between the relevant -two code points. The breaking rules are as follows: - -1. Break at the start and end of text (pretty obviously). - -2. Do not break between a CR and LF; otherwise, break before and after - controls. - -3. Do not break Hangul syllable sequences, the rules for which are: - - L may be followed by L, V, LV or LVT - LV or V may be followed by V or T - LVT or T may be followed by T - -4. Do not break before extending characters. - -The next two rules are only for extended grapheme clusters (but that's what we -are implementing). - -5. Do not break before SpacingMarks. - -6. Do not break after Prepend characters. - -7. Otherwise, break everywhere. -*/ - -const uint32_t PRIV(ucp_gbtable)[] = { - (1< 0x10ffff is not permitted -PCRE2_ERROR_UTF8_ERR14 3-byte character with value 0xd800-0xdfff is not permitted -PCRE2_ERROR_UTF8_ERR15 Overlong 2-byte sequence -PCRE2_ERROR_UTF8_ERR16 Overlong 3-byte sequence -PCRE2_ERROR_UTF8_ERR17 Overlong 4-byte sequence -PCRE2_ERROR_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) -PCRE2_ERROR_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) -PCRE2_ERROR_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) -PCRE2_ERROR_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff -*/ - -for (p = string; length > 0; p++) - { - register uint32_t ab, d; - - c = *p; - length--; - - if (c < 128) continue; /* ASCII character */ - - if (c < 0xc0) /* Isolated 10xx xxxx byte */ - { - *erroroffset = (int)(p - string); - return PCRE2_ERROR_UTF8_ERR20; - } - - if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */ - { - *erroroffset = (int)(p - string); - return PCRE2_ERROR_UTF8_ERR21; - } - - ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes (1-5) */ - if (length < ab) /* Missing bytes */ - { - *erroroffset = (int)(p - string); - switch(ab - length) - { - case 1: return PCRE2_ERROR_UTF8_ERR1; - case 2: return PCRE2_ERROR_UTF8_ERR2; - case 3: return PCRE2_ERROR_UTF8_ERR3; - case 4: return PCRE2_ERROR_UTF8_ERR4; - case 5: return PCRE2_ERROR_UTF8_ERR5; - } - } - length -= ab; /* Length remaining */ - - /* Check top bits in the second byte */ - - if (((d = *(++p)) & 0xc0) != 0x80) - { - *erroroffset = (int)(p - string) - 1; - return PCRE2_ERROR_UTF8_ERR6; - } - - /* For each length, check that the remaining bytes start with the 0x80 bit - set and not the 0x40 bit. Then check for an overlong sequence, and for the - excluded range 0xd800 to 0xdfff. */ - - switch (ab) - { - /* 2-byte character. No further bytes to check for 0x80. Check first byte - for for xx00 000x (overlong sequence). */ - - case 1: if ((c & 0x3e) == 0) - { - *erroroffset = (int)(p - string) - 1; - return PCRE2_ERROR_UTF8_ERR15; - } - break; - - /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes - for 1110 0000, xx0x xxxx (overlong sequence) or - 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */ - - case 2: - if ((*(++p) & 0xc0) != 0x80) /* Third byte */ - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR7; - } - if (c == 0xe0 && (d & 0x20) == 0) - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR16; - } - if (c == 0xed && d >= 0xa0) - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR14; - } - break; - - /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 - bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a - character greater than 0x0010ffff (f4 8f bf bf) */ - - case 3: - if ((*(++p) & 0xc0) != 0x80) /* Third byte */ - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR7; - } - if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ - { - *erroroffset = (int)(p - string) - 3; - return PCRE2_ERROR_UTF8_ERR8; - } - if (c == 0xf0 && (d & 0x30) == 0) - { - *erroroffset = (int)(p - string) - 3; - return PCRE2_ERROR_UTF8_ERR17; - } - if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) - { - *erroroffset = (int)(p - string) - 3; - return PCRE2_ERROR_UTF8_ERR13; - } - break; - - /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be - rejected by the length test below. However, we do the appropriate tests - here so that overlong sequences get diagnosed, and also in case there is - ever an option for handling these larger code points. */ - - /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for - 1111 1000, xx00 0xxx */ - - case 4: - if ((*(++p) & 0xc0) != 0x80) /* Third byte */ - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR7; - } - if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ - { - *erroroffset = (int)(p - string) - 3; - return PCRE2_ERROR_UTF8_ERR8; - } - if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ - { - *erroroffset = (int)(p - string) - 4; - return PCRE2_ERROR_UTF8_ERR9; - } - if (c == 0xf8 && (d & 0x38) == 0) - { - *erroroffset = (int)(p - string) - 4; - return PCRE2_ERROR_UTF8_ERR18; - } - break; - - /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for - 1111 1100, xx00 00xx. */ - - case 5: - if ((*(++p) & 0xc0) != 0x80) /* Third byte */ - { - *erroroffset = (int)(p - string) - 2; - return PCRE2_ERROR_UTF8_ERR7; - } - if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ - { - *erroroffset = (int)(p - string) - 3; - return PCRE2_ERROR_UTF8_ERR8; - } - if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ - { - *erroroffset = (int)(p - string) - 4; - return PCRE2_ERROR_UTF8_ERR9; - } - if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ - { - *erroroffset = (int)(p - string) - 5; - return PCRE2_ERROR_UTF8_ERR10; - } - if (c == 0xfc && (d & 0x3c) == 0) - { - *erroroffset = (int)(p - string) - 5; - return PCRE2_ERROR_UTF8_ERR19; - } - break; - } - - /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are - excluded by RFC 3629. The pointer p is currently at the last byte of the - character. */ - - if (ab > 3) - { - *erroroffset = (int)(p - string) - ab; - return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12; - } - } -return 0; - - -/* ----------------- Check a UTF-16 string ----------------- */ - -#elif PCRE2_CODE_UNIT_WIDTH == 16 - -/* There's not so much work, nor so many errors, for UTF-16. -PCRE2_ERROR_UTF16_ERR1 Missing low surrogate at the end of the string -PCRE2_ERROR_UTF16_ERR2 Invalid low surrogate -PCRE2_ERROR_UTF16_ERR3 Isolated low surrogate -*/ - -for (p = string; length > 0; p++) - { - c = *p; - length--; - - if ((c & 0xf800) != 0xd800) - { - /* Normal UTF-16 code point. Neither high nor low surrogate. */ - } - else if ((c & 0x0400) == 0) - { - /* High surrogate. Must be a followed by a low surrogate. */ - if (length == 0) - { - *erroroffset = p - string; - return PCRE2_ERROR_UTF16_ERR1; - } - p++; - length--; - if ((*p & 0xfc00) != 0xdc00) - { - *erroroffset = p - string; - return PCRE2_ERROR_UTF16_ERR2; - } - } - else - { - /* Isolated low surrogate. Always an error. */ - *erroroffset = p - string; - return PCRE2_ERROR_UTF16_ERR3; - } - } -return 0; - - - -/* ----------------- Check a UTF-32 string ----------------- */ - -#else - -/* There is very little to do for a UTF-32 string. -PCRE2_ERROR_UTF32_ERR1 Surrogate character -PCRE2_ERROR_UTF32_ERR2 Character > 0x10ffff -*/ - -for (p = string; length > 0; length--, p++) - { - c = *p; - if ((c & 0xfffff800u) != 0xd800u) - { - /* Normal UTF-32 code point. Neither high nor low surrogate. */ - if (c > 0x10ffffu) - { - *erroroffset = p - string; - return PCRE2_ERROR_UTF32_ERR2; - } - } - else - { - /* A surrogate */ - *erroroffset = p - string; - return PCRE2_ERROR_UTF32_ERR1; - } - } -return 0; -#endif /* CODE_UNIT_WIDTH */ -} -#endif /* SUPPORT_UNICODE */ - -/* End of pcre2_valid_utf.c */ diff --git a/pcre2/src/pcre2_xclass.c b/pcre2/src/pcre2_xclass.c deleted file mode 100644 index 407d3f5b8..000000000 --- a/pcre2/src/pcre2_xclass.c +++ /dev/null @@ -1,271 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* This module contains an internal function that is used to match an extended -class. It is used by pcre2_auto_possessify() and by both pcre2_match() and -pcre2_def_match(). */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -#include "pcre2_internal.h" - -/************************************************* -* Match character against an XCLASS * -*************************************************/ - -/* This function is called to match a character against an extended class that -might contain codepoints above 255 and/or Unicode properties. - -Arguments: - c the character - data points to the flag code unit of the XCLASS data - utf TRUE if in UTF mode - -Returns: TRUE if character matches, else FALSE -*/ - -BOOL -PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf) -{ -PCRE2_UCHAR t; -BOOL negated = (*data & XCL_NOT) != 0; - -#if PCRE2_CODE_UNIT_WIDTH == 8 -/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ -utf = TRUE; -#endif - -/* Code points < 256 are matched against a bitmap, if one is present. If not, -we still carry on, because there may be ranges that start below 256 in the -additional data. */ - -if (c < 256) - { - if ((*data & XCL_HASPROP) == 0) - { - if ((*data & XCL_MAP) == 0) return negated; - return (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0; - } - if ((*data & XCL_MAP) != 0 && - (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0) - return !negated; /* char found */ - } - -/* First skip the bit map if present. Then match against the list of Unicode -properties or large chars or ranges that end with a large char. We won't ever -encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */ - -if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR); - -while ((t = *data++) != XCL_END) - { - uint32_t x, y; - if (t == XCL_SINGLE) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(x, data); /* macro generates multiple statements */ - } - else -#endif - x = *data++; - if (c == x) return !negated; - } - else if (t == XCL_RANGE) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(x, data); /* macro generates multiple statements */ - GETCHARINC(y, data); /* macro generates multiple statements */ - } - else -#endif - { - x = *data++; - y = *data++; - } - if (c >= x && c <= y) return !negated; - } - -#ifdef SUPPORT_UNICODE - else /* XCL_PROP & XCL_NOTPROP */ - { - const ucd_record *prop = GET_UCD(c); - BOOL isprop = t == XCL_PROP; - - switch(*data) - { - case PT_ANY: - if (isprop) return !negated; - break; - - case PT_LAMP: - if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == isprop) return !negated; - break; - - case PT_GC: - if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) - return !negated; - break; - - case PT_PC: - if ((data[1] == prop->chartype) == isprop) return !negated; - break; - - case PT_SC: - if ((data[1] == prop->script) == isprop) return !negated; - break; - - case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop) - return !negated; - break; - - /* Perl space used to exclude VT, but from Perl 5.18 it is included, - which means that Perl space and POSIX space are now identical. PCRE - was changed at release 8.34. */ - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_CASES: - VSPACE_CASES: - if (isprop) return !negated; - break; - - default: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) - return !negated; - break; - } - break; - - case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) - == isprop) - return !negated; - break; - - case PT_UCNC: - if (c < 0xa0) - { - if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT) == isprop) - return !negated; - } - else - { - if ((c < 0xd800 || c > 0xdfff) == isprop) - return !negated; - } - break; - - /* The following three properties can occur only in an XCLASS, as there - is no \p or \P coding for them. */ - - /* Graphic character. Implement this as not Z (space or separator) and - not C (other), except for Cf (format) with a few exceptions. This seems - to be what Perl does. The exceptional characters are: - - U+061C Arabic Letter Mark - U+180E Mongolian Vowel Separator - U+2066 - U+2069 Various "isolate"s - */ - - case PT_PXGRAPH: - if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && - c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) - )) == isprop) - return !negated; - break; - - /* Printable character: same as graphic, with the addition of Zs, i.e. - not Zl and not Zp, and U+180E. */ - - case PT_PXPRINT: - if ((prop->chartype != ucp_Zl && - prop->chartype != ucp_Zp && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && - c != 0x061c && (c < 0x2066 || c > 0x2069)) - )) == isprop) - return !negated; - break; - - /* Punctuation: all Unicode punctuation, plus ASCII characters that - Unicode treats as symbols rather than punctuation, for Perl - compatibility (these are $+<=>^`|~). */ - - case PT_PXPUNCT: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || - (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) - return !negated; - break; - - /* This should never occur, but compilers may mutter if there is no - default. */ - - default: - return FALSE; - } - - data += 2; - } -#else - (void)utf; /* Avoid compiler warning */ -#endif /* SUPPORT_UNICODE */ - } - -return negated; /* char did not match */ -} - -/* End of pcre2_xclass.c */ diff --git a/pcre2/src/pcre2demo.c b/pcre2/src/pcre2demo.c deleted file mode 100644 index ec51cf11c..000000000 --- a/pcre2/src/pcre2demo.c +++ /dev/null @@ -1,423 +0,0 @@ -/************************************************* -* PCRE2 DEMONSTRATION PROGRAM * -*************************************************/ - -/* This is a demonstration program to illustrate a straightforward way of -calling the PCRE2 regular expression library from a C program. See the -pcre2sample documentation for a short discussion ("man pcre2sample" if you have -the PCRE2 man pages installed). PCRE2 is a revised API for the library, and is -incompatible with the original PCRE API. - -There are actually three libraries, each supporting a different code unit -width. This demonstration program uses the 8-bit library. - -In Unix-like environments, if PCRE2 is installed in your standard system -libraries, you should be able to compile this program using this command: - -gcc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo - -If PCRE2 is not installed in a standard place, it is likely to be installed -with support for the pkg-config mechanism. If you have pkg-config, you can -compile this program using this command: - -gcc -Wall pcre2demo.c `pkg-config --cflags --libs libpcre2-8` -o pcre2demo - -If you do not have pkg-config, you may have to use this: - -gcc -Wall pcre2demo.c -I/usr/local/include -L/usr/local/lib \ - -R/usr/local/lib -lpcre2-8 -o pcre2demo - -Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and -library files for PCRE2 are installed on your system. Only some operating -systems (Solaris is one) use the -R option. - -Building under Windows: - -If you want to statically link this program against a non-dll .a file, you must -define PCRE2_STATIC before including pcre2.h, so in this environment, uncomment -the following line. */ - -/* #define PCRE2_STATIC */ - -/* This macro must be defined before including pcre2.h. For a program that uses -only one code unit width, it makes it possible to use generic function names -such as pcre2_compile(). */ - -#define PCRE2_CODE_UNIT_WIDTH 8 - -#include -#include -#include - - -/************************************************************************** -* Here is the program. The API includes the concept of "contexts" for * -* setting up unusual interface requirements for compiling and matching, * -* such as custom memory managers and non-standard newline definitions. * -* This program does not do any of this, so it makes no use of contexts, * -* always passing NULL where a context could be given. * -**************************************************************************/ - -int main(int argc, char **argv) -{ -pcre2_code *re; -PCRE2_SPTR pattern; /* PCRE2_SPTR is a pointer to unsigned code units of */ -PCRE2_SPTR subject; /* the appropriate width (8, 16, or 32 bits). */ -PCRE2_SPTR name_table; - -int crlf_is_newline; -int errornumber; -int find_all; -int i; -int namecount; -int name_entry_size; -int rc; -int utf8; - -uint32_t option_bits; -uint32_t newline; - -PCRE2_SIZE erroroffset; -PCRE2_SIZE *ovector; - -size_t subject_length; -pcre2_match_data *match_data; - - - -/************************************************************************** -* First, sort out the command line. There is only one possible option at * -* the moment, "-g" to request repeated matching to find all occurrences, * -* like Perl's /g option. We set the variable find_all to a non-zero value * -* if the -g option is present. Apart from that, there must be exactly two * -* arguments. * -**************************************************************************/ - -find_all = 0; -for (i = 1; i < argc; i++) - { - if (strcmp(argv[i], "-g") == 0) find_all = 1; - else break; - } - -/* After the options, we require exactly two arguments, which are the pattern, -and the subject string. */ - -if (argc - i != 2) - { - printf("Two arguments required: a regex and a subject string\n"); - return 1; - } - -/* As pattern and subject are char arguments, they can be straightforwardly -cast to PCRE2_SPTR as we are working in 8-bit code units. */ - -pattern = (PCRE2_SPTR)argv[i]; -subject = (PCRE2_SPTR)argv[i+1]; -subject_length = strlen((char *)subject); - - -/************************************************************************* -* Now we are going to compile the regular expression pattern, and handle * -* any errors that are detected. * -*************************************************************************/ - -re = pcre2_compile( - pattern, /* the pattern */ - PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */ - 0, /* default options */ - &errornumber, /* for error number */ - &erroroffset, /* for error offset */ - NULL); /* use default compile context */ - -/* Compilation failed: print the error message and exit. */ - -if (re == NULL) - { - PCRE2_UCHAR buffer[256]; - pcre2_get_error_message(errornumber, buffer, sizeof(buffer)); - printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, - buffer); - return 1; - } - - -/************************************************************************* -* If the compilation succeeded, we call PCRE again, in order to do a * -* pattern match against the subject string. This does just ONE match. If * -* further matching is needed, it will be done below. Before running the * -* match we must set up a match_data block for holding the result. * -*************************************************************************/ - -/* Using this function ensures that the block is exactly the right size for -the number of capturing parentheses in the pattern. */ - -match_data = pcre2_match_data_create_from_pattern(re, NULL); - -rc = pcre2_match( - re, /* the compiled pattern */ - subject, /* the subject string */ - subject_length, /* the length of the subject */ - 0, /* start at offset 0 in the subject */ - 0, /* default options */ - match_data, /* block for storing the result */ - NULL); /* use default match context */ - -/* Matching failed: handle error cases */ - -if (rc < 0) - { - switch(rc) - { - case PCRE2_ERROR_NOMATCH: printf("No match\n"); break; - /* - Handle other special cases if you like - */ - default: printf("Matching error %d\n", rc); break; - } - pcre2_match_data_free(match_data); /* Release memory used for the match */ - pcre2_code_free(re); /* data and the compiled pattern. */ - return 1; - } - -/* Match succeded. Get a pointer to the output vector, where string offsets are -stored. */ - -ovector = pcre2_get_ovector_pointer(match_data); -printf("\nMatch succeeded at offset %d\n", (int)ovector[0]); - - -/************************************************************************* -* We have found the first match within the subject string. If the output * -* vector wasn't big enough, say so. Then output any substrings that were * -* captured. * -*************************************************************************/ - -/* The output vector wasn't big enough. This should not happen, because we used -pcre2_match_data_create_from_pattern() above. */ - -if (rc == 0) - printf("ovector was not big enough for all the captured substrings\n"); - -/* Show substrings stored in the output vector by number. Obviously, in a real -application you might want to do things other than print them. */ - -for (i = 0; i < rc; i++) - { - PCRE2_SPTR substring_start = subject + ovector[2*i]; - size_t substring_length = ovector[2*i+1] - ovector[2*i]; - printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start); - } - - -/************************************************************************** -* That concludes the basic part of this demonstration program. We have * -* compiled a pattern, and performed a single match. The code that follows * -* shows first how to access named substrings, and then how to code for * -* repeated matches on the same subject. * -**************************************************************************/ - -/* See if there are any named substrings, and if so, show them by name. First -we have to extract the count of named parentheses from the pattern. */ - -(void)pcre2_pattern_info( - re, /* the compiled pattern */ - PCRE2_INFO_NAMECOUNT, /* get the number of named substrings */ - &namecount); /* where to put the answer */ - -if (namecount <= 0) printf("No named substrings\n"); else - { - PCRE2_SPTR tabptr; - printf("Named substrings\n"); - - /* Before we can access the substrings, we must extract the table for - translating names to numbers, and the size of each entry in the table. */ - - (void)pcre2_pattern_info( - re, /* the compiled pattern */ - PCRE2_INFO_NAMETABLE, /* address of the table */ - &name_table); /* where to put the answer */ - - (void)pcre2_pattern_info( - re, /* the compiled pattern */ - PCRE2_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ - &name_entry_size); /* where to put the answer */ - - /* Now we can scan the table and, for each entry, print the number, the name, - and the substring itself. In the 8-bit library the number is held in two - bytes, most significant first. */ - - tabptr = name_table; - for (i = 0; i < namecount; i++) - { - int n = (tabptr[0] << 8) | tabptr[1]; - printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, - (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]); - tabptr += name_entry_size; - } - } - - -/************************************************************************* -* If the "-g" option was given on the command line, we want to continue * -* to search for additional matches in the subject string, in a similar * -* way to the /g option in Perl. This turns out to be trickier than you * -* might think because of the possibility of matching an empty string. * -* What happens is as follows: * -* * -* If the previous match was NOT for an empty string, we can just start * -* the next match at the end of the previous one. * -* * -* If the previous match WAS for an empty string, we can't do that, as it * -* would lead to an infinite loop. Instead, a call of pcre2_match() is * -* made with the PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set. The * -* first of these tells PCRE2 that an empty string at the start of the * -* subject is not a valid match; other possibilities must be tried. The * -* second flag restricts PCRE2 to one match attempt at the initial string * -* position. If this match succeeds, an alternative to the empty string * -* match has been found, and we can print it and proceed round the loop, * -* advancing by the length of whatever was found. If this match does not * -* succeed, we still stay in the loop, advancing by just one character. * -* In UTF-8 mode, which can be set by (*UTF) in the pattern, this may be * -* more than one byte. * -* * -* However, there is a complication concerned with newlines. When the * -* newline convention is such that CRLF is a valid newline, we must * -* advance by two characters rather than one. The newline convention can * -* be set in the regex by (*CR), etc.; if not, we must find the default. * -*************************************************************************/ - -if (!find_all) /* Check for -g */ - { - pcre2_match_data_free(match_data); /* Release the memory that was used */ - pcre2_code_free(re); /* for the match data and the pattern. */ - return 0; /* Exit the program. */ - } - -/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline -sequence. First, find the options with which the regex was compiled and extract -the UTF state. */ - -(void)pcre2_pattern_info(re, PCRE2_INFO_ALLOPTIONS, &option_bits); -utf8 = (option_bits & PCRE2_UTF) != 0; - -/* Now find the newline convention and see whether CRLF is a valid newline -sequence. */ - -(void)pcre2_pattern_info(re, PCRE2_INFO_NEWLINE, &newline); -crlf_is_newline = newline == PCRE2_NEWLINE_ANY || - newline == PCRE2_NEWLINE_CRLF || - newline == PCRE2_NEWLINE_ANYCRLF; - -/* Loop for second and subsequent matches */ - -for (;;) - { - uint32_t options = 0; /* Normally no options */ - PCRE2_SIZE start_offset = ovector[1]; /* Start at end of previous match */ - - /* If the previous match was for an empty string, we are finished if we are - at the end of the subject. Otherwise, arrange to run another match at the - same point to see if a non-empty match can be found. */ - - if (ovector[0] == ovector[1]) - { - if (ovector[0] == subject_length) break; - options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; - } - - /* Run the next matching operation */ - - rc = pcre2_match( - re, /* the compiled pattern */ - subject, /* the subject string */ - subject_length, /* the length of the subject */ - start_offset, /* starting offset in the subject */ - options, /* options */ - match_data, /* block for storing the result */ - NULL); /* use default match context */ - - /* This time, a result of NOMATCH isn't an error. If the value in "options" - is zero, it just means we have found all possible matches, so the loop ends. - Otherwise, it means we have failed to find a non-empty-string match at a - point where there was a previous empty-string match. In this case, we do what - Perl does: advance the matching position by one character, and continue. We - do this by setting the "end of previous match" offset, because that is picked - up at the top of the loop as the point at which to start again. - - There are two complications: (a) When CRLF is a valid newline sequence, and - the current position is just before it, advance by an extra byte. (b) - Otherwise we must ensure that we skip an entire UTF character if we are in - UTF mode. */ - - if (rc == PCRE2_ERROR_NOMATCH) - { - if (options == 0) break; /* All matches found */ - ovector[1] = start_offset + 1; /* Advance one code unit */ - if (crlf_is_newline && /* If CRLF is newline & */ - start_offset < subject_length - 1 && /* we are at CRLF, */ - subject[start_offset] == '\r' && - subject[start_offset + 1] == '\n') - ovector[1] += 1; /* Advance by one more. */ - else if (utf8) /* Otherwise, ensure we */ - { /* advance a whole UTF-8 */ - while (ovector[1] < subject_length) /* character. */ - { - if ((subject[ovector[1]] & 0xc0) != 0x80) break; - ovector[1] += 1; - } - } - continue; /* Go round the loop again */ - } - - /* Other matching errors are not recoverable. */ - - if (rc < 0) - { - printf("Matching error %d\n", rc); - pcre2_match_data_free(match_data); - pcre2_code_free(re); - return 1; - } - - /* Match succeded */ - - printf("\nMatch succeeded again at offset %d\n", (int)ovector[0]); - - /* The match succeeded, but the output vector wasn't big enough. This - should not happen. */ - - if (rc == 0) - printf("ovector was not big enough for all the captured substrings\n"); - - /* As before, show substrings stored in the output vector by number, and then - also any named substrings. */ - - for (i = 0; i < rc; i++) - { - PCRE2_SPTR substring_start = subject + ovector[2*i]; - size_t substring_length = ovector[2*i+1] - ovector[2*i]; - printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start); - } - - if (namecount <= 0) printf("No named substrings\n"); else - { - PCRE2_SPTR tabptr = name_table; - printf("Named substrings\n"); - for (i = 0; i < namecount; i++) - { - int n = (tabptr[0] << 8) | tabptr[1]; - printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, - (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]); - tabptr += name_entry_size; - } - } - } /* End of loop to find second and subsequent matches */ - -printf("\n"); -pcre2_match_data_free(match_data); -pcre2_code_free(re); -return 0; -} - -/* End of pcre2demo.c */ diff --git a/pcre2/src/pcre2grep.c b/pcre2/src/pcre2grep.c deleted file mode 100644 index aadb22a57..000000000 --- a/pcre2/src/pcre2grep.c +++ /dev/null @@ -1,3270 +0,0 @@ -/************************************************* -* pcre2grep program * -*************************************************/ - -/* This is a grep program that uses the 8-bit PCRE regular expression library -via the PCRE2 updated API to do its pattern matching. On Unix-like, Windows, -and native z/OS systems it can recurse into directories, and in z/OS it can -handle PDS files. - -Note that for native z/OS, in addition to defining the NATIVE_ZOS macro, an -additional header is required. That header is not included in the main PCRE2 -distribution because other apparatus is needed to compile pcre2grep for z/OS. -The header can be found in the special z/OS distribution, which is available -from www.zaconsultants.net or from www.cbttape.org. - - Copyright (c) 1997-2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef SUPPORT_LIBZ -#include -#endif - -#ifdef SUPPORT_LIBBZ2 -#include -#endif - -#define PCRE2_CODE_UNIT_WIDTH 8 -#include "pcre2.h" - -#define FALSE 0 -#define TRUE 1 - -typedef int BOOL; - -#define OFFSET_SIZE 33 - -#if BUFSIZ > 8192 -#define MAXPATLEN BUFSIZ -#else -#define MAXPATLEN 8192 -#endif - -#define PATBUFSIZE (MAXPATLEN + 10) /* Allows for prefix+suffix */ - -/* Values for the "filenames" variable, which specifies options for file name -output. The order is important; it is assumed that a file name is wanted for -all values greater than FN_DEFAULT. */ - -enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE }; - -/* File reading styles */ - -enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 }; - -/* Actions for the -d and -D options */ - -enum { dee_READ, dee_SKIP, dee_RECURSE }; -enum { DEE_READ, DEE_SKIP }; - -/* Actions for special processing options (flag bits) */ - -#define PO_WORD_MATCH 0x0001 -#define PO_LINE_MATCH 0x0002 -#define PO_FIXED_STRINGS 0x0004 - -/* Binary file options */ - -enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT }; - -/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some -environments), a warning is issued if the value of fwrite() is ignored. -Unfortunately, casting to (void) does not suppress the warning. To get round -this, we use a macro that compiles a fudge. Oddly, this does not also seem to -apply to fprintf(). */ - -#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {} - - - -/************************************************* -* Global variables * -*************************************************/ - -/* Jeffrey Friedl has some debugging requirements that are not part of the -regular code. */ - -#ifdef JFRIEDL_DEBUG -static int S_arg = -1; -static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */ -static unsigned int jfriedl_XT = 0; /* replicate text this many times */ -static const char *jfriedl_prefix = ""; -static const char *jfriedl_postfix = ""; -#endif - -static char *colour_string = (char *)"1;31"; -static char *colour_option = NULL; -static char *dee_option = NULL; -static char *DEE_option = NULL; -static char *locale = NULL; -static char *main_buffer = NULL; -static char *newline_arg = NULL; -static char *om_separator = (char *)""; -static char *stdin_name = (char *)"(standard input)"; - -static int after_context = 0; -static int before_context = 0; -static int binary_files = BIN_BINARY; -static int both_context = 0; -static int bufthird = PCRE2GREP_BUFSIZE; -static int bufsize = 3*PCRE2GREP_BUFSIZE; -static int endlinetype; - -#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H -static int dee_action = dee_SKIP; -#else -static int dee_action = dee_READ; -#endif -static int DEE_action = DEE_READ; -static int error_count = 0; -static int filenames = FN_DEFAULT; - -#ifdef SUPPORT_PCRE2GREP_JIT -static BOOL use_jit = TRUE; -#else -static BOOL use_jit = FALSE; -#endif - -static const uint8_t *character_tables = NULL; - -static uint32_t pcre2_options = 0; -static uint32_t process_options = 0; -static uint32_t match_limit = 0; -static uint32_t recursion_limit = 0; - -static pcre2_compile_context *compile_context; -static pcre2_match_context *match_context; -static pcre2_match_data *match_data; -static PCRE2_SIZE *offsets; - -static BOOL count_only = FALSE; -static BOOL do_colour = FALSE; -static BOOL file_offsets = FALSE; -static BOOL hyphenpending = FALSE; -static BOOL invert = FALSE; -static BOOL line_buffered = FALSE; -static BOOL line_offsets = FALSE; -static BOOL multiline = FALSE; -static BOOL number = FALSE; -static BOOL omit_zero_count = FALSE; -static BOOL resource_error = FALSE; -static BOOL quiet = FALSE; -static BOOL show_only_matching = FALSE; -static BOOL silent = FALSE; -static BOOL utf = FALSE; - -/* Structure for list of --only-matching capturing numbers. */ - -typedef struct omstr { - struct omstr *next; - int groupnum; -} omstr; - -static omstr *only_matching = NULL; -static omstr *only_matching_last = NULL; - -/* Structure for holding the two variables that describe a number chain. */ - -typedef struct omdatastr { - omstr **anchor; - omstr **lastptr; -} omdatastr; - -static omdatastr only_matching_data = { &only_matching, &only_matching_last }; - -/* Structure for list of file names (for -f and --{in,ex}clude-from) */ - -typedef struct fnstr { - struct fnstr *next; - char *name; -} fnstr; - -static fnstr *exclude_from = NULL; -static fnstr *exclude_from_last = NULL; -static fnstr *include_from = NULL; -static fnstr *include_from_last = NULL; - -static fnstr *file_lists = NULL; -static fnstr *file_lists_last = NULL; -static fnstr *pattern_files = NULL; -static fnstr *pattern_files_last = NULL; - -/* Structure for holding the two variables that describe a file name chain. */ - -typedef struct fndatastr { - fnstr **anchor; - fnstr **lastptr; -} fndatastr; - -static fndatastr exclude_from_data = { &exclude_from, &exclude_from_last }; -static fndatastr include_from_data = { &include_from, &include_from_last }; -static fndatastr file_lists_data = { &file_lists, &file_lists_last }; -static fndatastr pattern_files_data = { &pattern_files, &pattern_files_last }; - -/* Structure for pattern and its compiled form; used for matching patterns and -also for include/exclude patterns. */ - -typedef struct patstr { - struct patstr *next; - char *string; - pcre2_code *compiled; -} patstr; - -static patstr *patterns = NULL; -static patstr *patterns_last = NULL; -static patstr *include_patterns = NULL; -static patstr *include_patterns_last = NULL; -static patstr *exclude_patterns = NULL; -static patstr *exclude_patterns_last = NULL; -static patstr *include_dir_patterns = NULL; -static patstr *include_dir_patterns_last = NULL; -static patstr *exclude_dir_patterns = NULL; -static patstr *exclude_dir_patterns_last = NULL; - -/* Structure holding the two variables that describe a pattern chain. A pointer -to such structures is used for each appropriate option. */ - -typedef struct patdatastr { - patstr **anchor; - patstr **lastptr; -} patdatastr; - -static patdatastr match_patdata = { &patterns, &patterns_last }; -static patdatastr include_patdata = { &include_patterns, &include_patterns_last }; -static patdatastr exclude_patdata = { &exclude_patterns, &exclude_patterns_last }; -static patdatastr include_dir_patdata = { &include_dir_patterns, &include_dir_patterns_last }; -static patdatastr exclude_dir_patdata = { &exclude_dir_patterns, &exclude_dir_patterns_last }; - -static patstr **incexlist[4] = { &include_patterns, &exclude_patterns, - &include_dir_patterns, &exclude_dir_patterns }; - -static const char *incexname[4] = { "--include", "--exclude", - "--include-dir", "--exclude-dir" }; - -/* Structure for options and list of them */ - -enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_U32NUMBER, - OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES }; - -typedef struct option_item { - int type; - int one_char; - void *dataptr; - const char *long_name; - const char *help_text; -} option_item; - -/* Options without a single-letter equivalent get a negative value. This can be -used to identify them. */ - -#define N_COLOUR (-1) -#define N_EXCLUDE (-2) -#define N_EXCLUDE_DIR (-3) -#define N_HELP (-4) -#define N_INCLUDE (-5) -#define N_INCLUDE_DIR (-6) -#define N_LABEL (-7) -#define N_LOCALE (-8) -#define N_NULL (-9) -#define N_LOFFSETS (-10) -#define N_FOFFSETS (-11) -#define N_LBUFFER (-12) -#define N_M_LIMIT (-13) -#define N_M_LIMIT_REC (-14) -#define N_BUFSIZE (-15) -#define N_NOJIT (-16) -#define N_FILE_LIST (-17) -#define N_BINARY_FILES (-18) -#define N_EXCLUDE_FROM (-19) -#define N_INCLUDE_FROM (-20) -#define N_OM_SEPARATOR (-21) - -static option_item optionlist[] = { - { OP_NODATA, N_NULL, NULL, "", "terminate options" }, - { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" }, - { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" }, - { OP_NODATA, 'a', NULL, "text", "treat binary files as text" }, - { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" }, - { OP_BINFILES, N_BINARY_FILES, NULL, "binary-files=word", "set treatment of binary files" }, - { OP_NUMBER, N_BUFSIZE,&bufthird, "buffer-size=number", "set processing buffer size parameter" }, - { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" }, - { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" }, - { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" }, - { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" }, - { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" }, - { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" }, - { OP_PATLIST, 'e', &match_patdata, "regex(p)=pattern", "specify pattern (may be used more than once)" }, - { OP_NODATA, 'F', NULL, "fixed-strings", "patterns are sets of newline-separated strings" }, - { OP_FILELIST, 'f', &pattern_files_data, "file=path", "read patterns from file" }, - { OP_FILELIST, N_FILE_LIST, &file_lists_data, "file-list=path","read files to search from file" }, - { OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" }, - { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" }, - { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" }, - { OP_NODATA, 'I', NULL, "", "treat binary files as not matching (ignore)" }, - { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" }, -#ifdef SUPPORT_PCRE2GREP_JIT - { OP_NODATA, N_NOJIT, NULL, "no-jit", "do not use just-in-time compiler optimization" }, -#else - { OP_NODATA, N_NOJIT, NULL, "no-jit", "ignored: this pcre2grep does not support JIT" }, -#endif - { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" }, - { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" }, - { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" }, - { OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" }, - { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" }, - { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, - { OP_U32NUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE match limit option" }, - { OP_U32NUMBER, N_M_LIMIT_REC, &recursion_limit, "recursion-limit=number", "set PCRE match recursion limit option" }, - { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, - { OP_STRING, 'N', &newline_arg, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, - { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, - { OP_OP_NUMBERS, 'o', &only_matching_data, "only-matching=n", "show only the part of the line that matched" }, - { OP_STRING, N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" }, - { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, - { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, - { OP_PATLIST, N_EXCLUDE,&exclude_patdata, "exclude=pattern","exclude matching files when recursing" }, - { OP_PATLIST, N_INCLUDE,&include_patdata, "include=pattern","include matching files when recursing" }, - { OP_PATLIST, N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude-dir=pattern","exclude matching directories when recursing" }, - { OP_PATLIST, N_INCLUDE_DIR,&include_dir_patdata, "include-dir=pattern","include matching directories when recursing" }, - { OP_FILELIST, N_EXCLUDE_FROM,&exclude_from_data, "exclude-from=path", "read exclude list from file" }, - { OP_FILELIST, N_INCLUDE_FROM,&include_from_data, "include-from=path", "read include list from file" }, -#ifdef JFRIEDL_DEBUG - { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, -#endif - { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, - { OP_NODATA, 'u', NULL, "utf", "use UTF mode" }, - { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, - { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, - { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" }, - { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" }, - { OP_NODATA, 0, NULL, NULL, NULL } -}; - -/* Table of names for newline types. Must be kept in step with the definitions -of PCRE2_NEWLINE_xx in pcre2.h. */ - -static const char *newlines[] = { - "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" }; - -/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F -options. These set the 1, 2, and 4 bits in process_options, respectively. Note -that the combination of -w and -x has the same effect as -x on its own, so we -can treat them as the same. Note that the MAXPATLEN macro assumes the longest -prefix+suffix is 10 characters; if anything longer is added, it must be -adjusted. */ - -static const char *prefix[] = { - "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" }; - -static const char *suffix[] = { - "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" }; - -/* UTF-8 tables - used only when the newline setting is "any". */ - -const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; - -const char utf8_table4[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; - - - -/************************************************* -* Case-independent string compare * -*************************************************/ - -static int -strcmpic(const char *str1, const char *str2) -{ -unsigned int c1, c2; -while (*str1 != '\0' || *str2 != '\0') - { - c1 = tolower(*str1++); - c2 = tolower(*str2++); - if (c1 != c2) return ((c1 > c2) << 1) - 1; - } -return 0; -} - - - -/************************************************* -* Exit from the program * -*************************************************/ - -/* If there has been a resource error, give a suitable message. - -Argument: the return code -Returns: does not return -*/ - -static void -pcre2grep_exit(int rc) -{ -if (resource_error) - { - fprintf(stderr, "pcre2grep: Error %d, %d or %d means that a resource limit " - "was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT, - PCRE2_ERROR_RECURSIONLIMIT); - fprintf(stderr, "pcre2grep: Check your regex for nested unlimited loops.\n"); - } -exit(rc); -} - - -/************************************************* -* Add item to chain of patterns * -*************************************************/ - -/* Used to add an item onto a chain, or just return an unconnected item if the -"after" argument is NULL. - -Arguments: - s pattern string to add - after if not NULL points to item to insert after - -Returns: new pattern block or NULL on error -*/ - -static patstr * -add_pattern(char *s, patstr *after) -{ -patstr *p = (patstr *)malloc(sizeof(patstr)); -if (p == NULL) - { - fprintf(stderr, "pcre2grep: malloc failed\n"); - pcre2grep_exit(2); - } -if (strlen(s) > MAXPATLEN) - { - fprintf(stderr, "pcre2grep: pattern is too long (limit is %d bytes)\n", - MAXPATLEN); - free(p); - return NULL; - } -p->next = NULL; -p->string = s; -p->compiled = NULL; - -if (after != NULL) - { - p->next = after->next; - after->next = p; - } -return p; -} - - -/************************************************* -* Free chain of patterns * -*************************************************/ - -/* Used for several chains of patterns. - -Argument: pointer to start of chain -Returns: nothing -*/ - -static void -free_pattern_chain(patstr *pc) -{ -while (pc != NULL) - { - patstr *p = pc; - pc = p->next; - if (p->compiled != NULL) pcre2_code_free(p->compiled); - free(p); - } -} - - -/************************************************* -* Free chain of file names * -*************************************************/ - -/* -Argument: pointer to start of chain -Returns: nothing -*/ - -static void -free_file_chain(fnstr *fn) -{ -while (fn != NULL) - { - fnstr *f = fn; - fn = f->next; - free(f); - } -} - - -/************************************************* -* OS-specific functions * -*************************************************/ - -/* These functions are defined so that they can be made system specific. -At present there are versions for Unix-style environments, Windows, native -z/OS, and "no support". */ - - -/************* Directory scanning Unix-style and z/OS ***********/ - -#if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS -#include -#include -#include - -#if defined NATIVE_ZOS -/************* Directory and PDS/E scanning for z/OS ***********/ -/************* z/OS looks mostly like Unix with USS ************/ -/* However, z/OS needs the #include statements in this header */ -#include "pcrzosfs.h" -/* That header is not included in the main PCRE distribution because - other apparatus is needed to compile pcre2grep for z/OS. The header - can be found in the special z/OS distribution, which is available - from www.zaconsultants.net or from www.cbttape.org. */ -#endif - -typedef DIR directory_type; -#define FILESEP '/' - -static int -isdirectory(char *filename) -{ -struct stat statbuf; -if (stat(filename, &statbuf) < 0) - return 0; /* In the expectation that opening as a file will fail */ -return S_ISDIR(statbuf.st_mode); -} - -static directory_type * -opendirectory(char *filename) -{ -return opendir(filename); -} - -static char * -readdirectory(directory_type *dir) -{ -for (;;) - { - struct dirent *dent = readdir(dir); - if (dent == NULL) return NULL; - if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) - return dent->d_name; - } -/* Control never reaches here */ -} - -static void -closedirectory(directory_type *dir) -{ -closedir(dir); -} - - -/************* Test for regular file, Unix-style **********/ - -static int -isregfile(char *filename) -{ -struct stat statbuf; -if (stat(filename, &statbuf) < 0) - return 1; /* In the expectation that opening as a file will fail */ -return S_ISREG(statbuf.st_mode); -} - - -#if defined NATIVE_ZOS -/************* Test for a terminal in z/OS **********/ -/* isatty() does not work in a TSO environment, so always give FALSE.*/ - -static BOOL -is_stdout_tty(void) -{ -return FALSE; -} - -static BOOL -is_file_tty(FILE *f) -{ -return FALSE; -} - - -/************* Test for a terminal, Unix-style **********/ - -#else -static BOOL -is_stdout_tty(void) -{ -return isatty(fileno(stdout)); -} - -static BOOL -is_file_tty(FILE *f) -{ -return isatty(fileno(f)); -} -#endif - -/* End of Unix-style or native z/OS environment functions. */ - - -/************* Directory scanning in Windows ***********/ - -/* I (Philip Hazel) have no means of testing this code. It was contributed by -Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES -when it did not exist. David Byron added a patch that moved the #include of - to before the INVALID_FILE_ATTRIBUTES definition rather than after. -The double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is -undefined when it is indeed undefined. */ - -#elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H - -#ifndef STRICT -# define STRICT -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif - -#include - -#ifndef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF -#endif - -typedef struct directory_type -{ -HANDLE handle; -BOOL first; -WIN32_FIND_DATA data; -} directory_type; - -#define FILESEP '/' - -int -isdirectory(char *filename) -{ -DWORD attr = GetFileAttributes(filename); -if (attr == INVALID_FILE_ATTRIBUTES) - return 0; -return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; -} - -directory_type * -opendirectory(char *filename) -{ -size_t len; -char *pattern; -directory_type *dir; -DWORD err; -len = strlen(filename); -pattern = (char *)malloc(len + 3); -dir = (directory_type *)malloc(sizeof(*dir)); -if ((pattern == NULL) || (dir == NULL)) - { - fprintf(stderr, "pcre2grep: malloc failed\n"); - pcre2grep_exit(2); - } -memcpy(pattern, filename, len); -memcpy(&(pattern[len]), "\\*", 3); -dir->handle = FindFirstFile(pattern, &(dir->data)); -if (dir->handle != INVALID_HANDLE_VALUE) - { - free(pattern); - dir->first = TRUE; - return dir; - } -err = GetLastError(); -free(pattern); -free(dir); -errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; -return NULL; -} - -char * -readdirectory(directory_type *dir) -{ -for (;;) - { - if (!dir->first) - { - if (!FindNextFile(dir->handle, &(dir->data))) - return NULL; - } - else - { - dir->first = FALSE; - } - if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) - return dir->data.cFileName; - } -#ifndef _MSC_VER -return NULL; /* Keep compiler happy; never executed */ -#endif -} - -void -closedirectory(directory_type *dir) -{ -FindClose(dir->handle); -free(dir); -} - - -/************* Test for regular file in Windows **********/ - -/* I don't know how to do this, or if it can be done; assume all paths are -regular if they are not directories. */ - -int isregfile(char *filename) -{ -return !isdirectory(filename); -} - - -/************* Test for a terminal in Windows **********/ - -/* I don't know how to do this; assume never */ - -static BOOL -is_stdout_tty(void) -{ -return FALSE; -} - -static BOOL -is_file_tty(FILE *f) -{ -return FALSE; -} - -/* End of Windows functions */ - - -/************* Directory scanning when we can't do it ***********/ - -/* The type is void, and apart from isdirectory(), the functions do nothing. */ - -#else - -#define FILESEP 0 -typedef void directory_type; - -int isdirectory(char *filename) { return 0; } -directory_type * opendirectory(char *filename) { return (directory_type*)0;} -char *readdirectory(directory_type *dir) { return (char*)0;} -void closedirectory(directory_type *dir) {} - - -/************* Test for regular file when we can't do it **********/ - -/* Assume all files are regular. */ - -int isregfile(char *filename) { return 1; } - - -/************* Test for a terminal when we can't do it **********/ - -static BOOL -is_stdout_tty(void) -{ -return FALSE; -} - -static BOOL -is_file_tty(FILE *f) -{ -return FALSE; -} - -#endif /* End of system-specific functions */ - - - -#ifndef HAVE_STRERROR -/************************************************* -* Provide strerror() for non-ANSI libraries * -*************************************************/ - -/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() -in their libraries, but can provide the same facility by this simple -alternative function. */ - -extern int sys_nerr; -extern char *sys_errlist[]; - -char * -strerror(int n) -{ -if (n < 0 || n >= sys_nerr) return "unknown error number"; -return sys_errlist[n]; -} -#endif /* HAVE_STRERROR */ - - - -/************************************************* -* Usage function * -*************************************************/ - -static int -usage(int rc) -{ -option_item *op; -fprintf(stderr, "Usage: pcre2grep [-"); -for (op = optionlist; op->one_char != 0; op++) - { - if (op->one_char > 0) fprintf(stderr, "%c", op->one_char); - } -fprintf(stderr, "] [long options] [pattern] [files]\n"); -fprintf(stderr, "Type `pcre2grep --help' for more information and the long " - "options.\n"); -return rc; -} - - - -/************************************************* -* Help function * -*************************************************/ - -static void -help(void) -{ -option_item *op; - -printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); -printf("Search for PATTERN in each FILE or standard input.\n"); -printf("PATTERN must be present if neither -e nor -f is used.\n"); -printf("\"-\" can be used as a file name to mean STDIN.\n"); - -#ifdef SUPPORT_LIBZ -printf("Files whose names end in .gz are read using zlib.\n"); -#endif - -#ifdef SUPPORT_LIBBZ2 -printf("Files whose names end in .bz2 are read using bzlib2.\n"); -#endif - -#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 -printf("Other files and the standard input are read as plain files.\n\n"); -#else -printf("All files are read as plain files, without any interpretation.\n\n"); -#endif - -printf("Example: pcre2grep -i 'hello.*world' menu.h main.c\n\n"); -printf("Options:\n"); - -for (op = optionlist; op->one_char != 0; op++) - { - int n; - char s[4]; - - if (op->one_char > 0 && (op->long_name)[0] == 0) - n = 31 - printf(" -%c", op->one_char); - else - { - if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); - else strcpy(s, " "); - n = 31 - printf(" %s --%s", s, op->long_name); - } - - if (n < 1) n = 1; - printf("%.*s%s\n", n, " ", op->help_text); - } - -printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n"); -printf("The default value for --buffer-size is %d.\n", PCRE2GREP_BUFSIZE); -printf("When reading patterns or file names from a file, trailing white\n"); -printf("space is removed and blank lines are ignored.\n"); -printf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN); - -printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); -printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); -} - - - -/************************************************* -* Test exclude/includes * -*************************************************/ - -/* If any exclude pattern matches, the path is excluded. Otherwise, unless -there are no includes, the path must match an include pattern. - -Arguments: - path the path to be matched - ip the chain of include patterns - ep the chain of exclude patterns - -Returns: TRUE if the path is not excluded -*/ - -static BOOL -test_incexc(char *path, patstr *ip, patstr *ep) -{ -int plen = strlen((const char *)path); - -for (; ep != NULL; ep = ep->next) - { - if (pcre2_match(ep->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0) - return FALSE; - } - -if (ip == NULL) return TRUE; - -for (; ip != NULL; ip = ip->next) - { - if (pcre2_match(ip->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0) - return TRUE; - } - -return FALSE; -} - - - -/************************************************* -* Decode integer argument value * -*************************************************/ - -/* Integer arguments can be followed by K or M. Avoid the use of strtoul() -because SunOS4 doesn't have it. This is used only for unpicking arguments, so -just keep it simple. - -Arguments: - option_data the option data string - op the option item (for error messages) - longop TRUE if option given in long form - -Returns: a long integer -*/ - -static long int -decode_number(char *option_data, option_item *op, BOOL longop) -{ -unsigned long int n = 0; -char *endptr = option_data; -while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++; -while (isdigit((unsigned char)(*endptr))) - n = n * 10 + (int)(*endptr++ - '0'); -if (toupper(*endptr) == 'K') - { - n *= 1024; - endptr++; - } -else if (toupper(*endptr) == 'M') - { - n *= 1024*1024; - endptr++; - } - -if (*endptr != 0) /* Error */ - { - if (longop) - { - char *equals = strchr(op->long_name, '='); - int nlen = (equals == NULL)? (int)strlen(op->long_name) : - (int)(equals - op->long_name); - fprintf(stderr, "pcre2grep: Malformed number \"%s\" after --%.*s\n", - option_data, nlen, op->long_name); - } - else - fprintf(stderr, "pcre2grep: Malformed number \"%s\" after -%c\n", - option_data, op->one_char); - pcre2grep_exit(usage(2)); - } - -return n; -} - - - -/************************************************* -* Add item to a chain of numbers * -*************************************************/ - -/* Used to add an item onto a chain, or just return an unconnected item if the -"after" argument is NULL. - -Arguments: - n the number to add - after if not NULL points to item to insert after - -Returns: new number block -*/ - -static omstr * -add_number(int n, omstr *after) -{ -omstr *om = (omstr *)malloc(sizeof(omstr)); - -if (om == NULL) - { - fprintf(stderr, "pcre2grep: malloc failed\n"); - pcre2grep_exit(2); - } -om->next = NULL; -om->groupnum = n; - -if (after != NULL) - { - om->next = after->next; - after->next = om; - } -return om; -} - - - -/************************************************* -* Read one line of input * -*************************************************/ - -/* Normally, input is read using fread() into a large buffer, so many lines may -be read at once. However, doing this for tty input means that no output appears -until a lot of input has been typed. Instead, tty input is handled line by -line. We cannot use fgets() for this, because it does not stop at a binary -zero, and therefore there is no way of telling how many characters it has read, -because there may be binary zeros embedded in the data. - -Arguments: - buffer the buffer to read into - length the maximum number of characters to read - f the file - -Returns: the number of characters read, zero at end of file -*/ - -static unsigned int -read_one_line(char *buffer, int length, FILE *f) -{ -int c; -int yield = 0; -while ((c = fgetc(f)) != EOF) - { - buffer[yield++] = c; - if (c == '\n' || yield >= length) break; - } -return yield; -} - - - -/************************************************* -* Find end of line * -*************************************************/ - -/* The length of the endline sequence that is found is set via lenptr. This may -be zero at the very end of the file if there is no line-ending sequence there. - -Arguments: - p current position in line - endptr end of available data - lenptr where to put the length of the eol sequence - -Returns: pointer after the last byte of the line, - including the newline byte(s) -*/ - -static char * -end_of_line(char *p, char *endptr, int *lenptr) -{ -switch(endlinetype) - { - default: /* Just in case */ - case PCRE2_NEWLINE_LF: - while (p < endptr && *p != '\n') p++; - if (p < endptr) - { - *lenptr = 1; - return p + 1; - } - *lenptr = 0; - return endptr; - - case PCRE2_NEWLINE_CR: - while (p < endptr && *p != '\r') p++; - if (p < endptr) - { - *lenptr = 1; - return p + 1; - } - *lenptr = 0; - return endptr; - - case PCRE2_NEWLINE_CRLF: - for (;;) - { - while (p < endptr && *p != '\r') p++; - if (++p >= endptr) - { - *lenptr = 0; - return endptr; - } - if (*p == '\n') - { - *lenptr = 2; - return p + 1; - } - } - break; - - case PCRE2_NEWLINE_ANYCRLF: - while (p < endptr) - { - int extra = 0; - register int c = *((unsigned char *)p); - - if (utf && c >= 0xc0) - { - int gcii, gcss; - extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ - gcss = 6*extra; - c = (c & utf8_table3[extra]) << gcss; - for (gcii = 1; gcii <= extra; gcii++) - { - gcss -= 6; - c |= (p[gcii] & 0x3f) << gcss; - } - } - - p += 1 + extra; - - switch (c) - { - case '\n': - *lenptr = 1; - return p; - - case '\r': - if (p < endptr && *p == '\n') - { - *lenptr = 2; - p++; - } - else *lenptr = 1; - return p; - - default: - break; - } - } /* End of loop for ANYCRLF case */ - - *lenptr = 0; /* Must have hit the end */ - return endptr; - - case PCRE2_NEWLINE_ANY: - while (p < endptr) - { - int extra = 0; - register int c = *((unsigned char *)p); - - if (utf && c >= 0xc0) - { - int gcii, gcss; - extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ - gcss = 6*extra; - c = (c & utf8_table3[extra]) << gcss; - for (gcii = 1; gcii <= extra; gcii++) - { - gcss -= 6; - c |= (p[gcii] & 0x3f) << gcss; - } - } - - p += 1 + extra; - - switch (c) - { - case '\n': /* LF */ - case '\v': /* VT */ - case '\f': /* FF */ - *lenptr = 1; - return p; - - case '\r': /* CR */ - if (p < endptr && *p == '\n') - { - *lenptr = 2; - p++; - } - else *lenptr = 1; - return p; - -#ifndef EBCDIC - case 0x85: /* Unicode NEL */ - *lenptr = utf? 2 : 1; - return p; - - case 0x2028: /* Unicode LS */ - case 0x2029: /* Unicode PS */ - *lenptr = 3; - return p; -#endif /* Not EBCDIC */ - - default: - break; - } - } /* End of loop for ANY case */ - - *lenptr = 0; /* Must have hit the end */ - return endptr; - } /* End of overall switch */ -} - - - -/************************************************* -* Find start of previous line * -*************************************************/ - -/* This is called when looking back for before lines to print. - -Arguments: - p start of the subsequent line - startptr start of available data - -Returns: pointer to the start of the previous line -*/ - -static char * -previous_line(char *p, char *startptr) -{ -switch(endlinetype) - { - default: /* Just in case */ - case PCRE2_NEWLINE_LF: - p--; - while (p > startptr && p[-1] != '\n') p--; - return p; - - case PCRE2_NEWLINE_CR: - p--; - while (p > startptr && p[-1] != '\n') p--; - return p; - - case PCRE2_NEWLINE_CRLF: - for (;;) - { - p -= 2; - while (p > startptr && p[-1] != '\n') p--; - if (p <= startptr + 1 || p[-2] == '\r') return p; - } - /* Control can never get here */ - - case PCRE2_NEWLINE_ANY: - case PCRE2_NEWLINE_ANYCRLF: - if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--; - if (utf) while ((*p & 0xc0) == 0x80) p--; - - while (p > startptr) - { - register unsigned int c; - char *pp = p - 1; - - if (utf) - { - int extra = 0; - while ((*pp & 0xc0) == 0x80) pp--; - c = *((unsigned char *)pp); - if (c >= 0xc0) - { - int gcii, gcss; - extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ - gcss = 6*extra; - c = (c & utf8_table3[extra]) << gcss; - for (gcii = 1; gcii <= extra; gcii++) - { - gcss -= 6; - c |= (pp[gcii] & 0x3f) << gcss; - } - } - } - else c = *((unsigned char *)pp); - - if (endlinetype == PCRE2_NEWLINE_ANYCRLF) switch (c) - { - case '\n': /* LF */ - case '\r': /* CR */ - return p; - - default: - break; - } - - else switch (c) - { - case '\n': /* LF */ - case '\v': /* VT */ - case '\f': /* FF */ - case '\r': /* CR */ -#ifndef EBCDIE - case 0x85: /* Unicode NEL */ - case 0x2028: /* Unicode LS */ - case 0x2029: /* Unicode PS */ -#endif /* Not EBCDIC */ - return p; - - default: - break; - } - - p = pp; /* Back one character */ - } /* End of loop for ANY case */ - - return startptr; /* Hit start of data */ - } /* End of overall switch */ -} - - - - - -/************************************************* -* Print the previous "after" lines * -*************************************************/ - -/* This is called if we are about to lose said lines because of buffer filling, -and at the end of the file. The data in the line is written using fwrite() so -that a binary zero does not terminate it. - -Arguments: - lastmatchnumber the number of the last matching line, plus one - lastmatchrestart where we restarted after the last match - endptr end of available data - printname filename for printing - -Returns: nothing -*/ - -static void -do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr, - char *printname) -{ -if (after_context > 0 && lastmatchnumber > 0) - { - int count = 0; - while (lastmatchrestart < endptr && count++ < after_context) - { - int ellength; - char *pp = lastmatchrestart; - if (printname != NULL) fprintf(stdout, "%s-", printname); - if (number) fprintf(stdout, "%d-", lastmatchnumber++); - pp = end_of_line(pp, endptr, &ellength); - FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); - lastmatchrestart = pp; - } - hyphenpending = TRUE; - } -} - - - -/************************************************* -* Apply patterns to subject till one matches * -*************************************************/ - -/* This function is called to run through all patterns, looking for a match. It -is used multiple times for the same subject when colouring is enabled, in order -to find all possible matches. - -Arguments: - matchptr the start of the subject - length the length of the subject to match - options options for pcre_exec - startoffset where to start matching - mrc address of where to put the result of pcre2_match() - -Returns: TRUE if there was a match - FALSE if there was no match - invert if there was a non-fatal error -*/ - -static BOOL -match_patterns(char *matchptr, size_t length, unsigned int options, - size_t startoffset, int *mrc) -{ -int i; -size_t slen = length; -patstr *p = patterns; -const char *msg = "this text:\n\n"; - -if (slen > 200) - { - slen = 200; - msg = "text that starts:\n\n"; - } -for (i = 1; p != NULL; p = p->next, i++) - { - *mrc = pcre2_match(p->compiled, (PCRE2_SPTR)matchptr, (int)length, - startoffset, options, match_data, match_context); - if (*mrc >= 0) return TRUE; - if (*mrc == PCRE2_ERROR_NOMATCH) continue; - fprintf(stderr, "pcre2grep: pcre2_match() gave error %d while matching ", *mrc); - if (patterns->next != NULL) fprintf(stderr, "pattern number %d to ", i); - fprintf(stderr, "%s", msg); - FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */ - fprintf(stderr, "\n\n"); - if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_RECURSIONLIMIT || - *mrc == PCRE2_ERROR_JIT_STACKLIMIT) - resource_error = TRUE; - if (error_count++ > 20) - { - fprintf(stderr, "pcre2grep: Too many errors - abandoned.\n"); - pcre2grep_exit(2); - } - return invert; /* No more matching; don't show the line again */ - } - -return FALSE; /* No match, no errors */ -} - - - -/************************************************* -* Grep an individual file * -*************************************************/ - -/* This is called from grep_or_recurse() below. It uses a buffer that is three -times the value of bufthird. The matching point is never allowed to stray into -the top third of the buffer, thus keeping more of the file available for -context printing or for multiline scanning. For large files, the pointer will -be in the middle third most of the time, so the bottom third is available for -"before" context printing. - -Arguments: - handle the fopened FILE stream for a normal file - the gzFile pointer when reading is via libz - the BZFILE pointer when reading is via libbz2 - frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2 - filename the file name or NULL (for errors) - printname the file name if it is to be printed for each match - or NULL if the file name is not to be printed - it cannot be NULL if filenames[_nomatch]_only is set - -Returns: 0 if there was at least one match - 1 otherwise (no matches) - 2 if an overlong line is encountered - 3 if there is a read error on a .bz2 file -*/ - -static int -pcre2grep(void *handle, int frtype, char *filename, char *printname) -{ -int rc = 1; -int linenumber = 1; -int lastmatchnumber = 0; -int count = 0; -int filepos = 0; -char *lastmatchrestart = NULL; -char *ptr = main_buffer; -char *endptr; -size_t bufflength; -BOOL binary = FALSE; -BOOL endhyphenpending = FALSE; -BOOL input_line_buffered = line_buffered; -FILE *in = NULL; /* Ensure initialized */ - -#ifdef SUPPORT_LIBZ -gzFile ingz = NULL; -#endif - -#ifdef SUPPORT_LIBBZ2 -BZFILE *inbz2 = NULL; -#endif - - -/* Do the first read into the start of the buffer and set up the pointer to end -of what we have. In the case of libz, a non-zipped .gz file will be read as a -plain file. However, if a .bz2 file isn't actually bzipped, the first read will -fail. */ - -(void)frtype; - -#ifdef SUPPORT_LIBZ -if (frtype == FR_LIBZ) - { - ingz = (gzFile)handle; - bufflength = gzread (ingz, main_buffer, bufsize); - } -else -#endif - -#ifdef SUPPORT_LIBBZ2 -if (frtype == FR_LIBBZ2) - { - inbz2 = (BZFILE *)handle; - bufflength = BZ2_bzread(inbz2, main_buffer, bufsize); - if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */ - } /* without the cast it is unsigned. */ -else -#endif - - { - in = (FILE *)handle; - if (is_file_tty(in)) input_line_buffered = TRUE; - bufflength = input_line_buffered? - read_one_line(main_buffer, bufsize, in) : - fread(main_buffer, 1, bufsize, in); - } - -endptr = main_buffer + bufflength; - -/* Unless binary-files=text, see if we have a binary file. This uses the same -rule as GNU grep, namely, a search for a binary zero byte near the start of the -file. */ - -if (binary_files != BIN_TEXT) - { - binary = - memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL; - if (binary && binary_files == BIN_NOMATCH) return 1; - } - -/* Loop while the current pointer is not at the end of the file. For large -files, endptr will be at the end of the buffer when we are in the middle of the -file, but ptr will never get there, because as soon as it gets over 2/3 of the -way, the buffer is shifted left and re-filled. */ - -while (ptr < endptr) - { - int endlinelength; - int mrc = 0; - unsigned int options = 0; - BOOL match; - char *matchptr = ptr; - char *t = ptr; - size_t length, linelength; - size_t startoffset = 0; - - /* At this point, ptr is at the start of a line. We need to find the length - of the subject string to pass to pcre_exec(). In multiline mode, it is the - length remainder of the data in the buffer. Otherwise, it is the length of - the next line, excluding the terminating newline. After matching, we always - advance by the length of the next line. In multiline mode the PCRE2_FIRSTLINE - option is used for compiling, so that any match is constrained to be in the - first line. */ - - t = end_of_line(t, endptr, &endlinelength); - linelength = t - ptr - endlinelength; - length = multiline? (size_t)(endptr - ptr) : linelength; - - /* Check to see if the line we are looking at extends right to the very end - of the buffer without a line terminator. This means the line is too long to - handle. */ - - if (endlinelength == 0 && t == main_buffer + bufsize) - { - fprintf(stderr, "pcre2grep: line %d%s%s is too long for the internal buffer\n" - "pcre2grep: check the --buffer-size option\n", - linenumber, - (filename == NULL)? "" : " of file ", - (filename == NULL)? "" : filename); - return 2; - } - - /* Extra processing for Jeffrey Friedl's debugging. */ - -#ifdef JFRIEDL_DEBUG - if (jfriedl_XT || jfriedl_XR) - { -# include -# include - struct timeval start_time, end_time; - struct timezone dummy; - int i; - - if (jfriedl_XT) - { - unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix); - const char *orig = ptr; - ptr = malloc(newlen + 1); - if (!ptr) { - printf("out of memory"); - pcre2grep_exit(2); - } - endptr = ptr; - strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix); - for (i = 0; i < jfriedl_XT; i++) { - strncpy(endptr, orig, length); - endptr += length; - } - strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix); - length = newlen; - } - - if (gettimeofday(&start_time, &dummy) != 0) - perror("bad gettimeofday"); - - - for (i = 0; i < jfriedl_XR; i++) - match = (pcre_exec(patterns->compiled, patterns->hint, ptr, length, 0, - PCRE2_NOTEMPTY, offsets, OFFSET_SIZE) >= 0); - - if (gettimeofday(&end_time, &dummy) != 0) - perror("bad gettimeofday"); - - double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0)) - - - (start_time.tv_sec + (start_time.tv_usec / 1000000.0))); - - printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta); - return 0; - } -#endif - - /* We come back here after a match when show_only_matching is set, in order - to find any further matches in the same line. This applies to - --only-matching, --file-offsets, and --line-offsets. */ - - ONLY_MATCHING_RESTART: - - /* Run through all the patterns until one matches or there is an error other - than NOMATCH. This code is in a subroutine so that it can be re-used for - finding subsequent matches when colouring matched lines. After finding one - match, set PCRE2_NOTEMPTY to disable any further matches of null strings in - this line. */ - - match = match_patterns(matchptr, length, options, startoffset, &mrc); - options = PCRE2_NOTEMPTY; - - /* If it's a match or a not-match (as required), do what's wanted. */ - - if (match != invert) - { - BOOL hyphenprinted = FALSE; - - /* We've failed if we want a file that doesn't have any matches. */ - - if (filenames == FN_NOMATCH_ONLY) return 1; - - /* If all we want is a yes/no answer, we can return immediately. */ - - if (quiet) return 0; - - /* Just count if just counting is wanted. */ - - else if (count_only) count++; - - /* When handling a binary file and binary-files==binary, the "binary" - variable will be set true (it's false in all other cases). In this - situation we just want to output the file name. No need to scan further. */ - - else if (binary) - { - fprintf(stdout, "Binary file %s matches\n", filename); - return 0; - } - - /* Likewise, if all we want is a file name, there is no need to scan any - more lines in the file. */ - - else if (filenames == FN_MATCH_ONLY) - { - fprintf(stdout, "%s\n", printname); - return 0; - } - - /* The --only-matching option prints just the substring that matched, - and/or one or more captured portions of it, as long as these strings are - not empty. The --file-offsets and --line-offsets options output offsets for - the matching substring (all three set show_only_matching). None of these - mutually exclusive options prints any context. Afterwards, adjust the start - and then jump back to look for further matches in the same line. If we are - in invert mode, however, nothing is printed and we do not restart - this - could still be useful because the return code is set. */ - - else if (show_only_matching) - { - if (!invert) - { - size_t oldstartoffset; - - if (printname != NULL) fprintf(stdout, "%s:", printname); - if (number) fprintf(stdout, "%d:", linenumber); - - /* Handle --line-offsets */ - - if (line_offsets) - fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), - (int)(offsets[1] - offsets[0])); - - /* Handle --file-offsets */ - - else if (file_offsets) - fprintf(stdout, "%d,%d\n", - (int)(filepos + matchptr + offsets[0] - ptr), - (int)(offsets[1] - offsets[0])); - - /* Handle --only-matching, which may occur many times */ - - else - { - BOOL printed = FALSE; - omstr *om; - - for (om = only_matching; om != NULL; om = om->next) - { - int n = om->groupnum; - if (n < mrc) - { - int plen = offsets[2*n + 1] - offsets[2*n]; - if (plen > 0) - { - if (printed) fprintf(stdout, "%s", om_separator); - if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); - FWRITE(matchptr + offsets[n*2], 1, plen, stdout); - if (do_colour) fprintf(stdout, "%c[00m", 0x1b); - printed = TRUE; - } - } - } - - if (printed || printname != NULL || number) fprintf(stdout, "\n"); - } - - /* Prepare to repeat to find the next match. If the pattern contained a - lookbehind that included \K, it is possible that the end of the match - might be at or before the actual starting offset we have just used. In - this case, start one character further on. */ - - match = FALSE; - if (line_buffered) fflush(stdout); - rc = 0; /* Had some success */ - startoffset = offsets[1]; /* Restart after the match */ - oldstartoffset = pcre2_get_startchar(match_data); - if (startoffset <= oldstartoffset) - { - if (startoffset >= length) goto END_ONE_MATCH; /* Were at end */ - startoffset = oldstartoffset + 1; - if (utf) - while ((matchptr[startoffset] & 0xc0) == 0x80) startoffset++; - } - goto ONLY_MATCHING_RESTART; - } - } - - /* This is the default case when none of the above options is set. We print - the matching lines(s), possibly preceded and/or followed by other lines of - context. */ - - else - { - /* See if there is a requirement to print some "after" lines from a - previous match. We never print any overlaps. */ - - if (after_context > 0 && lastmatchnumber > 0) - { - int ellength; - int linecount = 0; - char *p = lastmatchrestart; - - while (p < ptr && linecount < after_context) - { - p = end_of_line(p, ptr, &ellength); - linecount++; - } - - /* It is important to advance lastmatchrestart during this printing so - that it interacts correctly with any "before" printing below. Print - each line's data using fwrite() in case there are binary zeroes. */ - - while (lastmatchrestart < p) - { - char *pp = lastmatchrestart; - if (printname != NULL) fprintf(stdout, "%s-", printname); - if (number) fprintf(stdout, "%d-", lastmatchnumber++); - pp = end_of_line(pp, endptr, &ellength); - FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); - lastmatchrestart = pp; - } - if (lastmatchrestart != ptr) hyphenpending = TRUE; - } - - /* If there were non-contiguous lines printed above, insert hyphens. */ - - if (hyphenpending) - { - fprintf(stdout, "--\n"); - hyphenpending = FALSE; - hyphenprinted = TRUE; - } - - /* See if there is a requirement to print some "before" lines for this - match. Again, don't print overlaps. */ - - if (before_context > 0) - { - int linecount = 0; - char *p = ptr; - - while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && - linecount < before_context) - { - linecount++; - p = previous_line(p, main_buffer); - } - - if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) - fprintf(stdout, "--\n"); - - while (p < ptr) - { - int ellength; - char *pp = p; - if (printname != NULL) fprintf(stdout, "%s-", printname); - if (number) fprintf(stdout, "%d-", linenumber - linecount--); - pp = end_of_line(pp, endptr, &ellength); - FWRITE(p, 1, pp - p, stdout); - p = pp; - } - } - - /* Now print the matching line(s); ensure we set hyphenpending at the end - of the file if any context lines are being output. */ - - if (after_context > 0 || before_context > 0) - endhyphenpending = TRUE; - - if (printname != NULL) fprintf(stdout, "%s:", printname); - if (number) fprintf(stdout, "%d:", linenumber); - - /* In multiline mode, we want to print to the end of the line in which - the end of the matched string is found, so we adjust linelength and the - line number appropriately, but only when there actually was a match - (invert not set). Because the PCRE2_FIRSTLINE option is set, the start of - the match will always be before the first newline sequence. */ - - if (multiline & !invert) - { - char *endmatch = ptr + offsets[1]; - t = ptr; - while (t <= endmatch) - { - t = end_of_line(t, endptr, &endlinelength); - if (t < endmatch) linenumber++; else break; - } - linelength = t - ptr - endlinelength; - } - - /*** NOTE: Use only fwrite() to output the data line, so that binary - zeroes are treated as just another data character. */ - - /* This extra option, for Jeffrey Friedl's debugging requirements, - replaces the matched string, or a specific captured string if it exists, - with X. When this happens, colouring is ignored. */ - -#ifdef JFRIEDL_DEBUG - if (S_arg >= 0 && S_arg < mrc) - { - int first = S_arg * 2; - int last = first + 1; - FWRITE(ptr, 1, offsets[first], stdout); - fprintf(stdout, "X"); - FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout); - } - else -#endif - - /* We have to split the line(s) up if colouring, and search for further - matches, but not of course if the line is a non-match. */ - - if (do_colour && !invert) - { - int plength; - FWRITE(ptr, 1, offsets[0], stdout); - fprintf(stdout, "%c[%sm", 0x1b, colour_string); - FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); - fprintf(stdout, "%c[00m", 0x1b); - for (;;) - { - startoffset = offsets[1]; - if (startoffset >= linelength + endlinelength || - !match_patterns(matchptr, length, options, startoffset, &mrc)) - break; - FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout); - fprintf(stdout, "%c[%sm", 0x1b, colour_string); - FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout); - fprintf(stdout, "%c[00m", 0x1b); - } - - /* In multiline mode, we may have already printed the complete line - and its line-ending characters (if they matched the pattern), so there - may be no more to print. */ - - plength = (int)((linelength + endlinelength) - startoffset); - if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout); - } - - /* Not colouring; no need to search for further matches */ - - else FWRITE(ptr, 1, linelength + endlinelength, stdout); - } - - /* End of doing what has to be done for a match. If --line-buffered was - given, flush the output. */ - - if (line_buffered) fflush(stdout); - rc = 0; /* Had some success */ - - /* Remember where the last match happened for after_context. We remember - where we are about to restart, and that line's number. */ - - lastmatchrestart = ptr + linelength + endlinelength; - lastmatchnumber = linenumber + 1; - } - - /* For a match in multiline inverted mode (which of course did not cause - anything to be printed), we have to move on to the end of the match before - proceeding. */ - - if (multiline && invert && match) - { - int ellength; - char *endmatch = ptr + offsets[1]; - t = ptr; - while (t < endmatch) - { - t = end_of_line(t, endptr, &ellength); - if (t <= endmatch) linenumber++; else break; - } - endmatch = end_of_line(endmatch, endptr, &ellength); - linelength = endmatch - ptr - ellength; - } - - /* Advance to after the newline and increment the line number. The file - offset to the current line is maintained in filepos. */ - - END_ONE_MATCH: - ptr += linelength + endlinelength; - filepos += (int)(linelength + endlinelength); - linenumber++; - - /* If input is line buffered, and the buffer is not yet full, read another - line and add it into the buffer. */ - - if (input_line_buffered && bufflength < (size_t)bufsize) - { - int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in); - bufflength += add; - endptr += add; - } - - /* If we haven't yet reached the end of the file (the buffer is full), and - the current point is in the top 1/3 of the buffer, slide the buffer down by - 1/3 and refill it. Before we do this, if some unprinted "after" lines are - about to be lost, print them. */ - - if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird) - { - if (after_context > 0 && - lastmatchnumber > 0 && - lastmatchrestart < main_buffer + bufthird) - { - do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); - lastmatchnumber = 0; - } - - /* Now do the shuffle */ - - memmove(main_buffer, main_buffer + bufthird, 2*bufthird); - ptr -= bufthird; - -#ifdef SUPPORT_LIBZ - if (frtype == FR_LIBZ) - bufflength = 2*bufthird + - gzread (ingz, main_buffer + 2*bufthird, bufthird); - else -#endif - -#ifdef SUPPORT_LIBBZ2 - if (frtype == FR_LIBBZ2) - bufflength = 2*bufthird + - BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird); - else -#endif - - bufflength = 2*bufthird + - (input_line_buffered? - read_one_line(main_buffer + 2*bufthird, bufthird, in) : - fread(main_buffer + 2*bufthird, 1, bufthird, in)); - endptr = main_buffer + bufflength; - - /* Adjust any last match point */ - - if (lastmatchnumber > 0) lastmatchrestart -= bufthird; - } - } /* Loop through the whole file */ - -/* End of file; print final "after" lines if wanted; do_after_lines sets -hyphenpending if it prints something. */ - -if (!show_only_matching && !count_only) - { - do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); - hyphenpending |= endhyphenpending; - } - -/* Print the file name if we are looking for those without matches and there -were none. If we found a match, we won't have got this far. */ - -if (filenames == FN_NOMATCH_ONLY) - { - fprintf(stdout, "%s\n", printname); - return 0; - } - -/* Print the match count if wanted */ - -if (count_only && !quiet) - { - if (count > 0 || !omit_zero_count) - { - if (printname != NULL && filenames != FN_NONE) - fprintf(stdout, "%s:", printname); - fprintf(stdout, "%d\n", count); - } - } - -return rc; -} - - - -/************************************************* -* Grep a file or recurse into a directory * -*************************************************/ - -/* Given a path name, if it's a directory, scan all the files if we are -recursing; if it's a file, grep it. - -Arguments: - pathname the path to investigate - dir_recurse TRUE if recursing is wanted (-r or -drecurse) - only_one_at_top TRUE if the path is the only one at toplevel - -Returns: -1 the file/directory was skipped - 0 if there was at least one match - 1 if there were no matches - 2 there was some kind of error - -However, file opening failures are suppressed if "silent" is set. -*/ - -static int -grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top) -{ -int rc = 1; -int frtype; -void *handle; -char *lastcomp; -FILE *in = NULL; /* Ensure initialized */ - -#ifdef SUPPORT_LIBZ -gzFile ingz = NULL; -#endif - -#ifdef SUPPORT_LIBBZ2 -BZFILE *inbz2 = NULL; -#endif - -#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 -int pathlen; -#endif - -#if defined NATIVE_ZOS -int zos_type; -FILE *zos_test_file; -#endif - -/* If the file name is "-" we scan stdin */ - -if (strcmp(pathname, "-") == 0) - { - return pcre2grep(stdin, FR_PLAIN, stdin_name, - (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? - stdin_name : NULL); - } - -/* Inclusion and exclusion: --include-dir and --exclude-dir apply only to -directories, whereas --include and --exclude apply to everything else. The test -is against the final component of the path. */ - -lastcomp = strrchr(pathname, FILESEP); -lastcomp = (lastcomp == NULL)? pathname : lastcomp + 1; - -/* If the file is a directory, skip if not recursing or if explicitly excluded. -Otherwise, scan the directory and recurse for each path within it. The scanning -code is localized so it can be made system-specific. */ - - -/* For z/OS, determine the file type. */ - -#if defined NATIVE_ZOS -zos_test_file = fopen(pathname,"rb"); - -if (zos_test_file == NULL) - { - if (!silent) fprintf(stderr, "pcre2grep: failed to test next file %s\n", - pathname, strerror(errno)); - return -1; - } -zos_type = identifyzosfiletype (zos_test_file); -fclose (zos_test_file); - -/* Handle a PDS in separate code */ - -if (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE) - { - return travelonpdsdir (pathname, only_one_at_top); - } - -/* Deal with regular files in the normal way below. These types are: - zos_type == __ZOS_PDS_MEMBER - zos_type == __ZOS_PS - zos_type == __ZOS_VSAM_KSDS - zos_type == __ZOS_VSAM_ESDS - zos_type == __ZOS_VSAM_RRDS -*/ - -/* Handle a z/OS directory using common code. */ - -else if (zos_type == __ZOS_HFS) - { -#endif /* NATIVE_ZOS */ - - -/* Handle directories: common code for all OS */ - -if (isdirectory(pathname)) - { - if (dee_action == dee_SKIP || - !test_incexc(lastcomp, include_dir_patterns, exclude_dir_patterns)) - return -1; - - if (dee_action == dee_RECURSE) - { - char buffer[1024]; - char *nextfile; - directory_type *dir = opendirectory(pathname); - - if (dir == NULL) - { - if (!silent) - fprintf(stderr, "pcre2grep: Failed to open directory %s: %s\n", pathname, - strerror(errno)); - return 2; - } - - while ((nextfile = readdirectory(dir)) != NULL) - { - int frc; - sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile); - frc = grep_or_recurse(buffer, dir_recurse, FALSE); - if (frc > 1) rc = frc; - else if (frc == 0 && rc == 1) rc = 0; - } - - closedirectory(dir); - return rc; - } - } - -#if defined NATIVE_ZOS - } -#endif - -/* If the file is not a directory, check for a regular file, and if it is not, -skip it if that's been requested. Otherwise, check for an explicit inclusion or -exclusion. */ - -else if ( -#if defined NATIVE_ZOS - (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) || -#else /* all other OS */ - (!isregfile(pathname) && DEE_action == DEE_SKIP) || -#endif - !test_incexc(lastcomp, include_patterns, exclude_patterns)) - return -1; /* File skipped */ - -/* Control reaches here if we have a regular file, or if we have a directory -and recursion or skipping was not requested, or if we have anything else and -skipping was not requested. The scan proceeds. If this is the first and only -argument at top level, we don't show the file name, unless we are only showing -the file name, or the filename was forced (-H). */ - -#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 -pathlen = (int)(strlen(pathname)); -#endif - -/* Open using zlib if it is supported and the file name ends with .gz. */ - -#ifdef SUPPORT_LIBZ -if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0) - { - ingz = gzopen(pathname, "rb"); - if (ingz == NULL) - { - if (!silent) - fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname, - strerror(errno)); - return 2; - } - handle = (void *)ingz; - frtype = FR_LIBZ; - } -else -#endif - -/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */ - -#ifdef SUPPORT_LIBBZ2 -if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0) - { - inbz2 = BZ2_bzopen(pathname, "rb"); - handle = (void *)inbz2; - frtype = FR_LIBBZ2; - } -else -#endif - -/* Otherwise use plain fopen(). The label is so that we can come back here if -an attempt to read a .bz2 file indicates that it really is a plain file. */ - -#ifdef SUPPORT_LIBBZ2 -PLAIN_FILE: -#endif - { - in = fopen(pathname, "rb"); - handle = (void *)in; - frtype = FR_PLAIN; - } - -/* All the opening methods return errno when they fail. */ - -if (handle == NULL) - { - if (!silent) - fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname, - strerror(errno)); - return 2; - } - -/* Now grep the file */ - -rc = pcre2grep(handle, frtype, pathname, (filenames > FN_DEFAULT || - (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); - -/* Close in an appropriate manner. */ - -#ifdef SUPPORT_LIBZ -if (frtype == FR_LIBZ) - gzclose(ingz); -else -#endif - -/* If it is a .bz2 file and the result is 3, it means that the first attempt to -read failed. If the error indicates that the file isn't in fact bzipped, try -again as a normal file. */ - -#ifdef SUPPORT_LIBBZ2 -if (frtype == FR_LIBBZ2) - { - if (rc == 3) - { - int errnum; - const char *err = BZ2_bzerror(inbz2, &errnum); - if (errnum == BZ_DATA_ERROR_MAGIC) - { - BZ2_bzclose(inbz2); - goto PLAIN_FILE; - } - else if (!silent) - fprintf(stderr, "pcre2grep: Failed to read %s using bzlib: %s\n", - pathname, err); - rc = 2; /* The normal "something went wrong" code */ - } - BZ2_bzclose(inbz2); - } -else -#endif - -/* Normal file close */ - -fclose(in); - -/* Pass back the yield from pcre2grep(). */ - -return rc; -} - - - -/************************************************* -* Handle a single-letter, no data option * -*************************************************/ - -static int -handle_option(int letter, int options) -{ -switch(letter) - { - case N_FOFFSETS: file_offsets = TRUE; break; - case N_HELP: help(); pcre2grep_exit(0); - case N_LBUFFER: line_buffered = TRUE; break; - case N_LOFFSETS: line_offsets = number = TRUE; break; - case N_NOJIT: use_jit = FALSE; break; - case 'a': binary_files = BIN_TEXT; break; - case 'c': count_only = TRUE; break; - case 'F': process_options |= PO_FIXED_STRINGS; break; - case 'H': filenames = FN_FORCE; break; - case 'I': binary_files = BIN_NOMATCH; break; - case 'h': filenames = FN_NONE; break; - case 'i': options |= PCRE2_CASELESS; break; - case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break; - case 'L': filenames = FN_NOMATCH_ONLY; break; - case 'M': multiline = TRUE; options |= PCRE2_MULTILINE|PCRE2_FIRSTLINE; break; - case 'n': number = TRUE; break; - - case 'o': - only_matching_last = add_number(0, only_matching_last); - if (only_matching == NULL) only_matching = only_matching_last; - break; - - case 'q': quiet = TRUE; break; - case 'r': dee_action = dee_RECURSE; break; - case 's': silent = TRUE; break; - case 'u': options |= PCRE2_UTF; utf = TRUE; break; - case 'v': invert = TRUE; break; - case 'w': process_options |= PO_WORD_MATCH; break; - case 'x': process_options |= PO_LINE_MATCH; break; - - case 'V': - { - unsigned char buffer[128]; - (void)pcre2_config(PCRE2_CONFIG_VERSION, buffer); - fprintf(stdout, "pcre2grep version %s\n", buffer); - } - pcre2grep_exit(0); - break; - - default: - fprintf(stderr, "pcre2grep: Unknown option -%c\n", letter); - pcre2grep_exit(usage(2)); - } - -return options; -} - - - - -/************************************************* -* Construct printed ordinal * -*************************************************/ - -/* This turns a number into "1st", "3rd", etc. */ - -static char * -ordin(int n) -{ -static char buffer[14]; -char *p = buffer; -sprintf(p, "%d", n); -while (*p != 0) p++; -switch (n%10) - { - case 1: strcpy(p, "st"); break; - case 2: strcpy(p, "nd"); break; - case 3: strcpy(p, "rd"); break; - default: strcpy(p, "th"); break; - } -return buffer; -} - - - -/************************************************* -* Compile a single pattern * -*************************************************/ - -/* Do nothing if the pattern has already been compiled. This is the case for -include/exclude patterns read from a file. - -When the -F option has been used, each "pattern" may be a list of strings, -separated by line breaks. They will be matched literally. We split such a -string and compile the first substring, inserting an additional block into the -pattern chain. - -Arguments: - p points to the pattern block - options the PCRE options - popts the processing options - fromfile TRUE if the pattern was read from a file - fromtext file name or identifying text (e.g. "include") - count 0 if this is the only command line pattern, or - number of the command line pattern, or - linenumber for a pattern from a file - -Returns: TRUE on success, FALSE after an error -*/ - -static BOOL -compile_pattern(patstr *p, int options, int popts, int fromfile, - const char *fromtext, int count) -{ -unsigned char buffer[PATBUFSIZE]; -PCRE2_SIZE erroffset; -char *ps = p->string; -unsigned int patlen = strlen(ps); -int errcode; - -if (p->compiled != NULL) return TRUE; - -if ((popts & PO_FIXED_STRINGS) != 0) - { - int ellength; - char *eop = ps + patlen; - char *pe = end_of_line(ps, eop, &ellength); - - if (ellength != 0) - { - if (add_pattern(pe, p) == NULL) return FALSE; - patlen = (int)(pe - ps - ellength); - } - } - -sprintf((char *)buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]); -p->compiled = pcre2_compile(buffer, -1, options, &errcode, &erroffset, - compile_context); -if (p->compiled != NULL) return TRUE; - -/* Handle compile errors */ - -erroffset -= (int)strlen(prefix[popts]); -if (erroffset > patlen) erroffset = patlen; -pcre2_get_error_message(errcode, buffer, PATBUFSIZE); - -if (fromfile) - { - fprintf(stderr, "pcre2grep: Error in regex in line %d of %s " - "at offset %d: %s\n", count, fromtext, (int)erroffset, buffer); - } -else - { - if (count == 0) - fprintf(stderr, "pcre2grep: Error in %s regex at offset %d: %s\n", - fromtext, (int)erroffset, buffer); - else - fprintf(stderr, "pcre2grep: Error in %s %s regex at offset %d: %s\n", - ordin(count), fromtext, (int)erroffset, buffer); - } - -return FALSE; -} - - - -/************************************************* -* Read and compile a file of patterns * -*************************************************/ - -/* This is used for --filelist, --include-from, and --exclude-from. - -Arguments: - name the name of the file; "-" is stdin - patptr pointer to the pattern chain anchor - patlastptr pointer to the last pattern pointer - popts the process options to pass to pattern_compile() - -Returns: TRUE if all went well -*/ - -static BOOL -read_pattern_file(char *name, patstr **patptr, patstr **patlastptr, int popts) -{ -int linenumber = 0; -FILE *f; -char *filename; -char buffer[PATBUFSIZE]; - -if (strcmp(name, "-") == 0) - { - f = stdin; - filename = stdin_name; - } -else - { - f = fopen(name, "r"); - if (f == NULL) - { - fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", name, strerror(errno)); - return FALSE; - } - filename = name; - } - -while (fgets(buffer, PATBUFSIZE, f) != NULL) - { - char *s = buffer + (int)strlen(buffer); - while (s > buffer && isspace((unsigned char)(s[-1]))) s--; - *s = 0; - linenumber++; - if (buffer[0] == 0) continue; /* Skip blank lines */ - - /* Note: this call to add_pattern() puts a pointer to the local variable - "buffer" into the pattern chain. However, that pointer is used only when - compiling the pattern, which happens immediately below, so we flatten it - afterwards, as a precaution against any later code trying to use it. */ - - *patlastptr = add_pattern(buffer, *patlastptr); - if (*patlastptr == NULL) - { - if (f != stdin) fclose(f); - return FALSE; - } - if (*patptr == NULL) *patptr = *patlastptr; - - /* This loop is needed because compiling a "pattern" when -F is set may add - on additional literal patterns if the original contains a newline. In the - common case, it never will, because fgets() stops at a newline. However, - the -N option can be used to give pcre2grep a different newline setting. */ - - for(;;) - { - if (!compile_pattern(*patlastptr, pcre2_options, popts, TRUE, filename, - linenumber)) - { - if (f != stdin) fclose(f); - return FALSE; - } - (*patlastptr)->string = NULL; /* Insurance */ - if ((*patlastptr)->next == NULL) break; - *patlastptr = (*patlastptr)->next; - } - } - -if (f != stdin) fclose(f); -return TRUE; -} - - - -/************************************************* -* Main program * -*************************************************/ - -/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */ - -int -main(int argc, char **argv) -{ -int i, j; -int rc = 1; -BOOL only_one_at_top; -patstr *cp; -fnstr *fn; -const char *locale_from = "--locale"; - -#ifdef SUPPORT_PCRE2GREP_JIT -pcre2_jit_stack *jit_stack = NULL; -#endif - -/* Set up a default compile and match contexts and a match data block. */ - -compile_context = pcre2_compile_context_create(NULL); -match_context = pcre2_match_context_create(NULL); -match_data = pcre2_match_data_create(OFFSET_SIZE, NULL); -offsets = pcre2_get_ovector_pointer(match_data); - -/* Process the options */ - -for (i = 1; i < argc; i++) - { - option_item *op = NULL; - char *option_data = (char *)""; /* default to keep compiler happy */ - BOOL longop; - BOOL longopwasequals = FALSE; - - if (argv[i][0] != '-') break; - - /* If we hit an argument that is just "-", it may be a reference to STDIN, - but only if we have previously had -e or -f to define the patterns. */ - - if (argv[i][1] == 0) - { - if (pattern_files != NULL || patterns != NULL) break; - else pcre2grep_exit(usage(2)); - } - - /* Handle a long name option, or -- to terminate the options */ - - if (argv[i][1] == '-') - { - char *arg = argv[i] + 2; - char *argequals = strchr(arg, '='); - - if (*arg == 0) /* -- terminates options */ - { - i++; - break; /* out of the options-handling loop */ - } - - longop = TRUE; - - /* Some long options have data that follows after =, for example file=name. - Some options have variations in the long name spelling: specifically, we - allow "regexp" because GNU grep allows it, though I personally go along - with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p". - These options are entered in the table as "regex(p)". Options can be in - both these categories. */ - - for (op = optionlist; op->one_char != 0; op++) - { - char *opbra = strchr(op->long_name, '('); - char *equals = strchr(op->long_name, '='); - - /* Handle options with only one spelling of the name */ - - if (opbra == NULL) /* Does not contain '(' */ - { - if (equals == NULL) /* Not thing=data case */ - { - if (strcmp(arg, op->long_name) == 0) break; - } - else /* Special case xxx=data */ - { - int oplen = (int)(equals - op->long_name); - int arglen = (argequals == NULL)? - (int)strlen(arg) : (int)(argequals - arg); - if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0) - { - option_data = arg + arglen; - if (*option_data == '=') - { - option_data++; - longopwasequals = TRUE; - } - break; - } - } - } - - /* Handle options with an alternate spelling of the name */ - - else - { - char buff1[24]; - char buff2[24]; - - int baselen = (int)(opbra - op->long_name); - int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1); - int arglen = (argequals == NULL || equals == NULL)? - (int)strlen(arg) : (int)(argequals - arg); - - sprintf(buff1, "%.*s", baselen, op->long_name); - sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1); - - if (strncmp(arg, buff1, arglen) == 0 || - strncmp(arg, buff2, arglen) == 0) - { - if (equals != NULL && argequals != NULL) - { - option_data = argequals; - if (*option_data == '=') - { - option_data++; - longopwasequals = TRUE; - } - } - break; - } - } - } - - if (op->one_char == 0) - { - fprintf(stderr, "pcre2grep: Unknown option %s\n", argv[i]); - pcre2grep_exit(usage(2)); - } - } - - /* Jeffrey Friedl's debugging harness uses these additional options which - are not in the right form for putting in the option table because they use - only one hyphen, yet are more than one character long. By putting them - separately here, they will not get displayed as part of the help() output, - but I don't think Jeffrey will care about that. */ - -#ifdef JFRIEDL_DEBUG - else if (strcmp(argv[i], "-pre") == 0) { - jfriedl_prefix = argv[++i]; - continue; - } else if (strcmp(argv[i], "-post") == 0) { - jfriedl_postfix = argv[++i]; - continue; - } else if (strcmp(argv[i], "-XT") == 0) { - sscanf(argv[++i], "%d", &jfriedl_XT); - continue; - } else if (strcmp(argv[i], "-XR") == 0) { - sscanf(argv[++i], "%d", &jfriedl_XR); - continue; - } -#endif - - - /* One-char options; many that have no data may be in a single argument; we - continue till we hit the last one or one that needs data. */ - - else - { - char *s = argv[i] + 1; - longop = FALSE; - - while (*s != 0) - { - for (op = optionlist; op->one_char != 0; op++) - { - if (*s == op->one_char) break; - } - if (op->one_char == 0) - { - fprintf(stderr, "pcre2grep: Unknown option letter '%c' in \"%s\"\n", - *s, argv[i]); - pcre2grep_exit(usage(2)); - } - - option_data = s+1; - - /* Break out if this is the last character in the string; it's handled - below like a single multi-char option. */ - - if (*option_data == 0) break; - - /* Check for a single-character option that has data: OP_OP_NUMBER(S) - are used for ones that either have a numerical number or defaults, i.e. - the data is optional. If a digit follows, there is data; if not, carry on - with other single-character options in the same string. */ - - if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS) - { - if (isdigit((unsigned char)s[1])) break; - } - else /* Check for an option with data */ - { - if (op->type != OP_NODATA) break; - } - - /* Handle a single-character option with no data, then loop for the - next character in the string. */ - - pcre2_options = handle_option(*s++, pcre2_options); - } - } - - /* At this point we should have op pointing to a matched option. If the type - is NO_DATA, it means that there is no data, and the option might set - something in the PCRE options. */ - - if (op->type == OP_NODATA) - { - pcre2_options = handle_option(op->one_char, pcre2_options); - continue; - } - - /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that - either has a value or defaults to something. It cannot have data in a - separate item. At the moment, the only such options are "colo(u)r", - "only-matching", and Jeffrey Friedl's special -S debugging option. */ - - if (*option_data == 0 && - (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER || - op->type == OP_OP_NUMBERS)) - { - switch (op->one_char) - { - case N_COLOUR: - colour_option = (char *)"auto"; - break; - - case 'o': - only_matching_last = add_number(0, only_matching_last); - if (only_matching == NULL) only_matching = only_matching_last; - break; - -#ifdef JFRIEDL_DEBUG - case 'S': - S_arg = 0; - break; -#endif - } - continue; - } - - /* Otherwise, find the data string for the option. */ - - if (*option_data == 0) - { - if (i >= argc - 1 || longopwasequals) - { - fprintf(stderr, "pcre2grep: Data missing after %s\n", argv[i]); - pcre2grep_exit(usage(2)); - } - option_data = argv[++i]; - } - - /* If the option type is OP_OP_NUMBERS, the value is a number that is to be - added to a chain of numbers. */ - - if (op->type == OP_OP_NUMBERS) - { - unsigned long int n = decode_number(option_data, op, longop); - omdatastr *omd = (omdatastr *)op->dataptr; - *(omd->lastptr) = add_number((int)n, *(omd->lastptr)); - if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr); - } - - /* If the option type is OP_PATLIST, it's the -e option, or one of the - include/exclude options, which can be called multiple times to create lists - of patterns. */ - - else if (op->type == OP_PATLIST) - { - patdatastr *pd = (patdatastr *)op->dataptr; - *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr)); - if (*(pd->lastptr) == NULL) goto EXIT2; - if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr); - } - - /* If the option type is OP_FILELIST, it's one of the options that names a - file. */ - - else if (op->type == OP_FILELIST) - { - fndatastr *fd = (fndatastr *)op->dataptr; - fn = (fnstr *)malloc(sizeof(fnstr)); - if (fn == NULL) - { - fprintf(stderr, "pcre2grep: malloc failed\n"); - goto EXIT2; - } - fn->next = NULL; - fn->name = option_data; - if (*(fd->anchor) == NULL) - *(fd->anchor) = fn; - else - (*(fd->lastptr))->next = fn; - *(fd->lastptr) = fn; - } - - /* Handle OP_BINARY_FILES */ - - else if (op->type == OP_BINFILES) - { - if (strcmp(option_data, "binary") == 0) - binary_files = BIN_BINARY; - else if (strcmp(option_data, "without-match") == 0) - binary_files = BIN_NOMATCH; - else if (strcmp(option_data, "text") == 0) - binary_files = BIN_TEXT; - else - { - fprintf(stderr, "pcre2grep: unknown value \"%s\" for binary-files\n", - option_data); - pcre2grep_exit(usage(2)); - } - } - - /* Otherwise, deal with a single string or numeric data value. */ - - else if (op->type != OP_NUMBER && op->type != OP_U32NUMBER && - op->type != OP_OP_NUMBER) - { - *((char **)op->dataptr) = option_data; - } - else - { - unsigned long int n = decode_number(option_data, op, longop); - if (op->type == OP_U32NUMBER) *((uint32_t *)op->dataptr) = n; - else *((int *)op->dataptr) = n; - } - } - -/* Options have been decoded. If -C was used, its value is used as a default -for -A and -B. */ - -if (both_context > 0) - { - if (after_context == 0) after_context = both_context; - if (before_context == 0) before_context = both_context; - } - -/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. -However, all three set show_only_matching because they display, each in their -own way, only the data that has matched. */ - -if ((only_matching != NULL && (file_offsets || line_offsets)) || - (file_offsets && line_offsets)) - { - fprintf(stderr, "pcre2grep: Cannot mix --only-matching, --file-offsets " - "and/or --line-offsets\n"); - pcre2grep_exit(usage(2)); - } - -/* Put limits into the match data block. */ - -if (match_limit > 0) pcre2_set_match_limit(match_context, match_limit); -if (recursion_limit > 0) pcre2_set_recursion_limit(match_context, recursion_limit); - -if (only_matching != NULL || file_offsets || line_offsets) - show_only_matching = TRUE; - -/* If a locale has not been provided as an option, see if the LC_CTYPE or -LC_ALL environment variable is set, and if so, use it. */ - -if (locale == NULL) - { - locale = getenv("LC_ALL"); - locale_from = "LCC_ALL"; - } - -if (locale == NULL) - { - locale = getenv("LC_CTYPE"); - locale_from = "LC_CTYPE"; - } - -/* If a locale is set, use it to generate the tables the PCRE needs. Passing -NULL to pcre2_maketables() means that malloc() is used to get the memory. */ - -if (locale != NULL) - { - if (setlocale(LC_CTYPE, locale) == NULL) - { - fprintf(stderr, "pcre2grep: Failed to set locale %s (obtained from %s)\n", - locale, locale_from); - goto EXIT2; - } - character_tables = pcre2_maketables(NULL); - pcre2_set_character_tables(compile_context, character_tables); - } - -/* Sort out colouring */ - -if (colour_option != NULL && strcmp(colour_option, "never") != 0) - { - if (strcmp(colour_option, "always") == 0) do_colour = TRUE; - else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty(); - else - { - fprintf(stderr, "pcre2grep: Unknown colour setting \"%s\"\n", - colour_option); - goto EXIT2; - } - if (do_colour) - { - char *cs = getenv("PCRE2GREP_COLOUR"); - if (cs == NULL) cs = getenv("PCRE2GREP_COLOR"); - if (cs != NULL) colour_string = cs; - } - } - -/* Sort out a newline setting. */ - -if (newline_arg != NULL) - { - for (endlinetype = 1; endlinetype < (int)(sizeof(newlines)/sizeof(char *)); - endlinetype++) - { - if (strcmpic(newline_arg, newlines[endlinetype]) == 0) break; - } - if (endlinetype < (int)(sizeof(newlines)/sizeof(char *))) - pcre2_set_newline(compile_context, endlinetype); - else - { - fprintf(stderr, "pcre2grep: Invalid newline specifier \"%s\"\n", - newline_arg); - goto EXIT2; - } - } - -/* Find default newline convention */ - -else - { - (void)pcre2_config(PCRE2_CONFIG_NEWLINE, &endlinetype); - } - -/* Interpret the text values for -d and -D */ - -if (dee_option != NULL) - { - if (strcmp(dee_option, "read") == 0) dee_action = dee_READ; - else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE; - else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP; - else - { - fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -d\n", dee_option); - goto EXIT2; - } - } - -if (DEE_option != NULL) - { - if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ; - else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP; - else - { - fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -D\n", DEE_option); - goto EXIT2; - } - } - -/* Check the values for Jeffrey Friedl's debugging options. */ - -#ifdef JFRIEDL_DEBUG -if (S_arg > 9) - { - fprintf(stderr, "pcre2grep: bad value for -S option\n"); - return 2; - } -if (jfriedl_XT != 0 || jfriedl_XR != 0) - { - if (jfriedl_XT == 0) jfriedl_XT = 1; - if (jfriedl_XR == 0) jfriedl_XR = 1; - } -#endif - -/* Get memory for the main buffer. */ - -bufsize = 3*bufthird; -main_buffer = (char *)malloc(bufsize); - -if (main_buffer == NULL) - { - fprintf(stderr, "pcre2grep: malloc failed\n"); - goto EXIT2; - } - -/* If no patterns were provided by -e, and there are no files provided by -f, -the first argument is the one and only pattern, and it must exist. */ - -if (patterns == NULL && pattern_files == NULL) - { - if (i >= argc) return usage(2); - patterns = patterns_last = add_pattern(argv[i++], NULL); - if (patterns == NULL) goto EXIT2; - } - -/* Compile the patterns that were provided on the command line, either by -multiple uses of -e or as a single unkeyed pattern. We cannot do this until -after all the command-line options are read so that we know which PCRE options -to use. When -F is used, compile_pattern() may add another block into the -chain, so we must not access the next pointer till after the compile. */ - -for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next) - { - if (!compile_pattern(cp, pcre2_options, process_options, FALSE, "command-line", - (j == 1 && patterns->next == NULL)? 0 : j)) - goto EXIT2; - } - -/* Read and compile the regular expressions that are provided in files. */ - -for (fn = pattern_files; fn != NULL; fn = fn->next) - { - if (!read_pattern_file(fn->name, &patterns, &patterns_last, process_options)) - goto EXIT2; - } - -/* Unless JIT has been explicitly disabled, arrange a stack for it to use. */ - -#ifdef SUPPORT_PCRE2GREP_JIT -if (use_jit) - jit_stack = pcre2_jit_stack_create(32*1024, 1024*1024, NULL); -#endif - -for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next) - { -#ifdef SUPPORT_PCRE2GREP_JIT - if (jit_stack != NULL && cp->compiled != NULL) - pcre2_jit_stack_assign(match_context, NULL, jit_stack); -#endif - } - -/* If there are include or exclude patterns read from the command line, compile -them. -F, -w, and -x do not apply, so the third argument of compile_pattern is -0. */ - -for (j = 0; j < 4; j++) - { - int k; - for (k = 1, cp = *(incexlist[j]); cp != NULL; k++, cp = cp->next) - { - if (!compile_pattern(cp, pcre2_options, 0, FALSE, incexname[j], - (k == 1 && cp->next == NULL)? 0 : k)) - goto EXIT2; - } - } - -/* Read and compile include/exclude patterns from files. */ - -for (fn = include_from; fn != NULL; fn = fn->next) - { - if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last, 0)) - goto EXIT2; - } - -for (fn = exclude_from; fn != NULL; fn = fn->next) - { - if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last, 0)) - goto EXIT2; - } - -/* If there are no files that contain lists of files to search, and there are -no file arguments, search stdin, and then exit. */ - -if (file_lists == NULL && i >= argc) - { - rc = pcre2grep(stdin, FR_PLAIN, stdin_name, - (filenames > FN_DEFAULT)? stdin_name : NULL); - goto EXIT; - } - -/* If any files that contains a list of files to search have been specified, -read them line by line and search the given files. */ - -for (fn = file_lists; fn != NULL; fn = fn->next) - { - char buffer[PATBUFSIZE]; - FILE *fl; - if (strcmp(fn->name, "-") == 0) fl = stdin; else - { - fl = fopen(fn->name, "rb"); - if (fl == NULL) - { - fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", fn->name, - strerror(errno)); - goto EXIT2; - } - } - while (fgets(buffer, PATBUFSIZE, fl) != NULL) - { - int frc; - char *end = buffer + (int)strlen(buffer); - while (end > buffer && isspace(end[-1])) end--; - *end = 0; - if (*buffer != 0) - { - frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE); - if (frc > 1) rc = frc; - else if (frc == 0 && rc == 1) rc = 0; - } - } - if (fl != stdin) fclose(fl); - } - -/* After handling file-list, work through remaining arguments. Pass in the fact -that there is only one argument at top level - this suppresses the file name if -the argument is not a directory and filenames are not otherwise forced. */ - -only_one_at_top = i == argc - 1 && file_lists == NULL; - -for (; i < argc; i++) - { - int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE, - only_one_at_top); - if (frc > 1) rc = frc; - else if (frc == 0 && rc == 1) rc = 0; - } - -EXIT: -#ifdef SUPPORT_PCRE2GREP_JIT -if (jit_stack != NULL) pcre2_jit_stack_free(jit_stack); -#endif - -free(main_buffer); -free((void *)character_tables); - -pcre2_compile_context_free(compile_context); -pcre2_match_context_free(match_context); -pcre2_match_data_free(match_data); - -free_pattern_chain(patterns); -free_pattern_chain(include_patterns); -free_pattern_chain(include_dir_patterns); -free_pattern_chain(exclude_patterns); -free_pattern_chain(exclude_dir_patterns); - -free_file_chain(exclude_from); -free_file_chain(include_from); -free_file_chain(pattern_files); -free_file_chain(file_lists); - -while (only_matching != NULL) - { - omstr *this = only_matching; - only_matching = this->next; - free(this); - } - -pcre2grep_exit(rc); - -EXIT2: -rc = 2; -goto EXIT; -} - -/* End of pcre2grep */ diff --git a/pcre2/src/pcre2posix.c b/pcre2/src/pcre2posix.c deleted file mode 100644 index 1d6e5b797..000000000 --- a/pcre2/src/pcre2posix.c +++ /dev/null @@ -1,335 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module is a wrapper that provides a POSIX API to the underlying PCRE2 -functions. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -/* Ensure that the PCRE2POSIX_EXP_xxx macros are set appropriately for -compiling these functions. This must come before including pcre2posix.h, where -they are set for an application (using these functions) if they have not -previously been set. */ - -#if defined(_WIN32) && !defined(PCRE2_STATIC) -# define PCRE2POSIX_EXP_DECL extern __declspec(dllexport) -# define PCRE2POSIX_EXP_DEFN __declspec(dllexport) -#endif - -/* We include pcre2.h before pcre2_internal.h so that the PCRE2 library -functions are declared as "import" for Windows by defining PCRE2_EXP_DECL as -"import". This is needed even though pcre2_internal.h itself includes pcre2.h, -because it does so after it has set PCRE2_EXP_DECL to "export" if it is not -already set. */ - -#include "pcre2.h" -#include "pcre2_internal.h" -#include "pcre2posix.h" - -/* Table to translate PCRE2 compile time error codes into POSIX error codes. -Only a few PCRE2 errors with a value greater than 23 turn into special POSIX -codes: most go to REG_BADPAT. The second table lists, in pairs, those that -don't. */ - -static const int eint1[] = { - 0, /* No error */ - REG_EESCAPE, /* \ at end of pattern */ - REG_EESCAPE, /* \c at end of pattern */ - REG_EESCAPE, /* unrecognized character follows \ */ - REG_BADBR, /* numbers out of order in {} quantifier */ - /* 5 */ - REG_BADBR, /* number too big in {} quantifier */ - REG_EBRACK, /* missing terminating ] for character class */ - REG_ECTYPE, /* invalid escape sequence in character class */ - REG_ERANGE, /* range out of order in character class */ - REG_BADRPT, /* nothing to repeat */ - /* 10 */ - REG_ASSERT, /* internal error: unexpected repeat */ - REG_BADPAT, /* unrecognized character after (? or (?- */ - REG_BADPAT, /* POSIX named classes are supported only within a class */ - REG_BADPAT, /* POSIX collating elements are not supported */ - REG_EPAREN, /* missing ) */ - /* 15 */ - REG_ESUBREG, /* reference to non-existent subpattern */ - REG_INVARG, /* pattern passed as NULL */ - REG_INVARG, /* unknown compile-time option bit(s) */ - REG_EPAREN, /* missing ) after (?# comment */ - REG_ESIZE, /* parentheses nested too deeply */ - /* 20 */ - REG_ESIZE, /* regular expression too large */ - REG_ESPACE, /* failed to get memory */ - REG_EPAREN, /* unmatched closing parenthesis */ - REG_ASSERT /* internal error: code overflow */ - }; - -static const int eint2[] = { - 30, REG_ECTYPE, /* unknown POSIX class name */ - 32, REG_INVARG, /* this version of PCRE2 does not have Unicode support */ - 37, REG_EESCAPE, /* PCRE2 does not support \L, \l, \N{name}, \U, or \u */ - 56, REG_INVARG, /* internal error: unknown newline setting */ -}; - -/* Table of texts corresponding to POSIX error codes */ - -static const char *const pstring[] = { - "", /* Dummy for value 0 */ - "internal error", /* REG_ASSERT */ - "invalid repeat counts in {}", /* BADBR */ - "pattern error", /* BADPAT */ - "? * + invalid", /* BADRPT */ - "unbalanced {}", /* EBRACE */ - "unbalanced []", /* EBRACK */ - "collation error - not relevant", /* ECOLLATE */ - "bad class", /* ECTYPE */ - "bad escape sequence", /* EESCAPE */ - "empty expression", /* EMPTY */ - "unbalanced ()", /* EPAREN */ - "bad range inside []", /* ERANGE */ - "expression too big", /* ESIZE */ - "failed to get memory", /* ESPACE */ - "bad back reference", /* ESUBREG */ - "bad argument", /* INVARG */ - "match failed" /* NOMATCH */ -}; - - - - -/************************************************* -* Translate error code to string * -*************************************************/ - -PCRE2POSIX_EXP_DEFN size_t PCRE2_CALL_CONVENTION -regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) -{ -int used; -const char *message; - -message = (errcode <= 0 || errcode >= (int)(sizeof(pstring)/sizeof(char *)))? - "unknown error code" : pstring[errcode]; - -if (preg != NULL && (int)preg->re_erroffset != -1) - { - used = snprintf(errbuf, errbuf_size, "%s at offset %-6d", message, - (int)preg->re_erroffset); - } -else - { - used = snprintf(errbuf, errbuf_size, "%s", message); - } - -return used + 1; -} - - - - -/************************************************* -* Free store held by a regex * -*************************************************/ - -PCRE2POSIX_EXP_DEFN void PCRE2_CALL_CONVENTION -regfree(regex_t *preg) -{ -pcre2_match_data_free(preg->re_match_data); -pcre2_code_free(preg->re_pcre2_code); -} - - - - -/************************************************* -* Compile a regular expression * -*************************************************/ - -/* -Arguments: - preg points to a structure for recording the compiled expression - pattern the pattern to compile - cflags compilation flags - -Returns: 0 on success - various non-zero codes on failure -*/ - -PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION -regcomp(regex_t *preg, const char *pattern, int cflags) -{ -PCRE2_SIZE erroffset; -int errorcode; -int options = 0; -int re_nsub = 0; - -if ((cflags & REG_ICASE) != 0) options |= PCRE2_CASELESS; -if ((cflags & REG_NEWLINE) != 0) options |= PCRE2_MULTILINE; -if ((cflags & REG_DOTALL) != 0) options |= PCRE2_DOTALL; -if ((cflags & REG_NOSUB) != 0) options |= PCRE2_NO_AUTO_CAPTURE; -if ((cflags & REG_UTF) != 0) options |= PCRE2_UTF; -if ((cflags & REG_UCP) != 0) options |= PCRE2_UCP; -if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY; - -preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, - options, &errorcode, &erroffset, NULL); -preg->re_erroffset = erroffset; - -if (preg->re_pcre2_code == NULL) - { - unsigned int i; - - /* A negative value is a UTF error; otherwise all error codes are greater - than COMPILE_ERROR_BASE, but check, just in case. */ - - if (errorcode < COMPILE_ERROR_BASE) return REG_BADPAT; - errorcode -= COMPILE_ERROR_BASE; - - if (errorcode < (int)(sizeof(eint1)/sizeof(const int))) - return eint1[errorcode]; - for (i = 0; i < sizeof(eint2)/(2*sizeof(const int)); i += 2) - if (errorcode == eint2[i]) return eint2[i+1]; - return REG_BADPAT; - } - -(void)pcre2_pattern_info((const pcre2_code *)preg->re_pcre2_code, - PCRE2_INFO_CAPTURECOUNT, &re_nsub); -preg->re_nsub = (size_t)re_nsub; -if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) re_nsub = -1; -preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL); - -if (preg->re_match_data == NULL) - { - pcre2_code_free(preg->re_pcre2_code); - return REG_ESPACE; - } - -return 0; -} - - - -/************************************************* -* Match a regular expression * -*************************************************/ - -/* A suitable match_data block, large enough to hold all possible captures, was -obtained when the pattern was compiled, to save having to allocate and free it -for each match. If REG_NOSUB was specified at compile time, the -PCRE_NO_AUTO_CAPTURE flag will be set. When this is the case, the nmatch and -pmatch arguments are ignored, and the only result is yes/no/error. */ - -PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION -regexec(const regex_t *preg, const char *string, size_t nmatch, - regmatch_t pmatch[], int eflags) -{ -int rc, so, eo; -int options = 0; -pcre2_match_data *md = (pcre2_match_data *)preg->re_match_data; - -if ((eflags & REG_NOTBOL) != 0) options |= PCRE2_NOTBOL; -if ((eflags & REG_NOTEOL) != 0) options |= PCRE2_NOTEOL; -if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE2_NOTEMPTY; - -((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ - -/* When no string data is being returned, or no vector has been passed in which -to put it, ensure that nmatch is zero. */ - -if ((((pcre2_real_code *)(preg->re_pcre2_code))->compile_options & - PCRE2_NO_AUTO_CAPTURE) != 0 || pmatch == NULL) nmatch = 0; - -/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings. -The man page from OS X says "REG_STARTEND affects only the location of the -string, not how it is matched". That is why the "so" value is used to bump the -start location rather than being passed as a PCRE2 "starting offset". */ - -if ((eflags & REG_STARTEND) != 0) - { - if (pmatch == NULL) return REG_INVARG; - so = pmatch[0].rm_so; - eo = pmatch[0].rm_eo; - } -else - { - so = 0; - eo = (int)strlen(string); - } - -rc = pcre2_match((const pcre2_code *)preg->re_pcre2_code, - (PCRE2_SPTR)string + so, (eo - so), 0, options, md, NULL); - -/* Successful match */ - -if (rc >= 0) - { - size_t i; - if ((size_t)rc > nmatch) rc = (int)nmatch; - for (i = 0; i < (size_t)rc; i++) - { - pmatch[i].rm_so = md->ovector[i*2]; - pmatch[i].rm_eo = md->ovector[i*2+1]; - } - for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; - return 0; - } - -/* Unsuccessful match */ - -if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21) - return REG_INVARG; - -switch(rc) - { - default: return REG_ASSERT; - case PCRE2_ERROR_BADMODE: return REG_INVARG; - case PCRE2_ERROR_BADMAGIC: return REG_INVARG; - case PCRE2_ERROR_BADOPTION: return REG_INVARG; - case PCRE2_ERROR_BADUTFOFFSET: return REG_INVARG; - case PCRE2_ERROR_MATCHLIMIT: return REG_ESPACE; - case PCRE2_ERROR_NOMATCH: return REG_NOMATCH; - case PCRE2_ERROR_NOMEMORY: return REG_ESPACE; - case PCRE2_ERROR_NULL: return REG_INVARG; - } -} - -/* End of pcre2posix.c */ diff --git a/pcre2/src/pcre2posix.h b/pcre2/src/pcre2posix.h deleted file mode 100644 index 44a2fd8ad..000000000 --- a/pcre2/src/pcre2posix.h +++ /dev/null @@ -1,146 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE2 is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* Have to include stdlib.h in order to ensure that size_t is defined. */ - -#include - -/* Allow for C++ users */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Options, mostly defined by POSIX, but with some extras. */ - -#define REG_ICASE 0x0001 /* Maps to PCRE2_CASELESS */ -#define REG_NEWLINE 0x0002 /* Maps to PCRE2_MULTILINE */ -#define REG_NOTBOL 0x0004 /* Maps to PCRE2_NOTBOL */ -#define REG_NOTEOL 0x0008 /* Maps to PCRE2_NOTEOL */ -#define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE2_DOTALL */ -#define REG_NOSUB 0x0020 /* Maps to PCRE2_NO_AUTO_CAPTURE */ -#define REG_UTF 0x0040 /* NOT defined by POSIX; maps to PCRE2_UTF */ -#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ -#define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE2_NOTEMPTY */ -#define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE2_UNGREEDY */ -#define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE2_UCP */ - -/* This is not used by PCRE2, but by defining it we make it easier -to slot PCRE2 into existing programs that make POSIX calls. */ - -#define REG_EXTENDED 0 - -/* Error values. Not all these are relevant or used by the wrapper. */ - -enum { - REG_ASSERT = 1, /* internal error ? */ - REG_BADBR, /* invalid repeat counts in {} */ - REG_BADPAT, /* pattern error */ - REG_BADRPT, /* ? * + invalid */ - REG_EBRACE, /* unbalanced {} */ - REG_EBRACK, /* unbalanced [] */ - REG_ECOLLATE, /* collation error - not relevant */ - REG_ECTYPE, /* bad class */ - REG_EESCAPE, /* bad escape sequence */ - REG_EMPTY, /* empty expression */ - REG_EPAREN, /* unbalanced () */ - REG_ERANGE, /* bad range inside [] */ - REG_ESIZE, /* expression too big */ - REG_ESPACE, /* failed to get memory */ - REG_ESUBREG, /* bad back reference */ - REG_INVARG, /* bad argument */ - REG_NOMATCH /* match failed */ -}; - - -/* The structure representing a compiled regular expression. */ - -typedef struct { - void *re_pcre2_code; - void *re_match_data; - size_t re_nsub; - size_t re_erroffset; -} regex_t; - -/* The structure in which a captured offset is returned. */ - -typedef int regoff_t; - -typedef struct { - regoff_t rm_so; - regoff_t rm_eo; -} regmatch_t; - -/* When an application links to a PCRE2 DLL in Windows, the symbols that are -imported have to be identified as such. When building PCRE2, the appropriate -export settings are needed, and are set in pcre2posix.c before including this -file. */ - -#if defined(_WIN32) && !defined(PCRE2_STATIC) && !defined(PCRE2POSIX_EXP_DECL) -# define PCRE2POSIX_EXP_DECL extern __declspec(dllimport) -# define PCRE2POSIX_EXP_DEFN __declspec(dllimport) -#endif - -/* By default, we use the standard "extern" declarations. */ - -#ifndef PCRE2POSIX_EXP_DECL -# ifdef __cplusplus -# define PCRE2POSIX_EXP_DECL extern "C" -# define PCRE2POSIX_EXP_DEFN extern "C" -# else -# define PCRE2POSIX_EXP_DECL extern -# define PCRE2POSIX_EXP_DEFN extern -# endif -#endif - -/* The functions */ - -PCRE2POSIX_EXP_DECL int regcomp(regex_t *, const char *, int); -PCRE2POSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, - regmatch_t *, int); -PCRE2POSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); -PCRE2POSIX_EXP_DECL void regfree(regex_t *); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* End of pcre2posix.h */ diff --git a/pcre2/src/pcre2test.c b/pcre2/src/pcre2test.c deleted file mode 100644 index 0a5879e47..000000000 --- a/pcre2/src/pcre2test.c +++ /dev/null @@ -1,7426 +0,0 @@ -/************************************************* -* PCRE2 testing program * -*************************************************/ - -/* PCRE2 is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. In 2014 -the API was completely revised and '2' was added to the name, because the old -API, which had lasted for 16 years, could not accommodate new requirements. At -the same time, this testing program was re-designed because its original -hacked-up (non-) design had also run out of steam. - - Written by Philip Hazel - Original code Copyright (c) 1997-2012 University of Cambridge - Rewritten code Copyright (c) 2016 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This program supports testing of the 8-bit, 16-bit, and 32-bit PCRE2 -libraries in a single program, though its input and output are always 8-bit. -It is different from modules such as pcre2_compile.c in the library itself, -which are compiled separately for each code unit width. If two widths are -enabled, for example, pcre2_compile.c is compiled twice. In contrast, -pcre2test.c is compiled only once, and linked with all the enabled libraries. -Therefore, it must not make use of any of the macros from pcre2.h or -pcre2_internal.h that depend on PCRE2_CODE_UNIT_WIDTH. It does, however, make -use of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16, and SUPPORT_PCRE2_32, to ensure that -it references only the enabled library functions. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if defined NATIVE_ZOS -#include "pcrzoscs.h" -/* That header is not included in the main PCRE2 distribution because other -apparatus is needed to compile pcre2test for z/OS. The header can be found in -the special z/OS distribution, which is available from www.zaconsultants.net or -from www.cbttape.org. */ -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -/* Both libreadline and libedit are optionally supported. The user-supplied -original patch uses readline/readline.h for libedit, but in at least one system -it is installed as editline/readline.h, so the configuration code now looks for -that first, falling back to readline/readline.h. */ - -#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) -#if defined(SUPPORT_LIBREADLINE) -#include -#include -#else -#if defined(HAVE_EDITLINE_READLINE_H) -#include -#else -#include -#endif -#endif -#endif - -/* Put the test for interactive input into a macro so that it can be changed if -required for different environments. */ - -#define INTERACTIVE(f) isatty(fileno(f)) - - -/* ---------------------- System-specific definitions ---------------------- */ - -/* A number of things vary for Windows builds. Originally, pcretest opened its -input and output without "b"; then I was told that "b" was needed in some -environments, so it was added for release 5.0 to both the input and output. (It -makes no difference on Unix-like systems.) Later I was told that it is wrong -for the input on Windows. I've now abstracted the modes into macros that are -set here, to make it easier to fiddle with them, and removed "b" from the input -mode under Windows. The BINARY versions are used when saving/restoring compiled -patterns. */ - -#if defined(_WIN32) || defined(WIN32) -#include /* For _setmode() */ -#include /* For _O_BINARY */ -#define INPUT_MODE "r" -#define OUTPUT_MODE "wb" -#define BINARY_INPUT_MODE "rb" -#define BINARY_OUTPUT_MODE "wb" - -#ifndef isatty -#define isatty _isatty /* This is what Windows calls them, I'm told, */ -#endif /* though in some environments they seem to */ - /* be already defined, hence the #ifndefs. */ -#ifndef fileno -#define fileno _fileno -#endif - -/* A user sent this fix for Borland Builder 5 under Windows. */ - -#ifdef __BORLANDC__ -#define _setmode(handle, mode) setmode(handle, mode) -#endif - -/* Not Windows */ - -#else -#include /* These two includes are needed */ -#include /* for setrlimit(). */ -#if defined NATIVE_ZOS /* z/OS uses non-binary I/O */ -#define INPUT_MODE "r" -#define OUTPUT_MODE "w" -#define BINARY_INPUT_MODE "rb" -#define BINARY_OUTPUT_MODE "wb" -#else -#define INPUT_MODE "rb" -#define OUTPUT_MODE "wb" -#define BINARY_INPUT_MODE "rb" -#define BINARY_OUTPUT_MODE "wb" -#endif -#endif - -#ifdef __VMS -#include -void vms_setsymbol( char *, char *, int ); -#endif - -/* ------------------End of system-specific definitions -------------------- */ - -/* Glueing macros that are used in several places below. */ - -#define glue(a,b) a##b -#define G(a,b) glue(a,b) - -/* Miscellaneous parameters and manifests */ - -#ifndef CLOCKS_PER_SEC -#ifdef CLK_TCK -#define CLOCKS_PER_SEC CLK_TCK -#else -#define CLOCKS_PER_SEC 100 -#endif -#endif - -#define CFAIL_UNSET UINT32_MAX /* Unset value for cfail fields */ -#define DFA_WS_DIMENSION 1000 /* Size of DFA workspace */ -#define DEFAULT_OVECCOUNT 15 /* Default ovector count */ -#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */ -#define LOCALESIZE 32 /* Size of locale name */ -#define LOOPREPEAT 500000 /* Default loop count for timing */ -#define PATSTACKSIZE 20 /* Pattern stack for save/restore testing */ -#define REPLACE_MODSIZE 100 /* Field for reading 8-bit replacement */ -#define VERSION_SIZE 64 /* Size of buffer for the version strings */ - -/* Make sure the buffer into which replacement strings are copied is big enough -to hold them as 32-bit code units. */ - -#define REPLACE_BUFFSIZE 1024 /* This is a byte value */ - -/* Execution modes */ - -#define PCRE8_MODE 8 -#define PCRE16_MODE 16 -#define PCRE32_MODE 32 - -/* Processing returns */ - -enum { PR_OK, PR_SKIP, PR_ABEND }; - -/* The macro PRINTABLE determines whether to print an output character as-is or -as a hex value when showing compiled patterns. is We use it in cases when the -locale has not been explicitly changed, so as to get consistent output from -systems that differ in their output from isprint() even in the "C" locale. */ - -#ifdef EBCDIC -#define PRINTABLE(c) ((c) >= 64 && (c) < 255) -#else -#define PRINTABLE(c) ((c) >= 32 && (c) < 127) -#endif - -#define PRINTOK(c) ((locale_tables != NULL)? isprint(c) : PRINTABLE(c)) - -/* We have to include some of the library source files because we need -to use some of the macros, internal structure definitions, and other internal -values - pcre2test has "inside information" compared to an application program -that strictly follows the PCRE2 API. - -Before including pcre2_internal.h we define PRIV so that it does not get -defined therein. This ensures that PRIV names in the included files do not -clash with those in the libraries. Also, although pcre2_internal.h does itself -include pcre2.h, we explicitly include it beforehand, along with pcre2posix.h, -so that the PCRE2_EXP_xxx macros get set appropriately for an application, not -for building the library. */ - -#define PRIV(name) name -#define PCRE2_CODE_UNIT_WIDTH 0 -#include "pcre2.h" -#include "pcre2posix.h" -#include "pcre2_internal.h" - -/* We need access to some of the data tables that PCRE2 uses. Defining -PCRE2_PCRETEST makes some minor changes in the files. The previous definition -of PRIV avoids name clashes. */ - -#define PCRE2_PCRE2TEST -#include "pcre2_tables.c" -#include "pcre2_ucd.c" - -/* 32-bit integer values in the input are read by strtoul() or strtol(). The -check needed for overflow depends on whether long ints are in fact longer than -ints. They are defined not to be shorter. */ - -#if ULONG_MAX > UINT32_MAX -#define U32OVERFLOW(x) (x > UINT32_MAX) -#else -#define U32OVERFLOW(x) (x == UINT32_MAX) -#endif - -#if LONG_MAX > INT32_MAX -#define S32OVERFLOW(x) (x > INT32_MAX || x < INT32_MIN) -#else -#define S32OVERFLOW(x) (x == INT32_MAX || x == INT32_MIN) -#endif - -/* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include -pcre2_intmodedep.h, which is where mode-dependent macros and structures are -defined. We can now include it for each supported code unit width. Because -PCRE2_CODE_UNIT_WIDTH was defined as zero before including pcre2.h, it will -have left PCRE2_SUFFIX defined as a no-op. We must re-define it appropriately -while including these files, and then restore it to a no-op. Because LINK_SIZE -may be changed in 16-bit mode and forced to 1 in 32-bit mode, the order of -these inclusions should not be changed. */ - -#undef PCRE2_SUFFIX -#undef PCRE2_CODE_UNIT_WIDTH - -#ifdef SUPPORT_PCRE2_8 -#define PCRE2_CODE_UNIT_WIDTH 8 -#define PCRE2_SUFFIX(a) G(a,8) -#include "pcre2_intmodedep.h" -#include "pcre2_printint.c" -#undef PCRE2_CODE_UNIT_WIDTH -#undef PCRE2_SUFFIX -#endif /* SUPPORT_PCRE2_8 */ - -#ifdef SUPPORT_PCRE2_16 -#define PCRE2_CODE_UNIT_WIDTH 16 -#define PCRE2_SUFFIX(a) G(a,16) -#include "pcre2_intmodedep.h" -#include "pcre2_printint.c" -#undef PCRE2_CODE_UNIT_WIDTH -#undef PCRE2_SUFFIX -#endif /* SUPPORT_PCRE2_16 */ - -#ifdef SUPPORT_PCRE2_32 -#define PCRE2_CODE_UNIT_WIDTH 32 -#define PCRE2_SUFFIX(a) G(a,32) -#include "pcre2_intmodedep.h" -#include "pcre2_printint.c" -#undef PCRE2_CODE_UNIT_WIDTH -#undef PCRE2_SUFFIX -#endif /* SUPPORT_PCRE2_32 */ - -#define PCRE2_SUFFIX(a) a - -/* We need to be able to check input text for UTF-8 validity, whatever code -widths are actually available, because the input to pcre2test is always in -8-bit code units. So we include the UTF validity checking function for 8-bit -code units. */ - -extern int valid_utf(PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE *); - -#define PCRE2_CODE_UNIT_WIDTH 8 -#undef PCRE2_SPTR -#define PCRE2_SPTR PCRE2_SPTR8 -#include "pcre2_valid_utf.c" -#undef PCRE2_CODE_UNIT_WIDTH -#undef PCRE2_SPTR - -/* If we have 8-bit support, default to it; if there is also 16-or 32-bit -support, it can be selected by a command-line option. If there is no 8-bit -support, there must be 16- or 32-bit support, so default to one of them. The -config function, JIT stack, contexts, and version string are the same in all -modes, so use the form of the first that is available. */ - -#if defined SUPPORT_PCRE2_8 -#define DEFAULT_TEST_MODE PCRE8_MODE -#define VERSION_TYPE PCRE2_UCHAR8 -#define PCRE2_CONFIG pcre2_config_8 -#define PCRE2_JIT_STACK pcre2_jit_stack_8 -#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8 -#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8 -#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8 -#define VERSION_TYPE PCRE2_UCHAR8 - -#elif defined SUPPORT_PCRE2_16 -#define DEFAULT_TEST_MODE PCRE16_MODE -#define VERSION_TYPE PCRE2_UCHAR16 -#define PCRE2_CONFIG pcre2_config_16 -#define PCRE2_JIT_STACK pcre2_jit_stack_16 -#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_16 -#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_16 -#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_16 - -#elif defined SUPPORT_PCRE2_32 -#define DEFAULT_TEST_MODE PCRE32_MODE -#define VERSION_TYPE PCRE2_UCHAR32 -#define PCRE2_CONFIG pcre2_config_32 -#define PCRE2_JIT_STACK pcre2_jit_stack_32 -#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_32 -#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_32 -#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_32 -#endif - -/* ------------- Structure and table for handling #-commands ------------- */ - -typedef struct cmdstruct { - const char *name; - int value; -} cmdstruct; - -enum { CMD_FORBID_UTF, CMD_LOAD, CMD_NEWLINE_DEFAULT, CMD_PATTERN, - CMD_PERLTEST, CMD_POP, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN }; - -static cmdstruct cmdlist[] = { - { "forbid_utf", CMD_FORBID_UTF }, - { "load", CMD_LOAD }, - { "newline_default", CMD_NEWLINE_DEFAULT }, - { "pattern", CMD_PATTERN }, - { "perltest", CMD_PERLTEST }, - { "pop", CMD_POP }, - { "save", CMD_SAVE }, - { "subject", CMD_SUBJECT }}; - -#define cmdlistcount sizeof(cmdlist)/sizeof(cmdstruct) - -/* ------------- Structures and tables for handling modifiers -------------- */ - -/* Table of names for newline types. Must be kept in step with the definitions -of PCRE2_NEWLINE_xx in pcre2.h. */ - -static const char *newlines[] = { - "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" }; - -/* Modifier types and applicability */ - -enum { MOD_CTC, /* Applies to a compile context */ - MOD_CTM, /* Applies to a match context */ - MOD_PAT, /* Applies to a pattern */ - MOD_PATP, /* Ditto, OK for Perl test */ - MOD_DAT, /* Applies to a data line */ - MOD_PD, /* Applies to a pattern or a data line */ - MOD_PDP, /* As MOD_PD, OK for Perl test */ - MOD_PND, /* As MOD_PD, but not for a default pattern */ - MOD_PNDP, /* As MOD_PND, OK for Perl test */ - MOD_CTL, /* Is a control bit */ - MOD_BSR, /* Is a BSR value */ - MOD_IN2, /* Is one or two unsigned integers */ - MOD_INS, /* Is a signed integer */ - MOD_INT, /* Is an unsigned integer */ - MOD_IND, /* Is an unsigned integer, but no value => default */ - MOD_NL, /* Is a newline value */ - MOD_NN, /* Is a number or a name; more than one may occur */ - MOD_OPT, /* Is an option bit */ - MOD_SIZ, /* Is a PCRE2_SIZE value */ - MOD_STR }; /* Is a string */ - -/* Control bits. Some apply to compiling, some to matching, but some can be set -either on a pattern or a data line, so they must all be distinct. There are now -so many of them that they are split into two fields. */ - -#define CTL_AFTERTEXT 0x00000001u -#define CTL_ALLAFTERTEXT 0x00000002u -#define CTL_ALLCAPTURES 0x00000004u -#define CTL_ALLUSEDTEXT 0x00000008u -#define CTL_ALTGLOBAL 0x00000010u -#define CTL_BINCODE 0x00000020u -#define CTL_CALLOUT_CAPTURE 0x00000040u -#define CTL_CALLOUT_INFO 0x00000080u -#define CTL_CALLOUT_NONE 0x00000100u -#define CTL_DFA 0x00000200u -#define CTL_EXPAND 0x00000400u -#define CTL_FINDLIMITS 0x00000800u -#define CTL_FULLBINCODE 0x00001000u -#define CTL_GETALL 0x00002000u -#define CTL_GLOBAL 0x00004000u -#define CTL_HEXPAT 0x00008000u -#define CTL_INFO 0x00010000u -#define CTL_JITFAST 0x00020000u -#define CTL_JITVERIFY 0x00040000u -#define CTL_MARK 0x00080000u -#define CTL_MEMORY 0x00100000u -#define CTL_NULLCONTEXT 0x00200000u -#define CTL_POSIX 0x00400000u -#define CTL_PUSH 0x00800000u -#define CTL_STARTCHAR 0x01000000u -#define CTL_ZERO_TERMINATE 0x02000000u -/* Spare 0x04000000u */ -/* Spare 0x08000000u */ -/* Spare 0x10000000u */ -/* Spare 0x20000000u */ -#define CTL_NL_SET 0x40000000u /* Informational */ -#define CTL_BSR_SET 0x80000000u /* Informational */ - -/* Second control word */ - -#define CTL2_SUBSTITUTE_EXTENDED 0x00000001u -#define CTL2_SUBSTITUTE_OVERFLOW_LENGTH 0x00000002u -#define CTL2_SUBSTITUTE_UNKNOWN_UNSET 0x00000004u -#define CTL2_SUBSTITUTE_UNSET_EMPTY 0x00000008u - -/* Combinations */ - -#define CTL_DEBUG (CTL_FULLBINCODE|CTL_INFO) /* For setting */ -#define CTL_ANYINFO (CTL_DEBUG|CTL_BINCODE|CTL_CALLOUT_INFO) -#define CTL_ANYGLOB (CTL_ALTGLOBAL|CTL_GLOBAL) - -/* These are all the controls that may be set either on a pattern or on a -data line. */ - -#define CTL_ALLPD (CTL_AFTERTEXT|\ - CTL_ALLAFTERTEXT|\ - CTL_ALLCAPTURES|\ - CTL_ALLUSEDTEXT|\ - CTL_ALTGLOBAL|\ - CTL_GLOBAL|\ - CTL_MARK|\ - CTL_MEMORY|\ - CTL_STARTCHAR) - -#define CTL2_ALLPD (CTL2_SUBSTITUTE_EXTENDED|\ - CTL2_SUBSTITUTE_OVERFLOW_LENGTH|\ - CTL2_SUBSTITUTE_UNKNOWN_UNSET|\ - CTL2_SUBSTITUTE_UNSET_EMPTY) - -/* Structures for holding modifier information for patterns and subject strings -(data). Fields containing modifiers that can be set either for a pattern or a -subject must be at the start and in the same order in both cases so that the -same offset in the big table below works for both. */ - -typedef struct patctl { /* Structure for pattern modifiers. */ - uint32_t options; /* Must be in same position as datctl */ - uint32_t control; /* Must be in same position as datctl */ - uint32_t control2; /* Must be in same position as datctl */ - uint8_t replacement[REPLACE_MODSIZE]; /* So must this */ - uint32_t jit; - uint32_t stackguard_test; - uint32_t tables_id; - uint32_t regerror_buffsize; - uint8_t locale[LOCALESIZE]; -} patctl; - -#define MAXCPYGET 10 -#define LENCPYGET 64 - -typedef struct datctl { /* Structure for data line modifiers. */ - uint32_t options; /* Must be in same position as patctl */ - uint32_t control; /* Must be in same position as patctl */ - uint32_t control2; /* Must be in same position as patctl */ - uint8_t replacement[REPLACE_MODSIZE]; /* So must this */ - uint32_t cfail[2]; - int32_t callout_data; - int32_t copy_numbers[MAXCPYGET]; - int32_t get_numbers[MAXCPYGET]; - uint32_t jitstack; - uint32_t oveccount; - uint32_t offset; - uint8_t copy_names[LENCPYGET]; - uint8_t get_names[LENCPYGET]; -} datctl; - -/* Ids for which context to modify. */ - -enum { CTX_PAT, /* Active pattern context */ - CTX_POPPAT, /* Ditto, for a popped pattern */ - CTX_DEFPAT, /* Default pattern context */ - CTX_DAT, /* Active data (match) context */ - CTX_DEFDAT }; /* Default data (match) context */ - -/* Macros to simplify the big table below. */ - -#define CO(name) offsetof(PCRE2_REAL_COMPILE_CONTEXT, name) -#define MO(name) offsetof(PCRE2_REAL_MATCH_CONTEXT, name) -#define PO(name) offsetof(patctl, name) -#define PD(name) PO(name) -#define DO(name) offsetof(datctl, name) - -/* Table of all long-form modifiers. Must be in collating sequence of modifier -name because it is searched by binary chop. */ - -typedef struct modstruct { - const char *name; - uint16_t which; - uint16_t type; - uint32_t value; - PCRE2_SIZE offset; -} modstruct; - -static modstruct modlist[] = { - { "aftertext", MOD_PNDP, MOD_CTL, CTL_AFTERTEXT, PO(control) }, - { "allaftertext", MOD_PNDP, MOD_CTL, CTL_ALLAFTERTEXT, PO(control) }, - { "allcaptures", MOD_PND, MOD_CTL, CTL_ALLCAPTURES, PO(control) }, - { "allow_empty_class", MOD_PAT, MOD_OPT, PCRE2_ALLOW_EMPTY_CLASS, PO(options) }, - { "allusedtext", MOD_PNDP, MOD_CTL, CTL_ALLUSEDTEXT, PO(control) }, - { "alt_bsux", MOD_PAT, MOD_OPT, PCRE2_ALT_BSUX, PO(options) }, - { "alt_circumflex", MOD_PAT, MOD_OPT, PCRE2_ALT_CIRCUMFLEX, PO(options) }, - { "alt_verbnames", MOD_PAT, MOD_OPT, PCRE2_ALT_VERBNAMES, PO(options) }, - { "altglobal", MOD_PND, MOD_CTL, CTL_ALTGLOBAL, PO(control) }, - { "anchored", MOD_PD, MOD_OPT, PCRE2_ANCHORED, PD(options) }, - { "auto_callout", MOD_PAT, MOD_OPT, PCRE2_AUTO_CALLOUT, PO(options) }, - { "bincode", MOD_PAT, MOD_CTL, CTL_BINCODE, PO(control) }, - { "bsr", MOD_CTC, MOD_BSR, 0, CO(bsr_convention) }, - { "callout_capture", MOD_DAT, MOD_CTL, CTL_CALLOUT_CAPTURE, DO(control) }, - { "callout_data", MOD_DAT, MOD_INS, 0, DO(callout_data) }, - { "callout_fail", MOD_DAT, MOD_IN2, 0, DO(cfail) }, - { "callout_info", MOD_PAT, MOD_CTL, CTL_CALLOUT_INFO, PO(control) }, - { "callout_none", MOD_DAT, MOD_CTL, CTL_CALLOUT_NONE, DO(control) }, - { "caseless", MOD_PATP, MOD_OPT, PCRE2_CASELESS, PO(options) }, - { "copy", MOD_DAT, MOD_NN, DO(copy_numbers), DO(copy_names) }, - { "debug", MOD_PAT, MOD_CTL, CTL_DEBUG, PO(control) }, - { "dfa", MOD_DAT, MOD_CTL, CTL_DFA, DO(control) }, - { "dfa_restart", MOD_DAT, MOD_OPT, PCRE2_DFA_RESTART, DO(options) }, - { "dfa_shortest", MOD_DAT, MOD_OPT, PCRE2_DFA_SHORTEST, DO(options) }, - { "dollar_endonly", MOD_PAT, MOD_OPT, PCRE2_DOLLAR_ENDONLY, PO(options) }, - { "dotall", MOD_PATP, MOD_OPT, PCRE2_DOTALL, PO(options) }, - { "dupnames", MOD_PATP, MOD_OPT, PCRE2_DUPNAMES, PO(options) }, - { "expand", MOD_PAT, MOD_CTL, CTL_EXPAND, PO(control) }, - { "extended", MOD_PATP, MOD_OPT, PCRE2_EXTENDED, PO(options) }, - { "find_limits", MOD_DAT, MOD_CTL, CTL_FINDLIMITS, DO(control) }, - { "firstline", MOD_PAT, MOD_OPT, PCRE2_FIRSTLINE, PO(options) }, - { "fullbincode", MOD_PAT, MOD_CTL, CTL_FULLBINCODE, PO(control) }, - { "get", MOD_DAT, MOD_NN, DO(get_numbers), DO(get_names) }, - { "getall", MOD_DAT, MOD_CTL, CTL_GETALL, DO(control) }, - { "global", MOD_PNDP, MOD_CTL, CTL_GLOBAL, PO(control) }, - { "hex", MOD_PAT, MOD_CTL, CTL_HEXPAT, PO(control) }, - { "info", MOD_PAT, MOD_CTL, CTL_INFO, PO(control) }, - { "jit", MOD_PAT, MOD_IND, 7, PO(jit) }, - { "jitfast", MOD_PAT, MOD_CTL, CTL_JITFAST, PO(control) }, - { "jitstack", MOD_DAT, MOD_INT, 0, DO(jitstack) }, - { "jitverify", MOD_PAT, MOD_CTL, CTL_JITVERIFY, PO(control) }, - { "locale", MOD_PAT, MOD_STR, LOCALESIZE, PO(locale) }, - { "mark", MOD_PNDP, MOD_CTL, CTL_MARK, PO(control) }, - { "match_limit", MOD_CTM, MOD_INT, 0, MO(match_limit) }, - { "match_unset_backref", MOD_PAT, MOD_OPT, PCRE2_MATCH_UNSET_BACKREF, PO(options) }, - { "max_pattern_length", MOD_CTC, MOD_SIZ, 0, CO(max_pattern_length) }, - { "memory", MOD_PD, MOD_CTL, CTL_MEMORY, PD(control) }, - { "multiline", MOD_PATP, MOD_OPT, PCRE2_MULTILINE, PO(options) }, - { "never_backslash_c", MOD_PAT, MOD_OPT, PCRE2_NEVER_BACKSLASH_C, PO(options) }, - { "never_ucp", MOD_PAT, MOD_OPT, PCRE2_NEVER_UCP, PO(options) }, - { "never_utf", MOD_PAT, MOD_OPT, PCRE2_NEVER_UTF, PO(options) }, - { "newline", MOD_CTC, MOD_NL, 0, CO(newline_convention) }, - { "no_auto_capture", MOD_PAT, MOD_OPT, PCRE2_NO_AUTO_CAPTURE, PO(options) }, - { "no_auto_possess", MOD_PATP, MOD_OPT, PCRE2_NO_AUTO_POSSESS, PO(options) }, - { "no_dotstar_anchor", MOD_PAT, MOD_OPT, PCRE2_NO_DOTSTAR_ANCHOR, PO(options) }, - { "no_start_optimize", MOD_PATP, MOD_OPT, PCRE2_NO_START_OPTIMIZE, PO(options) }, - { "no_utf_check", MOD_PD, MOD_OPT, PCRE2_NO_UTF_CHECK, PD(options) }, - { "notbol", MOD_DAT, MOD_OPT, PCRE2_NOTBOL, DO(options) }, - { "notempty", MOD_DAT, MOD_OPT, PCRE2_NOTEMPTY, DO(options) }, - { "notempty_atstart", MOD_DAT, MOD_OPT, PCRE2_NOTEMPTY_ATSTART, DO(options) }, - { "noteol", MOD_DAT, MOD_OPT, PCRE2_NOTEOL, DO(options) }, - { "null_context", MOD_PD, MOD_CTL, CTL_NULLCONTEXT, PO(control) }, - { "offset", MOD_DAT, MOD_INT, 0, DO(offset) }, - { "offset_limit", MOD_CTM, MOD_SIZ, 0, MO(offset_limit)}, - { "ovector", MOD_DAT, MOD_INT, 0, DO(oveccount) }, - { "parens_nest_limit", MOD_CTC, MOD_INT, 0, CO(parens_nest_limit) }, - { "partial_hard", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_HARD, DO(options) }, - { "partial_soft", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, - { "ph", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_HARD, DO(options) }, - { "posix", MOD_PAT, MOD_CTL, CTL_POSIX, PO(control) }, - { "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, - { "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) }, - { "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) }, - { "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) }, - { "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) }, - { "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) }, - { "startchar", MOD_PND, MOD_CTL, CTL_STARTCHAR, PO(control) }, - { "startoffset", MOD_DAT, MOD_INT, 0, DO(offset) }, - { "substitute_extended", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_EXTENDED, PO(control2) }, - { "substitute_overflow_length", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_OVERFLOW_LENGTH, PO(control2) }, - { "substitute_unknown_unset", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_UNKNOWN_UNSET, PO(control2) }, - { "substitute_unset_empty", MOD_PND, MOD_CTL, CTL2_SUBSTITUTE_UNSET_EMPTY, PO(control2) }, - { "tables", MOD_PAT, MOD_INT, 0, PO(tables_id) }, - { "ucp", MOD_PATP, MOD_OPT, PCRE2_UCP, PO(options) }, - { "ungreedy", MOD_PAT, MOD_OPT, PCRE2_UNGREEDY, PO(options) }, - { "use_offset_limit", MOD_PAT, MOD_OPT, PCRE2_USE_OFFSET_LIMIT, PO(options) }, - { "utf", MOD_PATP, MOD_OPT, PCRE2_UTF, PO(options) }, - { "zero_terminate", MOD_DAT, MOD_CTL, CTL_ZERO_TERMINATE, DO(control) } -}; - -#define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct) - -/* Controls and options that are supported for use with the POSIX interface. */ - -#define POSIX_SUPPORTED_COMPILE_OPTIONS ( \ - PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ - PCRE2_UCP|PCRE2_UTF|PCRE2_UNGREEDY) - -#define POSIX_SUPPORTED_COMPILE_CONTROLS ( \ - CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_POSIX) - -#define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0) - -#define POSIX_SUPPORTED_MATCH_OPTIONS ( \ - PCRE2_NOTBOL|PCRE2_NOTEMPTY|PCRE2_NOTEOL) - -#define POSIX_SUPPORTED_MATCH_CONTROLS (CTL_AFTERTEXT|CTL_ALLAFTERTEXT) -#define POSIX_SUPPORTED_MATCH_CONTROLS2 (0) - -/* Control bits that are not ignored with 'push'. */ - -#define PUSH_SUPPORTED_COMPILE_CONTROLS ( \ - CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \ - CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_BSR_SET|CTL_NL_SET) - -#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (0) - -/* Controls that apply only at compile time with 'push'. */ - -#define PUSH_COMPILE_ONLY_CONTROLS CTL_JITVERIFY -#define PUSH_COMPILE_ONLY_CONTROLS2 (0) - -/* Controls that are forbidden with #pop. */ - -#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_PUSH) - -/* Pattern controls that are mutually exclusive. At present these are all in -the first control word. */ - -static uint32_t exclusive_pat_controls[] = { - CTL_POSIX | CTL_HEXPAT, - CTL_POSIX | CTL_PUSH, - CTL_EXPAND | CTL_HEXPAT }; - -/* Data controls that are mutually exclusive. At present these are all in the -first control word. */ -static uint32_t exclusive_dat_controls[] = { - CTL_ALLUSEDTEXT | CTL_STARTCHAR, - CTL_FINDLIMITS | CTL_NULLCONTEXT }; - -/* Table of single-character abbreviated modifiers. The index field is -initialized to -1, but the first time the modifier is encountered, it is filled -in with the index of the full entry in modlist, to save repeated searching when -processing multiple test items. This short list is searched serially, so its -order does not matter. */ - -typedef struct c1modstruct { - const char *fullname; - uint32_t onechar; - int index; -} c1modstruct; - -static c1modstruct c1modlist[] = { - { "bincode", 'B', -1 }, - { "info", 'I', -1 }, - { "global", 'g', -1 }, - { "caseless", 'i', -1 }, - { "multiline", 'm', -1 }, - { "dotall", 's', -1 }, - { "extended", 'x', -1 } -}; - -#define C1MODLISTCOUNT sizeof(c1modlist)/sizeof(c1modstruct) - -/* Table of arguments for the -C command line option. Use macros to make the -table itself easier to read. */ - -#if defined SUPPORT_PCRE2_8 -#define SUPPORT_8 1 -#endif -#if defined SUPPORT_PCRE2_16 -#define SUPPORT_16 1 -#endif -#if defined SUPPORT_PCRE2_32 -#define SUPPORT_32 1 -#endif - -#ifndef SUPPORT_8 -#define SUPPORT_8 0 -#endif -#ifndef SUPPORT_16 -#define SUPPORT_16 0 -#endif -#ifndef SUPPORT_32 -#define SUPPORT_32 0 -#endif - -#ifdef EBCDIC -#define SUPPORT_EBCDIC 1 -#define EBCDIC_NL CHAR_LF -#else -#define SUPPORT_EBCDIC 0 -#define EBCDIC_NL 0 -#endif - -#ifdef NEVER_BACKSLASH_C -#define BACKSLASH_C 0 -#else -#define BACKSLASH_C 1 -#endif - -typedef struct coptstruct { - const char *name; - uint32_t type; - uint32_t value; -} coptstruct; - -enum { CONF_BSR, - CONF_FIX, - CONF_FIZ, - CONF_INT, - CONF_NL -}; - -static coptstruct coptlist[] = { - { "backslash-C", CONF_FIX, BACKSLASH_C }, - { "bsr", CONF_BSR, PCRE2_CONFIG_BSR }, - { "ebcdic", CONF_FIX, SUPPORT_EBCDIC }, - { "ebcdic-nl", CONF_FIZ, EBCDIC_NL }, - { "jit", CONF_INT, PCRE2_CONFIG_JIT }, - { "linksize", CONF_INT, PCRE2_CONFIG_LINKSIZE }, - { "newline", CONF_NL, PCRE2_CONFIG_NEWLINE }, - { "pcre2-16", CONF_FIX, SUPPORT_16 }, - { "pcre2-32", CONF_FIX, SUPPORT_32 }, - { "pcre2-8", CONF_FIX, SUPPORT_8 }, - { "unicode", CONF_INT, PCRE2_CONFIG_UNICODE } -}; - -#define COPTLISTCOUNT sizeof(coptlist)/sizeof(coptstruct) - -#undef SUPPORT_8 -#undef SUPPORT_16 -#undef SUPPORT_32 -#undef SUPPORT_EBCDIC - - -/* ----------------------- Static variables ------------------------ */ - -static FILE *infile; -static FILE *outfile; - -static const void *last_callout_mark; -static PCRE2_JIT_STACK *jit_stack = NULL; -static size_t jit_stack_size = 0; - -static BOOL first_callout; -static BOOL jit_was_used; -static BOOL restrict_for_perl_test = FALSE; -static BOOL show_memory = FALSE; - -static int code_unit_size; /* Bytes */ -static int jitrc; /* Return from JIT compile */ -static int test_mode = DEFAULT_TEST_MODE; -static int timeit = 0; -static int timeitm = 0; - -clock_t total_compile_time = 0; -clock_t total_jit_compile_time = 0; -clock_t total_match_time = 0; - -static uint32_t dfa_matched; -static uint32_t forbid_utf = 0; -static uint32_t maxlookbehind; -static uint32_t max_oveccount; -static uint32_t callout_count; - -static uint16_t local_newline_default = 0; - -static VERSION_TYPE jittarget[VERSION_SIZE]; -static VERSION_TYPE version[VERSION_SIZE]; -static VERSION_TYPE uversion[VERSION_SIZE]; - -static patctl def_patctl; -static patctl pat_patctl; -static datctl def_datctl; -static datctl dat_datctl; - -static void *patstack[PATSTACKSIZE]; -static int patstacknext = 0; - -#ifdef SUPPORT_PCRE2_8 -static regex_t preg = { NULL, NULL, 0, 0 }; -#endif - -static int *dfa_workspace = NULL; -static const uint8_t *locale_tables = NULL; -static uint8_t locale_name[32]; - -/* We need buffers for building 16/32-bit strings; 8-bit strings don't need -rebuilding, but set up the same naming scheme for use in macros. The "buffer" -buffer is where all input lines are read. Its size is the same as pbuffer8. -Pattern lines are always copied to pbuffer8 for use in callouts, even if they -are actually compiled from pbuffer16 or pbuffer32. */ - -static size_t pbuffer8_size = 50000; /* Initial size, bytes */ -static uint8_t *pbuffer8 = NULL; -static uint8_t *buffer = NULL; - -/* The dbuffer is where all processed data lines are put. In non-8-bit modes it -is cast as needed. For long data lines it grows as necessary. */ - -static size_t dbuffer_size = 1u << 14; /* Initial size, bytes */ -static uint8_t *dbuffer = NULL; - - -/* ---------------- Mode-dependent variables -------------------*/ - -#ifdef SUPPORT_PCRE2_8 -static pcre2_code_8 *compiled_code8; -static pcre2_general_context_8 *general_context8, *general_context_copy8; -static pcre2_compile_context_8 *pat_context8, *default_pat_context8; -static pcre2_match_context_8 *dat_context8, *default_dat_context8; -static pcre2_match_data_8 *match_data8; -#endif - -#ifdef SUPPORT_PCRE2_16 -static pcre2_code_16 *compiled_code16; -static pcre2_general_context_16 *general_context16, *general_context_copy16; -static pcre2_compile_context_16 *pat_context16, *default_pat_context16; -static pcre2_match_context_16 *dat_context16, *default_dat_context16; -static pcre2_match_data_16 *match_data16; -static PCRE2_SIZE pbuffer16_size = 0; /* Set only when needed */ -static uint16_t *pbuffer16 = NULL; -#endif - -#ifdef SUPPORT_PCRE2_32 -static pcre2_code_32 *compiled_code32; -static pcre2_general_context_32 *general_context32, *general_context_copy32; -static pcre2_compile_context_32 *pat_context32, *default_pat_context32; -static pcre2_match_context_32 *dat_context32, *default_dat_context32; -static pcre2_match_data_32 *match_data32; -static PCRE2_SIZE pbuffer32_size = 0; /* Set only when needed */ -static uint32_t *pbuffer32 = NULL; -#endif - - -/* ---------------- Macros that work in all modes ----------------- */ - -#define CAST8VAR(x) CASTVAR(uint8_t *, x) -#define SET(x,y) SETOP(x,y,=) -#define SETPLUS(x,y) SETOP(x,y,+=) -#define strlen8(x) strlen((char *)x) - - -/* ---------------- Mode-dependent, runtime-testing macros ------------------*/ - -/* Define macros for variables and functions that must be selected dynamically -depending on the mode setting (8, 16, 32). These are dependent on which modes -are supported. */ - -#if (defined (SUPPORT_PCRE2_8) + defined (SUPPORT_PCRE2_16) + \ - defined (SUPPORT_PCRE2_32)) >= 2 - -/* ----- All three modes supported ----- */ - -#if defined(SUPPORT_PCRE2_8) && defined(SUPPORT_PCRE2_16) && defined(SUPPORT_PCRE2_32) - -#define CASTFLD(t,a,b) ((test_mode == PCRE8_MODE)? (t)(G(a,8)->b) : \ - (test_mode == PCRE16_MODE)? (t)(G(a,16)->b) : (t)(G(a,32)->b)) - -#define CASTVAR(t,x) ( \ - (test_mode == PCRE8_MODE)? (t)G(x,8) : \ - (test_mode == PCRE16_MODE)? (t)G(x,16) : (t)G(x,32)) - -#define CODE_UNIT(a,b) ( \ - (test_mode == PCRE8_MODE)? (uint32_t)(((PCRE2_SPTR8)(a))[b]) : \ - (test_mode == PCRE16_MODE)? (uint32_t)(((PCRE2_SPTR16)(a))[b]) : \ - (uint32_t)(((PCRE2_SPTR32)(a))[b])) - -#define DATCTXCPY(a,b) \ - if (test_mode == PCRE8_MODE) \ - memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)); \ - else if (test_mode == PCRE16_MODE) \ - memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)); \ - else memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32)) - -#define FLD(a,b) ((test_mode == PCRE8_MODE)? G(a,8)->b : \ - (test_mode == PCRE16_MODE)? G(a,16)->b : G(a,32)->b) - -#define PATCTXCPY(a,b) \ - if (test_mode == PCRE8_MODE) \ - memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)); \ - else if (test_mode == PCRE16_MODE) \ - memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)); \ - else memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32)) - -#define PCHARS(lv, p, offset, len, utf, f) \ - if (test_mode == PCRE32_MODE) \ - lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \ - else if (test_mode == PCRE16_MODE) \ - lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \ - else \ - lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) - -#define PCHARSV(p, offset, len, utf, f) \ - if (test_mode == PCRE32_MODE) \ - (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \ - else if (test_mode == PCRE16_MODE) \ - (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \ - else \ - (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) - -#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_callout_enumerate_8(compiled_code8, \ - (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_callout_enumerate_16(compiled_code16, \ - (int(*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c); \ - else \ - a = pcre2_callout_enumerate_32(compiled_code32, \ - (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) - -#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ - if (test_mode == PCRE8_MODE) \ - G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g); \ - else if (test_mode == PCRE16_MODE) \ - G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g); \ - else \ - G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g) - -#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j); \ - else \ - a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j) - -#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ - if (test_mode == PCRE8_MODE) \ - r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)); \ - else if (test_mode == PCRE16_MODE) \ - r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)); \ - else \ - r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) - -#define PCRE2_GET_OVECTOR_COUNT(a,b) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_get_ovector_count_8(G(b,8)); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_get_ovector_count_16(G(b,16)); \ - else \ - a = pcre2_get_ovector_count_32(G(b,32)) - -#define PCRE2_GET_STARTCHAR(a,b) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_get_startchar_8(G(b,8)); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_get_startchar_16(G(b,16)); \ - else \ - a = pcre2_get_startchar_32(G(b,32)) - -#define PCRE2_JIT_COMPILE(r,a,b) \ - if (test_mode == PCRE8_MODE) r = pcre2_jit_compile_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) r = pcre2_jit_compile_16(G(a,16),b); \ - else r = pcre2_jit_compile_32(G(a,32),b) - -#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ - if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \ - else if (test_mode == PCRE16_MODE) pcre2_jit_free_unused_memory_16(G(a,16)); \ - else pcre2_jit_free_unused_memory_32(G(a,32)) - -#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \ - else \ - a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) - -#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); \ - else if (test_mode == PCRE16_MODE) \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); \ - else \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d); - -#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); \ - else \ - pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c); - -#define PCRE2_JIT_STACK_FREE(a) \ - if (test_mode == PCRE8_MODE) \ - pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); \ - else \ - pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a); - -#define PCRE2_MAKETABLES(a) \ - if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(NULL); \ - else if (test_mode == PCRE16_MODE) a = pcre2_maketables_16(NULL); \ - else a = pcre2_maketables_32(NULL) - -#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \ - else \ - a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) - -#define PCRE2_MATCH_DATA_CREATE(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - G(a,8) = pcre2_match_data_create_8(b,c); \ - else if (test_mode == PCRE16_MODE) \ - G(a,16) = pcre2_match_data_create_16(b,c); \ - else \ - G(a,32) = pcre2_match_data_create_32(b,c) - -#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c); \ - else if (test_mode == PCRE16_MODE) \ - G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c); \ - else \ - G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c) - -#define PCRE2_MATCH_DATA_FREE(a) \ - if (test_mode == PCRE8_MODE) \ - pcre2_match_data_free_8(G(a,8)); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_match_data_free_16(G(a,16)); \ - else \ - pcre2_match_data_free_32(G(a,32)) - -#define PCRE2_PATTERN_INFO(a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_pattern_info_8(G(b,8),c,d); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_pattern_info_16(G(b,16),c,d); \ - else \ - a = pcre2_pattern_info_32(G(b,32),c,d) - -#define PCRE2_PRINTINT(a) \ - if (test_mode == PCRE8_MODE) \ - pcre2_printint_8(compiled_code8,outfile,a); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_printint_16(compiled_code16,outfile,a); \ - else \ - pcre2_printint_32(compiled_code32,outfile,a) - -#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)); \ - else if (test_mode == PCRE16_MODE) \ - r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)); \ - else \ - r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32)) - -#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ - if (test_mode == PCRE8_MODE) \ - r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)); \ - else if (test_mode == PCRE16_MODE) \ - r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)); \ - else \ - r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32)) - -#define PCRE2_SERIALIZE_FREE(a) \ - if (test_mode == PCRE8_MODE) \ - pcre2_serialize_free_8(a); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_serialize_free_16(a); \ - else \ - pcre2_serialize_free_32(a) - -#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ - if (test_mode == PCRE8_MODE) \ - r = pcre2_serialize_get_number_of_codes_8(a); \ - else if (test_mode == PCRE16_MODE) \ - r = pcre2_serialize_get_number_of_codes_16(a); \ - else \ - r = pcre2_serialize_get_number_of_codes_32(a); \ - -#define PCRE2_SET_CALLOUT(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); \ - else \ - pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c); - -#define PCRE2_SET_CHARACTER_TABLES(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_character_tables_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_character_tables_16(G(a,16),b); \ - else \ - pcre2_set_character_tables_32(G(a,32),b) - -#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_compile_recursion_guard_8(G(a,8),b,c); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_compile_recursion_guard_16(G(a,16),b,c); \ - else \ - pcre2_set_compile_recursion_guard_32(G(a,32),b,c) - -#define PCRE2_SET_MATCH_LIMIT(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_match_limit_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_match_limit_16(G(a,16),b); \ - else \ - pcre2_set_match_limit_32(G(a,32),b) - -#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_max_pattern_length_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_max_pattern_length_16(G(a,16),b); \ - else \ - pcre2_set_max_pattern_length_32(G(a,32),b) - -#define PCRE2_SET_OFFSET_LIMIT(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_offset_limit_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_offset_limit_16(G(a,16),b); \ - else \ - pcre2_set_offset_limit_32(G(a,32),b) - -#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_parens_nest_limit_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_parens_nest_limit_16(G(a,16),b); \ - else \ - pcre2_set_parens_nest_limit_32(G(a,32),b) - -#define PCRE2_SET_RECURSION_LIMIT(a,b) \ - if (test_mode == PCRE8_MODE) \ - pcre2_set_recursion_limit_8(G(a,8),b); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_set_recursion_limit_16(G(a,16),b); \ - else \ - pcre2_set_recursion_limit_32(G(a,32),b) - -#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ - (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \ - (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \ - else \ - a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \ - (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l) - -#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e); \ - else \ - a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e) - -#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e); \ - else \ - a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e) - -#define PCRE2_SUBSTRING_FREE(a) \ - if (test_mode == PCRE8_MODE) pcre2_substring_free_8((PCRE2_UCHAR8 *)a); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_substring_free_16((PCRE2_UCHAR16 *)a); \ - else pcre2_substring_free_32((PCRE2_UCHAR32 *)a) - -#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e); \ - else \ - a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e) - -#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e); \ - else \ - a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e) - -#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d); \ - else \ - a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d) - -#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_length_bynumber_8(G(b,8),c,d); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_length_bynumber_16(G(b,16),c,d); \ - else \ - a = pcre2_substring_length_bynumber_32(G(b,32),c,d) - -#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d); \ - else \ - a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d) - -#define PCRE2_SUBSTRING_LIST_FREE(a) \ - if (test_mode == PCRE8_MODE) \ - pcre2_substring_list_free_8((PCRE2_SPTR8 *)a); \ - else if (test_mode == PCRE16_MODE) \ - pcre2_substring_list_free_16((PCRE2_SPTR16 *)a); \ - else \ - pcre2_substring_list_free_32((PCRE2_SPTR32 *)a) - -#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ - if (test_mode == PCRE8_MODE) \ - a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); \ - else if (test_mode == PCRE16_MODE) \ - a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); \ - else \ - a = pcre2_substring_number_from_name_32(G(b,32),G(c,32)) - -#define PTR(x) ( \ - (test_mode == PCRE8_MODE)? (void *)G(x,8) : \ - (test_mode == PCRE16_MODE)? (void *)G(x,16) : \ - (void *)G(x,32)) - -#define SETFLD(x,y,z) \ - if (test_mode == PCRE8_MODE) G(x,8)->y = z; \ - else if (test_mode == PCRE16_MODE) G(x,16)->y = z; \ - else G(x,32)->y = z - -#define SETFLDVEC(x,y,v,z) \ - if (test_mode == PCRE8_MODE) G(x,8)->y[v] = z; \ - else if (test_mode == PCRE16_MODE) G(x,16)->y[v] = z; \ - else G(x,32)->y[v] = z - -#define SETOP(x,y,z) \ - if (test_mode == PCRE8_MODE) G(x,8) z y; \ - else if (test_mode == PCRE16_MODE) G(x,16) z y; \ - else G(x,32) z y - -#define SETCASTPTR(x,y) \ - if (test_mode == PCRE8_MODE) \ - G(x,8) = (uint8_t *)(y); \ - else if (test_mode == PCRE16_MODE) \ - G(x,16) = (uint16_t *)(y); \ - else \ - G(x,32) = (uint32_t *)(y) - -#define STRLEN(p) ((test_mode == PCRE8_MODE)? ((int)strlen((char *)p)) : \ - (test_mode == PCRE16_MODE)? ((int)strlen16((PCRE2_SPTR16)p)) : \ - ((int)strlen32((PCRE2_SPTR32)p))) - -#define SUB1(a,b) \ - if (test_mode == PCRE8_MODE) G(a,8)(G(b,8)); \ - else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16)); \ - else G(a,32)(G(b,32)) - -#define SUB2(a,b,c) \ - if (test_mode == PCRE8_MODE) G(a,8)(G(b,8),G(c,8)); \ - else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16),G(c,16)); \ - else G(a,32)(G(b,32),G(c,32)) - -#define TEST(x,r,y) ( \ - (test_mode == PCRE8_MODE && G(x,8) r (y)) || \ - (test_mode == PCRE16_MODE && G(x,16) r (y)) || \ - (test_mode == PCRE32_MODE && G(x,32) r (y))) - -#define TESTFLD(x,f,r,y) ( \ - (test_mode == PCRE8_MODE && G(x,8)->f r (y)) || \ - (test_mode == PCRE16_MODE && G(x,16)->f r (y)) || \ - (test_mode == PCRE32_MODE && G(x,32)->f r (y))) - - - -/* ----- Two out of three modes are supported ----- */ - -#else - -/* We can use some macro trickery to make a single set of definitions work in -the three different cases. */ - -/* ----- 32-bit and 16-bit but not 8-bit supported ----- */ - -#if defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_16) -#define BITONE 32 -#define BITTWO 16 - -/* ----- 32-bit and 8-bit but not 16-bit supported ----- */ - -#elif defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_8) -#define BITONE 32 -#define BITTWO 8 - -/* ----- 16-bit and 8-bit but not 32-bit supported ----- */ - -#else -#define BITONE 16 -#define BITTWO 8 -#endif - - -/* ----- Common macros for two-mode cases ----- */ - -#define CASTFLD(t,a,b) \ - ((test_mode == G(G(PCRE,BITONE),_MODE))? (t)(G(a,BITONE)->b) : \ - (t)(G(a,BITTWO)->b)) - -#define CASTVAR(t,x) ( \ - (test_mode == G(G(PCRE,BITONE),_MODE))? \ - (t)G(x,BITONE) : (t)G(x,BITTWO)) - -#define CODE_UNIT(a,b) ( \ - (test_mode == G(G(PCRE,BITONE),_MODE))? \ - (uint32_t)(((G(PCRE2_SPTR,BITONE))(a))[b]) : \ - (uint32_t)(((G(PCRE2_SPTR,BITTWO))(a))[b])) - -#define DATCTXCPY(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_match_context_,BITONE))); \ - else \ - memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_match_context_,BITTWO))) - -#define FLD(a,b) \ - ((test_mode == G(G(PCRE,BITONE),_MODE))? G(a,BITONE)->b : G(a,BITTWO)->b) - -#define PATCTXCPY(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_compile_context_,BITONE))); \ - else \ - memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_compile_context_,BITTWO))) - -#define PCHARS(lv, p, offset, len, utf, f) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - lv = G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \ - else \ - lv = G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f) - -#define PCHARSV(p, offset, len, utf, f) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - (void)G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \ - else \ - (void)G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f) - -#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_callout_enumerate,BITONE)(G(compiled_code,BITONE), \ - (int (*)(struct G(pcre2_callout_enumerate_block_,BITONE) *, void *))b,c); \ - else \ - a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \ - (int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c) - -#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(a,BITONE) = G(pcre2_compile_,BITONE)(G(b,BITONE),c,d,e,f,g); \ - else \ - G(a,BITTWO) = G(pcre2_compile_,BITTWO)(G(b,BITTWO),c,d,e,f,g) - -#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_dfa_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ - G(g,BITONE),h,i,j); \ - else \ - a = G(pcre2_dfa_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ - G(g,BITTWO),h,i,j) - -#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - r = G(pcre2_get_error_message_,BITONE)(a,G(b,BITONE),G(G(b,BITONE),_size)); \ - else \ - r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size)) - -#define PCRE2_GET_OVECTOR_COUNT(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_get_ovector_count_,BITONE)(G(b,BITONE)); \ - else \ - a = G(pcre2_get_ovector_count_,BITTWO)(G(b,BITTWO)) - -#define PCRE2_GET_STARTCHAR(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_get_startchar_,BITONE)(G(b,BITONE)); \ - else \ - a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO)) - -#define PCRE2_JIT_COMPILE(r,a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - r = G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \ - else \ - r = G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_jit_free_unused_memory_,BITONE)(G(a,BITONE)); \ - else \ - G(pcre2_jit_free_unused_memory_,BITTWO)(G(a,BITTWO)) - -#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_jit_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ - G(g,BITONE),h); \ - else \ - a = G(pcre2_jit_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ - G(g,BITTWO),h) - -#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITONE)(b,c,d); \ - else \ - a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITTWO)(b,c,d); \ - -#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_jit_stack_assign_,BITONE)(G(a,BITONE),(G(pcre2_jit_callback_,BITONE))b,c); \ - else \ - G(pcre2_jit_stack_assign_,BITTWO)(G(a,BITTWO),(G(pcre2_jit_callback_,BITTWO))b,c); - -#define PCRE2_JIT_STACK_FREE(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_jit_stack_free_,BITONE)((G(pcre2_jit_stack_,BITONE) *)a); \ - else \ - G(pcre2_jit_stack_free_,BITTWO)((G(pcre2_jit_stack_,BITTWO) *)a); - -#define PCRE2_MAKETABLES(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_maketables_,BITONE)(NULL); \ - else \ - a = G(pcre2_maketables_,BITTWO)(NULL) - -#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ - G(g,BITONE),h); \ - else \ - a = G(pcre2_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ - G(g,BITTWO),h) - -#define PCRE2_MATCH_DATA_CREATE(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(a,BITONE) = G(pcre2_match_data_create_,BITONE)(b,c); \ - else \ - G(a,BITTWO) = G(pcre2_match_data_create_,BITTWO)(b,c) - -#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(a,BITONE) = G(pcre2_match_data_create_from_pattern_,BITONE)(G(b,BITONE),c); \ - else \ - G(a,BITTWO) = G(pcre2_match_data_create_from_pattern_,BITTWO)(G(b,BITTWO),c) - -#define PCRE2_MATCH_DATA_FREE(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_match_data_free_,BITONE)(G(a,BITONE)); \ - else \ - G(pcre2_match_data_free_,BITTWO)(G(a,BITTWO)) - -#define PCRE2_PATTERN_INFO(a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_pattern_info_,BITONE)(G(b,BITONE),c,d); \ - else \ - a = G(pcre2_pattern_info_,BITTWO)(G(b,BITTWO),c,d) - -#define PCRE2_PRINTINT(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_printint_,BITONE)(G(compiled_code,BITONE),outfile,a); \ - else \ - G(pcre2_printint_,BITTWO)(G(compiled_code,BITTWO),outfile,a) - -#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - r = G(pcre2_serialize_decode_,BITONE)((G(pcre2_code_,BITONE) **)a,b,c,G(d,BITONE)); \ - else \ - r = G(pcre2_serialize_decode_,BITTWO)((G(pcre2_code_,BITTWO) **)a,b,c,G(d,BITTWO)) - -#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - r = G(pcre2_serialize_encode_,BITONE)((G(const pcre2_code_,BITONE) **)a,b,c,d,G(e,BITONE)); \ - else \ - r = G(pcre2_serialize_encode_,BITTWO)((G(const pcre2_code_,BITTWO) **)a,b,c,d,G(e,BITTWO)) - -#define PCRE2_SERIALIZE_FREE(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_serialize_free_,BITONE)(a); \ - else \ - G(pcre2_serialize_free_,BITTWO)(a) - -#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - r = G(pcre2_serialize_get_number_of_codes_,BITONE)(a); \ - else \ - r = G(pcre2_serialize_get_number_of_codes_,BITTWO)(a) - -#define PCRE2_SET_CALLOUT(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_callout_,BITONE)(G(a,BITONE), \ - (int (*)(G(pcre2_callout_block_,BITONE) *, void *))b,c); \ - else \ - G(pcre2_set_callout_,BITTWO)(G(a,BITTWO), \ - (int (*)(G(pcre2_callout_block_,BITTWO) *, void *))b,c); - -#define PCRE2_SET_CHARACTER_TABLES(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_character_tables_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_character_tables_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_compile_recursion_guard_,BITONE)(G(a,BITONE),b,c); \ - else \ - G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c) - -#define PCRE2_SET_MATCH_LIMIT(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_match_limit_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_max_pattern_length_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_max_pattern_length_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SET_OFFSET_LIMIT(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_offset_limit_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_offset_limit_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_parens_nest_limit_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SET_RECURSION_LIMIT(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_set_recursion_limit_,BITONE)(G(a,BITONE),b); \ - else \ - G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b) - -#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ - G(g,BITONE),G(h,BITONE),(G(PCRE2_SPTR,BITONE))i,j, \ - (G(PCRE2_UCHAR,BITONE) *)k,l); \ - else \ - a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \ - G(g,BITTWO),G(h,BITTWO),(G(PCRE2_SPTR,BITTWO))i,j, \ - (G(PCRE2_UCHAR,BITTWO) *)k,l) - -#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\ - (G(PCRE2_UCHAR,BITONE) *)d,e); \ - else \ - a = G(pcre2_substring_copy_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\ - (G(PCRE2_UCHAR,BITTWO) *)d,e) - -#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_copy_bynumber_,BITONE)(G(b,BITONE),c,\ - (G(PCRE2_UCHAR,BITONE) *)d,e); \ - else \ - a = G(pcre2_substring_copy_bynumber_,BITTWO)(G(b,BITTWO),c,\ - (G(PCRE2_UCHAR,BITTWO) *)d,e) - -#define PCRE2_SUBSTRING_FREE(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_substring_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \ - else G(pcre2_substring_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a) - -#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_get_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\ - (G(PCRE2_UCHAR,BITONE) **)d,e); \ - else \ - a = G(pcre2_substring_get_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\ - (G(PCRE2_UCHAR,BITTWO) **)d,e) - -#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_get_bynumber_,BITONE)(G(b,BITONE),c,\ - (G(PCRE2_UCHAR,BITONE) **)d,e); \ - else \ - a = G(pcre2_substring_get_bynumber_,BITTWO)(G(b,BITTWO),c,\ - (G(PCRE2_UCHAR,BITTWO) **)d,e) - -#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_length_byname_,BITONE)(G(b,BITONE),G(c,BITONE),d); \ - else \ - a = G(pcre2_substring_length_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),d) - -#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_length_bynumber_,BITONE)(G(b,BITONE),c,d); \ - else \ - a = G(pcre2_substring_length_bynumber_,BITTWO)(G(b,BITTWO),c,d) - -#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_list_get_,BITONE)(G(b,BITONE), \ - (G(PCRE2_UCHAR,BITONE) ***)c,d); \ - else \ - a = G(pcre2_substring_list_get_,BITTWO)(G(b,BITTWO), \ - (G(PCRE2_UCHAR,BITTWO) ***)c,d) - -#define PCRE2_SUBSTRING_LIST_FREE(a) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(pcre2_substring_list_free_,BITONE)((G(PCRE2_SPTR,BITONE) *)a); \ - else \ - G(pcre2_substring_list_free_,BITTWO)((G(PCRE2_SPTR,BITTWO) *)a) - -#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - a = G(pcre2_substring_number_from_name_,BITONE)(G(b,BITONE),G(c,BITONE)); \ - else \ - a = G(pcre2_substring_number_from_name_,BITTWO)(G(b,BITTWO),G(c,BITTWO)) - -#define PTR(x) ( \ - (test_mode == G(G(PCRE,BITONE),_MODE))? (void *)G(x,BITONE) : \ - (void *)G(x,BITTWO)) - -#define SETFLD(x,y,z) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y = z; \ - else G(x,BITTWO)->y = z - -#define SETFLDVEC(x,y,v,z) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y[v] = z; \ - else G(x,BITTWO)->y[v] = z - -#define SETOP(x,y,z) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE) z y; \ - else G(x,BITTWO) z y - -#define SETCASTPTR(x,y) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(x,BITONE) = (G(G(uint,BITONE),_t) *)(y); \ - else \ - G(x,BITTWO) = (G(G(uint,BITTWO),_t) *)(y) - -#define STRLEN(p) ((test_mode == G(G(PCRE,BITONE),_MODE))? \ - G(strlen,BITONE)((G(PCRE2_SPTR,BITONE))p) : \ - G(strlen,BITTWO)((G(PCRE2_SPTR,BITTWO))p)) - -#define SUB1(a,b) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(a,BITONE)(G(b,BITONE)); \ - else \ - G(a,BITTWO)(G(b,BITTWO)) - -#define SUB2(a,b,c) \ - if (test_mode == G(G(PCRE,BITONE),_MODE)) \ - G(a,BITONE))(G(b,BITONE),G(c,BITONE)); \ - else \ - G(a,BITTWO))(G(b,BITTWO),G(c,BITTWO)) - -#define TEST(x,r,y) ( \ - (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE) r (y)) || \ - (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO) r (y))) - -#define TESTFLD(x,f,r,y) ( \ - (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE)->f r (y)) || \ - (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO)->f r (y))) - - -#endif /* Two out of three modes */ - -/* ----- End of cases where more than one mode is supported ----- */ - - -/* ----- Only 8-bit mode is supported ----- */ - -#elif defined SUPPORT_PCRE2_8 -#define CASTFLD(t,a,b) (t)(G(a,8)->b) -#define CASTVAR(t,x) (t)G(x,8) -#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR8)(a))[b]) -#define DATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)) -#define FLD(a,b) G(a,8)->b -#define PATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)) -#define PCHARS(lv, p, offset, len, utf, f) \ - lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) -#define PCHARSV(p, offset, len, utf, f) \ - (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f) -#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ - a = pcre2_callout_enumerate_8(compiled_code8, \ - (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c) -#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ - G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g) -#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ - a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j) -#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ - r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)) -#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8)) -#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8)) -#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_8(G(a,8),b) -#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8)) -#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h) -#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); -#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ - pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); -#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); -#define PCRE2_MAKETABLES(a) a = pcre2_maketables_8(NULL) -#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h) -#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,8) = pcre2_match_data_create_8(b,c) -#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ - G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c) -#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_8(G(a,8)) -#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_8(G(b,8),c,d) -#define PCRE2_PRINTINT(a) pcre2_printint_8(compiled_code8,outfile,a) -#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ - r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)) -#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ - r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)) -#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_8(a) -#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ - r = pcre2_serialize_get_number_of_codes_8(a) -#define PCRE2_SET_CALLOUT(a,b,c) \ - pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c) -#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b) -#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ - pcre2_set_compile_recursion_guard_8(G(a,8),b,c) -#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b) -#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b) -#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b) -#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b) -#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b) -#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ - a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ - (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l) -#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e) -#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e) -#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_8((PCRE2_UCHAR8 *)a) -#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e) -#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e) -#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ - a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d) -#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ - a = pcre2_substring_length_bynumber_8(G(b,8),c,d) -#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ - a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d) -#define PCRE2_SUBSTRING_LIST_FREE(a) \ - pcre2_substring_list_free_8((PCRE2_SPTR8 *)a) -#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ - a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); -#define PTR(x) (void *)G(x,8) -#define SETFLD(x,y,z) G(x,8)->y = z -#define SETFLDVEC(x,y,v,z) G(x,8)->y[v] = z -#define SETOP(x,y,z) G(x,8) z y -#define SETCASTPTR(x,y) G(x,8) = (uint8_t *)(y) -#define STRLEN(p) (int)strlen((char *)p) -#define SUB1(a,b) G(a,8)(G(b,8)) -#define SUB2(a,b,c) G(a,8)(G(b,8),G(c,8)) -#define TEST(x,r,y) (G(x,8) r (y)) -#define TESTFLD(x,f,r,y) (G(x,8)->f r (y)) - - -/* ----- Only 16-bit mode is supported ----- */ - -#elif defined SUPPORT_PCRE2_16 -#define CASTFLD(t,a,b) (t)(G(a,16)->b) -#define CASTVAR(t,x) (t)G(x,16) -#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR16)(a))[b]) -#define DATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)) -#define FLD(a,b) G(a,16)->b -#define PATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)) -#define PCHARS(lv, p, offset, len, utf, f) \ - lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f) -#define PCHARSV(p, offset, len, utf, f) \ - (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f) -#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ - a = pcre2_callout_enumerate_16(compiled_code16, \ - (int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c) -#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ - G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g) -#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ - a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j) -#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ - r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)) -#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16)) -#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16)) -#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_16(G(a,16),b) -#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16)) -#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h) -#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); -#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ - pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); -#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); -#define PCRE2_MAKETABLES(a) a = pcre2_maketables_16(NULL) -#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h) -#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,16) = pcre2_match_data_create_16(b,c) -#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ - G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c) -#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_16(G(a,16)) -#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_16(G(b,16),c,d) -#define PCRE2_PRINTINT(a) pcre2_printint_16(compiled_code16,outfile,a) -#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ - r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)) -#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ - r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)) -#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_16(a) -#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ - r = pcre2_serialize_get_number_of_codes_16(a) -#define PCRE2_SET_CALLOUT(a,b,c) \ - pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); -#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b) -#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ - pcre2_set_compile_recursion_guard_16(G(a,16),b,c) -#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b) -#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_16(G(a,16),b) -#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b) -#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b) -#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b) -#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ - a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \ - (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l) -#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e) -#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e) -#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_16((PCRE2_UCHAR16 *)a) -#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e) -#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e) -#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ - a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d) -#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ - a = pcre2_substring_length_bynumber_16(G(b,16),c,d) -#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ - a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d) -#define PCRE2_SUBSTRING_LIST_FREE(a) \ - pcre2_substring_list_free_16((PCRE2_SPTR16 *)a) -#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ - a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); -#define PTR(x) (void *)G(x,16) -#define SETFLD(x,y,z) G(x,16)->y = z -#define SETFLDVEC(x,y,v,z) G(x,16)->y[v] = z -#define SETOP(x,y,z) G(x,16) z y -#define SETCASTPTR(x,y) G(x,16) = (uint16_t *)(y) -#define STRLEN(p) (int)strlen16((PCRE2_SPTR16)p) -#define SUB1(a,b) G(a,16)(G(b,16)) -#define SUB2(a,b,c) G(a,16)(G(b,16),G(c,16)) -#define TEST(x,r,y) (G(x,16) r (y)) -#define TESTFLD(x,f,r,y) (G(x,16)->f r (y)) - - -/* ----- Only 32-bit mode is supported ----- */ - -#elif defined SUPPORT_PCRE2_32 -#define CASTFLD(t,a,b) (t)(G(a,32)->b) -#define CASTVAR(t,x) (t)G(x,32) -#define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR32)(a))[b]) -#define DATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32)) -#define FLD(a,b) G(a,32)->b -#define PATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32)) -#define PCHARS(lv, p, offset, len, utf, f) \ - lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f) -#define PCHARSV(p, offset, len, utf, f) \ - (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f) -#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ - a = pcre2_callout_enumerate_32(compiled_code32, \ - (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) -#define PCRE2_COMPILE(a,b,c,d,e,f,g) \ - G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g) -#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ - a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j) -#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ - r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) -#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32)) -#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32)) -#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_32(G(a,32),b) -#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32)) -#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) -#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \ - a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d); -#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \ - pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c); -#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a); -#define PCRE2_MAKETABLES(a) a = pcre2_maketables_32(NULL) -#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ - a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) -#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,32) = pcre2_match_data_create_32(b,c) -#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \ - G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c) -#define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_32(G(a,32)) -#define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_32(G(b,32),c,d) -#define PCRE2_PRINTINT(a) pcre2_printint_32(compiled_code32,outfile,a) -#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \ - r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32)) -#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \ - r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32)) -#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_32(a) -#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \ - r = pcre2_serialize_get_number_of_codes_32(a) -#define PCRE2_SET_CALLOUT(a,b,c) \ - pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c); -#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b) -#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ - pcre2_set_compile_recursion_guard_32(G(a,32),b,c) -#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b) -#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_32(G(a,32),b) -#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b) -#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b) -#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b) -#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ - a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \ - (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l) -#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e) -#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e); -#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_32((PCRE2_UCHAR32 *)a) -#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \ - a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e) -#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \ - a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e) -#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \ - a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d) -#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \ - a = pcre2_substring_length_bynumber_32(G(b,32),c,d) -#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \ - a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d) -#define PCRE2_SUBSTRING_LIST_FREE(a) \ - pcre2_substring_list_free_32((PCRE2_SPTR32 *)a) -#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \ - a = pcre2_substring_number_from_name_32(G(b,32),G(c,32)); -#define PTR(x) (void *)G(x,32) -#define SETFLD(x,y,z) G(x,32)->y = z -#define SETFLDVEC(x,y,v,z) G(x,32)->y[v] = z -#define SETOP(x,y,z) G(x,32) z y -#define SETCASTPTR(x,y) G(x,32) = (uint32_t *)(y) -#define STRLEN(p) (int)strlen32((PCRE2_SPTR32)p) -#define SUB1(a,b) G(a,32)(G(b,32)) -#define SUB2(a,b,c) G(a,32)(G(b,32),G(c,32)) -#define TEST(x,r,y) (G(x,32) r (y)) -#define TESTFLD(x,f,r,y) (G(x,32)->f r (y)) - -#endif - -/* ----- End of mode-specific function call macros ----- */ - - - - -/************************************************* -* Alternate character tables * -*************************************************/ - -/* By default, the "tables" pointer in the compile context when calling -pcre2_compile() is not set (= NULL), thereby using the default tables of the -library. However, the tables modifier can be used to select alternate sets of -tables, for different kinds of testing. Note that the locale modifier also -adjusts the tables. */ - -/* This is the set of tables distributed as default with PCRE2. It recognizes -only ASCII characters. */ - -static const uint8_t tables1[] = { - -/* This table is a lower casing table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table is a case flipping table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table contains bit maps for various character classes. Each map is 32 -bytes long and the bits run from the least significant end of each byte. The -classes that have their own maps are: space, xdigit, digit, upper, lower, word, -graph, print, punct, and cntrl. Other classes are built from combinations. */ - - 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, - 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - -/* This table identifies various classes of character by individual bits: - 0x01 white space character - 0x02 letter - 0x04 decimal digit - 0x08 hexadecimal digit - 0x10 alphanumeric or '_' - 0x80 regular expression metacharacter or binary zero -*/ - - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ - 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ - 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ - 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ - 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ - 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ - -/* This is a set of tables that came originally from a Windows user. It seems -to be at least an approximation of ISO 8859. In particular, there are -characters greater than 128 that are marked as spaces, letters, etc. */ - -static const uint8_t tables2[] = { -0,1,2,3,4,5,6,7, -8,9,10,11,12,13,14,15, -16,17,18,19,20,21,22,23, -24,25,26,27,28,29,30,31, -32,33,34,35,36,37,38,39, -40,41,42,43,44,45,46,47, -48,49,50,51,52,53,54,55, -56,57,58,59,60,61,62,63, -64,97,98,99,100,101,102,103, -104,105,106,107,108,109,110,111, -112,113,114,115,116,117,118,119, -120,121,122,91,92,93,94,95, -96,97,98,99,100,101,102,103, -104,105,106,107,108,109,110,111, -112,113,114,115,116,117,118,119, -120,121,122,123,124,125,126,127, -128,129,130,131,132,133,134,135, -136,137,138,139,140,141,142,143, -144,145,146,147,148,149,150,151, -152,153,154,155,156,157,158,159, -160,161,162,163,164,165,166,167, -168,169,170,171,172,173,174,175, -176,177,178,179,180,181,182,183, -184,185,186,187,188,189,190,191, -224,225,226,227,228,229,230,231, -232,233,234,235,236,237,238,239, -240,241,242,243,244,245,246,215, -248,249,250,251,252,253,254,223, -224,225,226,227,228,229,230,231, -232,233,234,235,236,237,238,239, -240,241,242,243,244,245,246,247, -248,249,250,251,252,253,254,255, -0,1,2,3,4,5,6,7, -8,9,10,11,12,13,14,15, -16,17,18,19,20,21,22,23, -24,25,26,27,28,29,30,31, -32,33,34,35,36,37,38,39, -40,41,42,43,44,45,46,47, -48,49,50,51,52,53,54,55, -56,57,58,59,60,61,62,63, -64,97,98,99,100,101,102,103, -104,105,106,107,108,109,110,111, -112,113,114,115,116,117,118,119, -120,121,122,91,92,93,94,95, -96,65,66,67,68,69,70,71, -72,73,74,75,76,77,78,79, -80,81,82,83,84,85,86,87, -88,89,90,123,124,125,126,127, -128,129,130,131,132,133,134,135, -136,137,138,139,140,141,142,143, -144,145,146,147,148,149,150,151, -152,153,154,155,156,157,158,159, -160,161,162,163,164,165,166,167, -168,169,170,171,172,173,174,175, -176,177,178,179,180,181,182,183, -184,185,186,187,188,189,190,191, -224,225,226,227,228,229,230,231, -232,233,234,235,236,237,238,239, -240,241,242,243,244,245,246,215, -248,249,250,251,252,253,254,223, -192,193,194,195,196,197,198,199, -200,201,202,203,204,205,206,207, -208,209,210,211,212,213,214,247, -216,217,218,219,220,221,222,255, -0,62,0,0,1,0,0,0, -0,0,0,0,0,0,0,0, -32,0,0,0,1,0,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,255,3, -126,0,0,0,126,0,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,255,3, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,12,2, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0, -254,255,255,7,0,0,0,0, -0,0,0,0,0,0,0,0, -255,255,127,127,0,0,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,254,255,255,7, -0,0,0,0,0,4,32,4, -0,0,0,128,255,255,127,255, -0,0,0,0,0,0,255,3, -254,255,255,135,254,255,255,7, -0,0,0,0,0,4,44,6, -255,255,127,255,255,255,127,255, -0,0,0,0,254,255,255,255, -255,255,255,255,255,255,255,127, -0,0,0,0,254,255,255,255, -255,255,255,255,255,255,255,255, -0,2,0,0,255,255,255,255, -255,255,255,255,255,255,255,127, -0,0,0,0,255,255,255,255, -255,255,255,255,255,255,255,255, -0,0,0,0,254,255,0,252, -1,0,0,248,1,0,0,120, -0,0,0,0,254,255,255,255, -0,0,128,0,0,0,128,0, -255,255,255,255,0,0,0,0, -0,0,0,0,0,0,0,128, -255,255,255,255,0,0,0,0, -0,0,0,0,0,0,0,0, -128,0,0,0,0,0,0,0, -0,1,1,0,1,1,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0, -1,0,0,0,128,0,0,0, -128,128,128,128,0,0,128,0, -28,28,28,28,28,28,28,28, -28,28,0,0,0,0,0,128, -0,26,26,26,26,26,26,18, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,18, -18,18,18,128,128,0,128,16, -0,26,26,26,26,26,26,18, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,18, -18,18,18,128,128,0,0,0, -0,0,0,0,0,1,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0, -1,0,0,0,0,0,0,0, -0,0,18,0,0,0,0,0, -0,0,20,20,0,18,0,0, -0,20,18,0,0,0,0,0, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,0, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,18, -18,18,18,18,18,18,18,0, -18,18,18,18,18,18,18,18 -}; - - - -/************************************************* -* Local memory functions * -*************************************************/ - -/* Alternative memory functions, to test functionality. */ - -static void *my_malloc(size_t size, void *data) -{ -void *block = malloc(size); -(void)data; -if (show_memory) - fprintf(outfile, "malloc %3d %p\n", (int)size, block); -return block; -} - -static void my_free(void *block, void *data) -{ -(void)data; -if (show_memory) - fprintf(outfile, "free %p\n", block); -free(block); -} - -/* For recursion malloc/free, to test stacking calls */ - -#ifdef HEAP_MATCH_RECURSE -static void *my_stack_malloc(size_t size, void *data) -{ -void *block = malloc(size); -(void)data; -if (show_memory) - fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block); -return block; -} - -static void my_stack_free(void *block, void *data) -{ -(void)data; -if (show_memory) - fprintf(outfile, "stack_free %p\n", block); -free(block); -} -#endif /* HEAP_MATCH_RECURSE */ - - -/************************************************* -* Callback function for stack guard * -*************************************************/ - -/* This is set up to be called from pcre2_compile() when the stackguard=n -modifier sets a value greater than zero. The test we do is whether the -parenthesis nesting depth is greater than the value set by the modifier. - -Argument: the current parenthesis nesting depth -Returns: non-zero to kill the compilation -*/ - -static int -stack_guard(uint32_t depth, void *user_data) -{ -(void)user_data; -return depth > pat_patctl.stackguard_test; -} - - -/************************************************* -* JIT memory callback * -*************************************************/ - -static PCRE2_JIT_STACK* -jit_callback(void *arg) -{ -jit_was_used = TRUE; -return (PCRE2_JIT_STACK *)arg; -} - - -/************************************************* -* Convert UTF-8 character to code point * -*************************************************/ - -/* This function reads one or more bytes that represent a UTF-8 character, -and returns the codepoint of that character. Note that the function supports -the original UTF-8 definition of RFC 2279, allowing for values in the range 0 -to 0x7fffffff, up to 6 bytes long. This makes it possible to generate -codepoints greater than 0x10ffff which are useful for testing PCRE2's error -checking, and also for generating 32-bit non-UTF data values above the UTF -limit. - -Argument: - utf8bytes a pointer to the byte vector - vptr a pointer to an int to receive the value - -Returns: > 0 => the number of bytes consumed - -6 to 0 => malformed UTF-8 character at offset = (-return) -*/ - -static int -utf82ord(PCRE2_SPTR8 utf8bytes, uint32_t *vptr) -{ -uint32_t c = *utf8bytes++; -uint32_t d = c; -int i, j, s; - -for (i = -1; i < 6; i++) /* i is number of additional bytes */ - { - if ((d & 0x80) == 0) break; - d <<= 1; - } - -if (i == -1) { *vptr = c; return 1; } /* ascii character */ -if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ - -/* i now has a value in the range 1-5 */ - -s = 6*i; -d = (c & utf8_table3[i]) << s; - -for (j = 0; j < i; j++) - { - c = *utf8bytes++; - if ((c & 0xc0) != 0x80) return -(j+1); - s -= 6; - d |= (c & 0x3f) << s; - } - -/* Check that encoding was the correct unique one */ - -for (j = 0; j < utf8_table1_size; j++) - if (d <= (uint32_t)utf8_table1[j]) break; -if (j != i) return -(i+1); - -/* Valid value */ - -*vptr = d; -return i+1; -} - - - -/************************************************* -* Print one character * -*************************************************/ - -/* Print a single character either literally, or as a hex escape, and count how -many printed characters are used. - -Arguments: - c the character - utf TRUE in UTF mode - f the FILE to print to, or NULL just to count characters - -Returns: number of characters written -*/ - -static int -pchar(uint32_t c, BOOL utf, FILE *f) -{ -int n = 0; -if (PRINTOK(c)) - { - if (f != NULL) fprintf(f, "%c", c); - return 1; - } - -if (c < 0x100) - { - if (utf) - { - if (f != NULL) fprintf(f, "\\x{%02x}", c); - return 6; - } - else - { - if (f != NULL) fprintf(f, "\\x%02x", c); - return 4; - } - } - -if (f != NULL) n = fprintf(f, "\\x{%02x}", c); -return n >= 0 ? n : 0; -} - - - -#ifdef SUPPORT_PCRE2_16 -/************************************************* -* Find length of 0-terminated 16-bit string * -*************************************************/ - -static size_t strlen16(PCRE2_SPTR16 p) -{ -PCRE2_SPTR16 pp = p; -while (*pp != 0) pp++; -return (int)(pp - p); -} -#endif /* SUPPORT_PCRE2_16 */ - - - -#ifdef SUPPORT_PCRE2_32 -/************************************************* -* Find length of 0-terminated 32-bit string * -*************************************************/ - -static size_t strlen32(PCRE2_SPTR32 p) -{ -PCRE2_SPTR32 pp = p; -while (*pp != 0) pp++; -return (int)(pp - p); -} -#endif /* SUPPORT_PCRE2_32 */ - - -#ifdef SUPPORT_PCRE2_8 -/************************************************* -* Print 8-bit character string * -*************************************************/ - -/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. -For printing *MARK strings, a negative length is given. If handed a NULL file, -just counts chars without printing. */ - -static int pchars8(PCRE2_SPTR8 p, int length, BOOL utf, FILE *f) -{ -uint32_t c = 0; -int yield = 0; -if (length < 0) length = p[-1]; -while (length-- > 0) - { - if (utf) - { - int rc = utf82ord(p, &c); - if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ - { - length -= rc - 1; - p += rc; - yield += pchar(c, utf, f); - continue; - } - } - c = *p++; - yield += pchar(c, utf, f); - } -return yield; -} -#endif - - -#ifdef SUPPORT_PCRE2_16 -/************************************************* -* Print 16-bit character string * -*************************************************/ - -/* Must handle UTF-16 strings in utf mode. Yields number of characters printed. -For printing *MARK strings, a negative length is given. If handed a NULL file, -just counts chars without printing. */ - -static int pchars16(PCRE2_SPTR16 p, int length, BOOL utf, FILE *f) -{ -int yield = 0; -if (length < 0) length = p[-1]; -while (length-- > 0) - { - uint32_t c = *p++ & 0xffff; - if (utf && c >= 0xD800 && c < 0xDC00 && length > 0) - { - int d = *p & 0xffff; - if (d >= 0xDC00 && d <= 0xDFFF) - { - c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; - length--; - p++; - } - } - yield += pchar(c, utf, f); - } -return yield; -} -#endif /* SUPPORT_PCRE2_16 */ - - - -#ifdef SUPPORT_PCRE2_32 -/************************************************* -* Print 32-bit character string * -*************************************************/ - -/* Must handle UTF-32 strings in utf mode. Yields number of characters printed. -For printing *MARK strings, a negative length is given.If handed a NULL file, -just counts chars without printing. */ - -static int pchars32(PCRE2_SPTR32 p, int length, BOOL utf, FILE *f) -{ -int yield = 0; -(void)(utf); /* Avoid compiler warning */ -if (length < 0) length = p[-1]; -while (length-- > 0) - { - uint32_t c = *p++; - yield += pchar(c, utf, f); - } -return yield; -} -#endif /* SUPPORT_PCRE2_32 */ - - - - -#ifdef SUPPORT_PCRE2_8 -/************************************************* -* Convert character value to UTF-8 * -*************************************************/ - -/* This function takes an integer value in the range 0 - 0x7fffffff -and encodes it as a UTF-8 character in 0 to 6 bytes. - -Arguments: - cvalue the character value - utf8bytes pointer to buffer for result - at least 6 bytes long - -Returns: number of characters placed in the buffer -*/ - -static int -ord2utf8(uint32_t cvalue, uint8_t *utf8bytes) -{ -register int i, j; -if (cvalue > 0x7fffffffu) - return -1; -for (i = 0; i < utf8_table1_size; i++) - if (cvalue <= (uint32_t)utf8_table1[i]) break; -utf8bytes += i; -for (j = i; j > 0; j--) - { - *utf8bytes-- = 0x80 | (cvalue & 0x3f); - cvalue >>= 6; - } -*utf8bytes = utf8_table2[i] | cvalue; -return i + 1; -} -#endif /* SUPPORT_PCRE2_8 */ - - - -#ifdef SUPPORT_PCRE2_16 -/************************************************* -* Convert pattern to 16-bit * -*************************************************/ - -/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If -all the input bytes are ASCII, the space needed for a 16-bit string is exactly -double the 8-bit size. Otherwise, the size needed for a 16-bit string is no -more than double, because up to 0xffff uses no more than 3 bytes in UTF-8 but -possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in -UTF-16. The result is always left in pbuffer16. Impose a minimum size to save -repeated re-sizing. - -Note that this function does not object to surrogate values. This is -deliberate; it makes it possible to construct UTF-16 strings that are invalid, -for the purpose of testing that they are correctly faulted. - -Arguments: - p points to a byte string - utf non-zero if converting to UTF-16 - lenptr points to number of bytes in the string (excluding trailing zero) - -Returns: 0 on success, with the length updated to the number of 16-bit - data items used (excluding the trailing zero) - OR -1 if a UTF-8 string is malformed - OR -2 if a value > 0x10ffff is encountered in UTF mode - OR -3 if a value > 0xffff is encountered when not in UTF mode -*/ - -static PCRE2_SIZE -to16(uint8_t *p, int utf, PCRE2_SIZE *lenptr) -{ -uint16_t *pp; -PCRE2_SIZE len = *lenptr; - -if (pbuffer16_size < 2*len + 2) - { - if (pbuffer16 != NULL) free(pbuffer16); - pbuffer16_size = 2*len + 2; - if (pbuffer16_size < 256) pbuffer16_size = 256; - pbuffer16 = (uint16_t *)malloc(pbuffer16_size); - if (pbuffer16 == NULL) - { - fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer16\n", - (unsigned long int)pbuffer16_size); - exit(1); - } - } - -pp = pbuffer16; -if (!utf) - { - for (; len > 0; len--) *pp++ = *p++; - } -else while (len > 0) - { - uint32_t c; - int chlen = utf82ord(p, &c); - if (chlen <= 0) return -1; - if (c > 0x10ffff) return -2; - p += chlen; - len -= chlen; - if (c < 0x10000) *pp++ = c; else - { - if (!utf) return -3; - c -= 0x10000; - *pp++ = 0xD800 | (c >> 10); - *pp++ = 0xDC00 | (c & 0x3ff); - } - } - -*pp = 0; -*lenptr = pp - pbuffer16; -return 0; -} -#endif - - - -#ifdef SUPPORT_PCRE2_32 -/************************************************* -* Convert pattern to 32-bit * -*************************************************/ - -/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If -all the input bytes are ASCII, the space needed for a 32-bit string is exactly -four times the 8-bit size. Otherwise, the size needed for a 32-bit string is no -more than four times, because the number of characters must be less than the -number of bytes. The result is always left in pbuffer32. Impose a minimum size -to save repeated re-sizing. - -Note that this function does not object to surrogate values. This is -deliberate; it makes it possible to construct UTF-32 strings that are invalid, -for the purpose of testing that they are correctly faulted. - -Arguments: - p points to a byte string - utf true if UTF-8 (to be converted to UTF-32) - lenptr points to number of bytes in the string (excluding trailing zero) - -Returns: 0 on success, with the length updated to the number of 32-bit - data items used (excluding the trailing zero) - OR -1 if a UTF-8 string is malformed - OR -2 if a value > 0x10ffff is encountered in UTF mode -*/ - -static PCRE2_SIZE -to32(uint8_t *p, int utf, PCRE2_SIZE *lenptr) -{ -uint32_t *pp; -PCRE2_SIZE len = *lenptr; - -if (pbuffer32_size < 4*len + 4) - { - if (pbuffer32 != NULL) free(pbuffer32); - pbuffer32_size = 4*len + 4; - if (pbuffer32_size < 256) pbuffer32_size = 256; - pbuffer32 = (uint32_t *)malloc(pbuffer32_size); - if (pbuffer32 == NULL) - { - fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer32\n", - (unsigned long int)pbuffer32_size); - exit(1); - } - } - -pp = pbuffer32; -if (!utf) - { - for (; len > 0; len--) *pp++ = *p++; - } -else while (len > 0) - { - uint32_t c; - int chlen = utf82ord(p, &c); - if (chlen <= 0) return -1; - if (utf && c > 0x10ffff) return -2; - p += chlen; - len -= chlen; - *pp++ = c; - } - -*pp = 0; -*lenptr = pp - pbuffer32; -return 0; -} -#endif /* SUPPORT_PCRE2_32 */ - - - -/************************************************* -* Move back by so many characters * -*************************************************/ - -/* Given a code unit offset in a subject string, move backwards by a number of -characters, and return the resulting offset. - -Arguments: - subject pointer to the string - offset start offset - count count to move back by - utf TRUE if in UTF mode - -Returns: a possibly changed offset -*/ - -static PCRE2_SIZE -backchars(uint8_t *subject, PCRE2_SIZE offset, uint32_t count, BOOL utf) -{ -if (!utf || test_mode == PCRE32_MODE) - return (count >= offset)? 0 : (offset - count); - -else if (test_mode == PCRE8_MODE) - { - PCRE2_SPTR8 pp = (PCRE2_SPTR8)subject + offset; - for (; count > 0 && pp > (PCRE2_SPTR8)subject; count--) - { - pp--; - while ((*pp & 0xc0) == 0x80) pp--; - } - return pp - (PCRE2_SPTR8)subject; - } - -else /* 16-bit mode */ - { - PCRE2_SPTR16 pp = (PCRE2_SPTR16)subject + offset; - for (; count > 0 && pp > (PCRE2_SPTR16)subject; count--) - { - pp--; - if ((*pp & 0xfc00) == 0xdc00) pp--; - } - return pp - (PCRE2_SPTR16)subject; - } -} - - - -/************************************************* -* Expand input buffers * -*************************************************/ - -/* This function doubles the size of the input buffer and the buffer for -keeping an 8-bit copy of patterns (pbuffer8), and copies the current buffers to -the new ones. - -Arguments: none -Returns: nothing (aborts if malloc() fails) -*/ - -static void -expand_input_buffers(void) -{ -int new_pbuffer8_size = 2*pbuffer8_size; -uint8_t *new_buffer = (uint8_t *)malloc(new_pbuffer8_size); -uint8_t *new_pbuffer8 = (uint8_t *)malloc(new_pbuffer8_size); - -if (new_buffer == NULL || new_pbuffer8 == NULL) - { - fprintf(stderr, "pcre2test: malloc(%d) failed\n", new_pbuffer8_size); - exit(1); - } - -memcpy(new_buffer, buffer, pbuffer8_size); -memcpy(new_pbuffer8, pbuffer8, pbuffer8_size); - -pbuffer8_size = new_pbuffer8_size; - -free(buffer); -free(pbuffer8); - -buffer = new_buffer; -pbuffer8 = new_pbuffer8; -} - - - -/************************************************* -* Read or extend an input line * -*************************************************/ - -/* Input lines are read into buffer, but both patterns and data lines can be -continued over multiple input lines. In addition, if the buffer fills up, we -want to automatically expand it so as to be able to handle extremely large -lines that are needed for certain stress tests. When the input buffer is -expanded, the other two buffers must also be expanded likewise, and the -contents of pbuffer, which are a copy of the input for callouts, must be -preserved (for when expansion happens for a data line). This is not the most -optimal way of handling this, but hey, this is just a test program! - -Arguments: - f the file to read - start where in buffer to start (this *must* be within buffer) - prompt for stdin or readline() - -Returns: pointer to the start of new data - could be a copy of start, or could be moved - NULL if no data read and EOF reached -*/ - -static uint8_t * -extend_inputline(FILE *f, uint8_t *start, const char *prompt) -{ -uint8_t *here = start; - -for (;;) - { - size_t rlen = (size_t)(pbuffer8_size - (here - buffer)); - - if (rlen > 1000) - { - int dlen; - - /* If libreadline or libedit support is required, use readline() to read a - line if the input is a terminal. Note that readline() removes the trailing - newline, so we must put it back again, to be compatible with fgets(). */ - -#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) - if (INTERACTIVE(f)) - { - size_t len; - char *s = readline(prompt); - if (s == NULL) return (here == start)? NULL : start; - len = strlen(s); - if (len > 0) add_history(s); - if (len > rlen - 1) len = rlen - 1; - memcpy(here, s, len); - here[len] = '\n'; - here[len+1] = 0; - free(s); - } - else -#endif - - /* Read the next line by normal means, prompting if the file is a tty. */ - - { - if (INTERACTIVE(f)) printf("%s", prompt); - if (fgets((char *)here, rlen, f) == NULL) - return (here == start)? NULL : start; - } - - dlen = (int)strlen((char *)here); - if (dlen > 0 && here[dlen - 1] == '\n') return start; - here += dlen; - } - - else - { - size_t start_offset = start - buffer; - size_t here_offset = here - buffer; - expand_input_buffers(); - start = buffer + start_offset; - here = buffer + here_offset; - } - } - -/* Control never gets here */ -} - - - -/************************************************* -* Case-independent strncmp() function * -*************************************************/ - -/* -Arguments: - s first string - t second string - n number of characters to compare - -Returns: < 0, = 0, or > 0, according to the comparison -*/ - -static int -strncmpic(const uint8_t *s, const uint8_t *t, int n) -{ -while (n--) - { - int c = tolower(*s++) - tolower(*t++); - if (c) return c; - } -return 0; -} - - - -/************************************************* -* Scan the main modifier list * -*************************************************/ - -/* This function searches the modifier list for a long modifier name. - -Argument: - p start of the name - lenp length of the name - -Returns: an index in the modifier list, or -1 on failure -*/ - -static int -scan_modifiers(const uint8_t *p, unsigned int len) -{ -int bot = 0; -int top = MODLISTCOUNT; - -while (top > bot) - { - int mid = (bot + top)/2; - unsigned int mlen = strlen(modlist[mid].name); - int c = strncmp((char *)p, modlist[mid].name, (len < mlen)? len : mlen); - if (c == 0) - { - if (len == mlen) return mid; - c = (int)len - (int)mlen; - } - if (c > 0) bot = mid + 1; else top = mid; - } - -return -1; - -} - - - -/************************************************* -* Check a modifer and find its field * -*************************************************/ - -/* This function is called when a modifier has been identified. We check that -it is allowed here and find the field that is to be changed. - -Arguments: - m the modifier list entry - ctx CTX_PAT => pattern context - CTX_POPPAT => pattern context for popped pattern - CTX_DEFPAT => default pattern context - CTX_DAT => data context - CTX_DEFDAT => default data context - pctl point to pattern control block - dctl point to data control block - c a single character or 0 - -Returns: a field pointer or NULL -*/ - -static void * -check_modifier(modstruct *m, int ctx, patctl *pctl, datctl *dctl, uint32_t c) -{ -void *field = NULL; -PCRE2_SIZE offset = m->offset; - -if (restrict_for_perl_test) switch(m->which) - { - case MOD_PNDP: - case MOD_PATP: - case MOD_PDP: - break; - - default: - fprintf(outfile, "** '%s' is not allowed in a Perl-compatible test\n", - m->name); - return NULL; - } - -switch (m->which) - { - case MOD_CTC: /* Compile context modifier */ - if (ctx == CTX_DEFPAT) field = PTR(default_pat_context); - else if (ctx == CTX_PAT) field = PTR(pat_context); - break; - - case MOD_CTM: /* Match context modifier */ - if (ctx == CTX_DEFDAT) field = PTR(default_dat_context); - else if (ctx == CTX_DAT) field = PTR(dat_context); - break; - - case MOD_DAT: /* Data line modifier */ - if (dctl != NULL) field = dctl; - break; - - case MOD_PAT: /* Pattern modifier */ - case MOD_PATP: /* Allowed for Perl test */ - if (pctl != NULL) field = pctl; - break; - - case MOD_PD: /* Pattern or data line modifier */ - case MOD_PDP: /* Ditto, allowed for Perl test */ - case MOD_PND: /* Ditto, but not default pattern */ - case MOD_PNDP: /* Ditto, allowed for Perl test */ - if (dctl != NULL) field = dctl; - else if (pctl != NULL && (m->which == MOD_PD || ctx != CTX_DEFPAT)) - field = pctl; - break; - } - -if (field == NULL) - { - if (c == 0) - fprintf(outfile, "** '%s' is not valid here\n", m->name); - else - fprintf(outfile, "** /%c is not valid here\n", c); - return NULL; - } - -return (char *)field + offset; -} - - - -/************************************************* -* Decode a modifier list * -*************************************************/ - -/* A pointer to a control block is NULL when called in cases when that block is -not relevant. They are never all relevant in one call. At least one of patctl -and datctl is NULL. The second argument specifies which context to use for -modifiers that apply to contexts. - -Arguments: - p point to modifier string - ctx CTX_PAT => pattern context - CTX_POPPAT => pattern context for popped pattern - CTX_DEFPAT => default pattern context - CTX_DAT => data context - CTX_DEFDAT => default data context - pctl point to pattern control block - dctl point to data control block - -Returns: TRUE if successful decode, FALSE otherwise -*/ - -static BOOL -decode_modifiers(uint8_t *p, int ctx, patctl *pctl, datctl *dctl) -{ -uint8_t *ep, *pp; -long li; -unsigned long uli; -BOOL first = TRUE; - -for (;;) - { - void *field; - modstruct *m; - BOOL off = FALSE; - unsigned int i, len; - int index; - char *endptr; - - /* Skip white space and commas. */ - - while (isspace(*p) || *p == ',') p++; - if (*p == 0) break; - - /* Find the end of the item; lose trailing whitespace at end of line. */ - - for (ep = p; *ep != 0 && *ep != ','; ep++); - if (*ep == 0) - { - while (ep > p && isspace(ep[-1])) ep--; - *ep = 0; - } - - /* Remember if the first character is '-'. */ - - if (*p == '-') - { - off = TRUE; - p++; - } - - /* Find the length of a full-length modifier name, and scan for it. */ - - pp = p; - while (pp < ep && *pp != '=') pp++; - index = scan_modifiers(p, pp - p); - - /* If the first modifier is unrecognized, try to interpret it as a sequence - of single-character abbreviated modifiers. None of these modifiers have any - associated data. They just set options or control bits. */ - - if (index < 0) - { - uint32_t cc; - uint8_t *mp = p; - - if (!first) - { - fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p); - if (ep - p == 1) - fprintf(outfile, "** Single-character modifiers must come first\n"); - return FALSE; - } - - for (cc = *p; cc != ',' && cc != '\n' && cc != 0; cc = *(++p)) - { - for (i = 0; i < C1MODLISTCOUNT; i++) - if (cc == c1modlist[i].onechar) break; - - if (i >= C1MODLISTCOUNT) - { - fprintf(outfile, "** Unrecognized modifier '%c' in '%.*s'\n", - *p, (int)(ep-mp), mp); - return FALSE; - } - - if (c1modlist[i].index >= 0) - { - index = c1modlist[i].index; - } - - else - { - index = scan_modifiers((uint8_t *)(c1modlist[i].fullname), - strlen(c1modlist[i].fullname)); - if (index < 0) - { - fprintf(outfile, "** Internal error: single-character equivalent " - "modifier '%s' not found\n", c1modlist[i].fullname); - return FALSE; - } - c1modlist[i].index = index; /* Cache for next time */ - } - - field = check_modifier(modlist + index, ctx, pctl, dctl, *p); - if (field == NULL) return FALSE; - *((uint32_t *)field) |= modlist[index].value; - } - - continue; /* With tne next (fullname) modifier */ - } - - /* We have a match on a full-name modifier. Check for the existence of data - when needed. */ - - m = modlist + index; /* Save typing */ - if (m->type != MOD_CTL && m->type != MOD_OPT && - (m->type != MOD_IND || *pp == '=')) - { - if (*pp++ != '=') - { - fprintf(outfile, "** '=' expected after '%s'\n", m->name); - return FALSE; - } - if (off) - { - fprintf(outfile, "** '-' is not valid for '%s'\n", m->name); - return FALSE; - } - } - - /* These on/off types have no data. */ - - else if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) - { - fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p); - return FALSE; - } - - /* Set the data length for those types that have data. Then find the field - that is to be set. If check_modifier() returns NULL, it has already output an - error message. */ - - len = ep - pp; - field = check_modifier(m, ctx, pctl, dctl, 0); - if (field == NULL) return FALSE; - - /* Process according to data type. */ - - switch (m->type) - { - case MOD_CTL: - case MOD_OPT: - if (off) *((uint32_t *)field) &= ~m->value; - else *((uint32_t *)field) |= m->value; - break; - - case MOD_BSR: - if (len == 7 && strncmpic(pp, (const uint8_t *)"default", 7) == 0) - { -#ifdef BSR_ANYCRLF - *((uint16_t *)field) = PCRE2_BSR_ANYCRLF; -#else - *((uint16_t *)field) = PCRE2_BSR_UNICODE; -#endif - if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_BSR_SET; - else dctl->control &= ~CTL_BSR_SET; - } - else - { - if (len == 7 && strncmpic(pp, (const uint8_t *)"anycrlf", 7) == 0) - *((uint16_t *)field) = PCRE2_BSR_ANYCRLF; - else if (len == 7 && strncmpic(pp, (const uint8_t *)"unicode", 7) == 0) - *((uint16_t *)field) = PCRE2_BSR_UNICODE; - else goto INVALID_VALUE; - if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_BSR_SET; - else dctl->control |= CTL_BSR_SET; - } - pp = ep; - break; - - case MOD_IN2: /* One or two unsigned integers */ - if (!isdigit(*pp)) goto INVALID_VALUE; - uli = strtoul((const char *)pp, &endptr, 10); - if (U32OVERFLOW(uli)) goto INVALID_VALUE; - ((uint32_t *)field)[0] = (uint32_t)uli; - if (*endptr == ':') - { - uli = strtoul((const char *)endptr+1, &endptr, 10); - if (U32OVERFLOW(uli)) goto INVALID_VALUE; - ((uint32_t *)field)[1] = (uint32_t)uli; - } - else ((uint32_t *)field)[1] = 0; - pp = (uint8_t *)endptr; - break; - - /* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or - less than ULONG_MAX. So first test for overflowing the long int, and then - test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */ - - case MOD_SIZ: /* PCRE2_SIZE value */ - if (!isdigit(*pp)) goto INVALID_VALUE; - uli = strtoul((const char *)pp, &endptr, 10); - if (uli == ULONG_MAX) goto INVALID_VALUE; -#if ULONG_MAX > PCRE2_SIZE_MAX - if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE; -#endif - *((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli; - pp = (uint8_t *)endptr; - break; - - case MOD_IND: /* Unsigned integer with default */ - if (len == 0) - { - *((uint32_t *)field) = (uint32_t)(m->value); - break; - } - /* Fall through */ - - case MOD_INT: /* Unsigned integer */ - if (!isdigit(*pp)) goto INVALID_VALUE; - uli = strtoul((const char *)pp, &endptr, 10); - if (U32OVERFLOW(uli)) goto INVALID_VALUE; - *((uint32_t *)field) = (uint32_t)uli; - pp = (uint8_t *)endptr; - break; - - case MOD_INS: /* Signed integer */ - if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE; - li = strtol((const char *)pp, &endptr, 10); - if (S32OVERFLOW(li)) goto INVALID_VALUE; - *((int32_t *)field) = (int32_t)li; - pp = (uint8_t *)endptr; - break; - - case MOD_NL: - for (i = 0; i < sizeof(newlines)/sizeof(char *); i++) - if (len == strlen(newlines[i]) && - strncmpic(pp, (const uint8_t *)newlines[i], len) == 0) break; - if (i >= sizeof(newlines)/sizeof(char *)) goto INVALID_VALUE; - if (i == 0) - { - *((uint16_t *)field) = NEWLINE_DEFAULT; - if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_NL_SET; - else dctl->control &= ~CTL_NL_SET; - } - else - { - *((uint16_t *)field) = i; - if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_NL_SET; - else dctl->control |= CTL_NL_SET; - } - pp = ep; - break; - - case MOD_NN: /* Name or (signed) number; may be several */ - if (isdigit(*pp) || *pp == '-') - { - int ct = MAXCPYGET - 1; - int32_t value; - li = strtol((const char *)pp, &endptr, 10); - if (S32OVERFLOW(li)) goto INVALID_VALUE; - value = (int32_t)li; - field = (char *)field - m->offset + m->value; /* Adjust field ptr */ - if (value >= 0) /* Add new number */ - { - while (*((int32_t *)field) >= 0 && ct-- > 0) /* Skip previous */ - field = (char *)field + sizeof(int32_t); - if (ct <= 0) - { - fprintf(outfile, "** Too many numeric '%s' modifiers\n", m->name); - return FALSE; - } - } - *((int32_t *)field) = value; - if (ct > 0) ((int32_t *)field)[1] = -1; - pp = (uint8_t *)endptr; - } - - /* Multiple strings are put end to end. */ - - else - { - char *nn = (char *)field; - if (len > 0) /* Add new name */ - { - while (*nn != 0) nn += strlen(nn) + 1; - if (nn + len + 1 - (char *)field > LENCPYGET) - { - fprintf(outfile, "** Too many named '%s' modifiers\n", m->name); - return FALSE; - } - memcpy(nn, pp, len); - } - nn[len] = 0 ; - nn[len+1] = 0; - pp = ep; - } - break; - - case MOD_STR: - if (len + 1 > m->value) - { - fprintf(outfile, "** Overlong value for '%s' (max %d code units)\n", - m->name, m->value - 1); - return FALSE; - } - memcpy(field, pp, len); - ((uint8_t *)field)[len] = 0; - pp = ep; - break; - } - - if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) - { - fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name); - return FALSE; - } - - p = pp; - first = FALSE; - - if (ctx == CTX_POPPAT && - (pctl->options != 0 || - pctl->tables_id != 0 || - pctl->locale[0] != 0 || - (pctl->control & NOTPOP_CONTROLS) != 0)) - { - fprintf(outfile, "** '%s' is not valid here\n", m->name); - return FALSE; - } - } - -return TRUE; - -INVALID_VALUE: -fprintf(outfile, "** Invalid value in '%.*s'\n", (int)(ep-p), p); -return FALSE; -} - - -/************************************************* -* Get info from a pattern * -*************************************************/ - -/* A wrapped call to pcre2_pattern_info(), applied to the current compiled -pattern. - -Arguments: - what code for the required information - where where to put the answer - unsetok PCRE2_ERROR_UNSET is an "expected" result - -Returns: the return from pcre2_pattern_info() -*/ - -static int -pattern_info(int what, void *where, BOOL unsetok) -{ -int rc; -PCRE2_PATTERN_INFO(rc, compiled_code, what, where); -if (rc >= 0) return 0; -if (rc != PCRE2_ERROR_UNSET || !unsetok) - { - fprintf(outfile, "Error %d from pcre2_pattern_info_%d(%d)\n", rc, test_mode, - what); - if (rc == PCRE2_ERROR_BADMODE) - fprintf(outfile, "Running in %d-bit mode but pattern was compiled in " - "%d-bit mode\n", test_mode, - 8 * (FLD(compiled_code, flags) & PCRE2_MODE_MASK)); - } -return rc; -} - - - -#ifdef SUPPORT_PCRE2_8 -/************************************************* -* Show something in a list * -*************************************************/ - -/* This function just helps to keep the code that uses it tidier. It's used for -various lists of things where there needs to be introductory text before the -first item. As these calls are all in the POSIX-support code, they happen only -when 8-bit mode is supported. */ - -static void -prmsg(const char **msg, const char *s) -{ -fprintf(outfile, "%s %s", *msg, s); -*msg = ""; -} -#endif /* SUPPORT_PCRE2_8 */ - - - -/************************************************* -* Show control bits * -*************************************************/ - -/* Called for mutually exclusive controls and for unsupported POSIX controls. -Because the bits are unique, this can be used for both pattern and data control -words. - -Arguments: - controls control bits - controls2 more control bits - before text to print before - -Returns: nothing -*/ - -static void -show_controls(uint32_t controls, uint32_t controls2, const char *before) -{ -fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - before, - ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "", - ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "", - ((controls & CTL_ALLCAPTURES) != 0)? " allcaptures" : "", - ((controls & CTL_ALLUSEDTEXT) != 0)? " allusedtext" : "", - ((controls & CTL_ALTGLOBAL) != 0)? " altglobal" : "", - ((controls & CTL_BINCODE) != 0)? " bincode" : "", - ((controls & CTL_BSR_SET) != 0)? " bsr" : "", - ((controls & CTL_CALLOUT_CAPTURE) != 0)? " callout_capture" : "", - ((controls & CTL_CALLOUT_INFO) != 0)? " callout_info" : "", - ((controls & CTL_CALLOUT_NONE) != 0)? " callout_none" : "", - ((controls & CTL_DFA) != 0)? " dfa" : "", - ((controls & CTL_EXPAND) != 0)? " expand" : "", - ((controls & CTL_FINDLIMITS) != 0)? " find_limits" : "", - ((controls & CTL_FULLBINCODE) != 0)? " fullbincode" : "", - ((controls & CTL_GETALL) != 0)? " getall" : "", - ((controls & CTL_GLOBAL) != 0)? " global" : "", - ((controls & CTL_HEXPAT) != 0)? " hex" : "", - ((controls & CTL_INFO) != 0)? " info" : "", - ((controls & CTL_JITFAST) != 0)? " jitfast" : "", - ((controls & CTL_JITVERIFY) != 0)? " jitverify" : "", - ((controls & CTL_MARK) != 0)? " mark" : "", - ((controls & CTL_MEMORY) != 0)? " memory" : "", - ((controls & CTL_NL_SET) != 0)? " newline" : "", - ((controls & CTL_NULLCONTEXT) != 0)? " null_context" : "", - ((controls & CTL_POSIX) != 0)? " posix" : "", - ((controls & CTL_PUSH) != 0)? " push" : "", - ((controls & CTL_STARTCHAR) != 0)? " startchar" : "", - ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "", - ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "", - ((controls2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) != 0)? " substitute_unknown_unset" : "", - ((controls2 & CTL2_SUBSTITUTE_UNSET_EMPTY) != 0)? " substitute_unset_empty" : "", - ((controls & CTL_ZERO_TERMINATE) != 0)? " zero_terminate" : ""); -} - - - -/************************************************* -* Show compile options * -*************************************************/ - -/* Called from show_pattern_info() and for unsupported POSIX options. - -Arguments: - options an options word - before text to print before - after text to print after - -Returns: nothing -*/ - -static void -show_compile_options(uint32_t options, const char *before, const char *after) -{ -if (options == 0) fprintf(outfile, "%s %s", before, after); -else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - before, - ((options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "", - ((options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "", - ((options & PCRE2_ALT_VERBNAMES) != 0)? " alt_verbnames" : "", - ((options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? " allow_empty_class" : "", - ((options & PCRE2_ANCHORED) != 0)? " anchored" : "", - ((options & PCRE2_AUTO_CALLOUT) != 0)? " auto_callout" : "", - ((options & PCRE2_CASELESS) != 0)? " caseless" : "", - ((options & PCRE2_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", - ((options & PCRE2_DOTALL) != 0)? " dotall" : "", - ((options & PCRE2_DUPNAMES) != 0)? " dupnames" : "", - ((options & PCRE2_EXTENDED) != 0)? " extended" : "", - ((options & PCRE2_FIRSTLINE) != 0)? " firstline" : "", - ((options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "", - ((options & PCRE2_MULTILINE) != 0)? " multiline" : "", - ((options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "", - ((options & PCRE2_NEVER_UCP) != 0)? " never_ucp" : "", - ((options & PCRE2_NEVER_UTF) != 0)? " never_utf" : "", - ((options & PCRE2_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "", - ((options & PCRE2_NO_AUTO_POSSESS) != 0)? " no_auto_possess" : "", - ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? " no_dotstar_anchor" : "", - ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "", - ((options & PCRE2_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "", - ((options & PCRE2_UCP) != 0)? " ucp" : "", - ((options & PCRE2_UNGREEDY) != 0)? " ungreedy" : "", - ((options & PCRE2_USE_OFFSET_LIMIT) != 0)? " use_offset_limit" : "", - ((options & PCRE2_UTF) != 0)? " utf" : "", - after); -} - - - -#ifdef SUPPORT_PCRE2_8 -/************************************************* -* Show match options * -*************************************************/ - -/* Called for unsupported POSIX options. */ - -static void -show_match_options(uint32_t options) -{ -fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s", - ((options & PCRE2_ANCHORED) != 0)? " anchored" : "", - ((options & PCRE2_DFA_RESTART) != 0)? " dfa_restart" : "", - ((options & PCRE2_DFA_SHORTEST) != 0)? " dfa_shortest" : "", - ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "", - ((options & PCRE2_NOTBOL) != 0)? " notbol" : "", - ((options & PCRE2_NOTEMPTY) != 0)? " notempty" : "", - ((options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "", - ((options & PCRE2_NOTEOL) != 0)? " noteol" : "", - ((options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "", - ((options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : ""); -} -#endif /* SUPPORT_PCRE2_8 */ - - - -/************************************************* -* Show memory usage info for a pattern * -*************************************************/ - -static void -show_memory_info(void) -{ -uint32_t name_count, name_entry_size; -size_t size, cblock_size; - -#ifdef SUPPORT_PCRE2_8 -if (test_mode == 8) cblock_size = sizeof(pcre2_real_code_8); -#endif -#ifdef SUPPORT_PCRE2_16 -if (test_mode == 16) cblock_size = sizeof(pcre2_real_code_16); -#endif -#ifdef SUPPORT_PCRE2_32 -if (test_mode == 32) cblock_size = sizeof(pcre2_real_code_32); -#endif - -(void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE); -(void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE); -(void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE); -fprintf(outfile, "Memory allocation (code space): %d\n", - (int)(size - name_count*name_entry_size*code_unit_size - cblock_size)); -if (pat_patctl.jit != 0) - { - (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE); - fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)size); - } -} - - - -/************************************************* -* Callback function for callout enumeration * -*************************************************/ - -/* The only differences in the callout emumeration block for different code -unit widths are that the pointers to the subject, the most recent MARK, and a -callout argument string point to strings of the appropriate width. Casts can be -used to deal with this. - -Argument: - cb pointer to enumerate block - callout_data user data - -Returns: 0 -*/ - -static int callout_callback(pcre2_callout_enumerate_block_8 *cb, - void *callout_data) -{ -uint32_t i; -BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; - -(void)callout_data; /* Not currently displayed */ - -fprintf(outfile, "Callout "); -if (cb->callout_string != NULL) - { - uint32_t delimiter = CODE_UNIT(cb->callout_string, -1); - fprintf(outfile, "%c", delimiter); - PCHARSV(cb->callout_string, 0, - cb->callout_string_length, utf, outfile); - for (i = 0; callout_start_delims[i] != 0; i++) - if (delimiter == callout_start_delims[i]) - { - delimiter = callout_end_delims[i]; - break; - } - fprintf(outfile, "%c ", delimiter); - } -else fprintf(outfile, "%d ", cb->callout_number); - -fprintf(outfile, "%.*s\n", - (int)((cb->next_item_length == 0)? 1 : cb->next_item_length), - pbuffer8 + cb->pattern_position); - -return 0; -} - - - -/************************************************* -* Show information about a pattern * -*************************************************/ - -/* This function is called after a pattern has been compiled if any of the -information-requesting controls have been set. - -Arguments: none - -Returns: PR_OK continue processing next line - PR_SKIP skip to a blank line - PR_ABEND abort the pcre2test run -*/ - -static int -show_pattern_info(void) -{ -uint32_t compile_options, overall_options; - -if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0) - { - fprintf(outfile, "------------------------------------------------------------------\n"); - PCRE2_PRINTINT((pat_patctl.control & CTL_FULLBINCODE) != 0); - } - -if ((pat_patctl.control & CTL_INFO) != 0) - { - const void *nametable; - const uint8_t *start_bits; - BOOL match_limit_set, recursion_limit_set; - uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit, - hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty, - match_limit, minlength, nameentrysize, namecount, newline_convention, - recursion_limit; - - /* These info requests may return PCRE2_ERROR_UNSET. */ - - switch(pattern_info(PCRE2_INFO_MATCHLIMIT, &match_limit, TRUE)) - { - case 0: - match_limit_set = TRUE; - break; - - case PCRE2_ERROR_UNSET: - match_limit_set = FALSE; - break; - - default: - return PR_ABEND; - } - - switch(pattern_info(PCRE2_INFO_RECURSIONLIMIT, &recursion_limit, TRUE)) - { - case 0: - recursion_limit_set = TRUE; - break; - - case PCRE2_ERROR_UNSET: - recursion_limit_set = FALSE; - break; - - default: - return PR_ABEND; - } - - /* These info requests should always succeed. */ - - if (pattern_info(PCRE2_INFO_BACKREFMAX, &backrefmax, FALSE) + - pattern_info(PCRE2_INFO_BSR, &bsr_convention, FALSE) + - pattern_info(PCRE2_INFO_CAPTURECOUNT, &capture_count, FALSE) + - pattern_info(PCRE2_INFO_FIRSTBITMAP, &start_bits, FALSE) + - pattern_info(PCRE2_INFO_FIRSTCODEUNIT, &first_cunit, FALSE) + - pattern_info(PCRE2_INFO_FIRSTCODETYPE, &first_ctype, FALSE) + - pattern_info(PCRE2_INFO_HASBACKSLASHC, &hasbackslashc, FALSE) + - pattern_info(PCRE2_INFO_HASCRORLF, &hascrorlf, FALSE) + - pattern_info(PCRE2_INFO_JCHANGED, &jchanged, FALSE) + - pattern_info(PCRE2_INFO_LASTCODEUNIT, &last_cunit, FALSE) + - pattern_info(PCRE2_INFO_LASTCODETYPE, &last_ctype, FALSE) + - pattern_info(PCRE2_INFO_MATCHEMPTY, &match_empty, FALSE) + - pattern_info(PCRE2_INFO_MINLENGTH, &minlength, FALSE) + - pattern_info(PCRE2_INFO_NAMECOUNT, &namecount, FALSE) + - pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize, FALSE) + - pattern_info(PCRE2_INFO_NAMETABLE, &nametable, FALSE) + - pattern_info(PCRE2_INFO_NEWLINE, &newline_convention, FALSE) - != 0) - return PR_ABEND; - - fprintf(outfile, "Capturing subpattern count = %d\n", capture_count); - - if (backrefmax > 0) - fprintf(outfile, "Max back reference = %d\n", backrefmax); - - if (maxlookbehind > 0) - fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind); - - if (match_limit_set) - fprintf(outfile, "Match limit = %u\n", match_limit); - - if (recursion_limit_set) - fprintf(outfile, "Recursion limit = %u\n", recursion_limit); - - if (namecount > 0) - { - fprintf(outfile, "Named capturing subpatterns:\n"); - for (; namecount > 0; namecount--) - { - int imm2_size = test_mode == PCRE8_MODE ? 2 : 1; - uint32_t length = (uint32_t)STRLEN(nametable + imm2_size); - fprintf(outfile, " "); - PCHARSV(nametable, imm2_size, length, FALSE, outfile); - while (length++ < nameentrysize - imm2_size) putc(' ', outfile); -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE) - fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR32)nametable)[0])); -#endif -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE) - fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR16)nametable)[0])); -#endif -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) - fprintf(outfile, "%3d\n", (int)( - ((((PCRE2_SPTR8)nametable)[0]) << 8) | ((PCRE2_SPTR8)nametable)[1])); -#endif - nametable = (void*)((PCRE2_SPTR8)nametable + nameentrysize * code_unit_size); - } - } - - if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); - if (hasbackslashc) fprintf(outfile, "Contains \\C\n"); - if (match_empty) fprintf(outfile, "May match empty string\n"); - - pattern_info(PCRE2_INFO_ARGOPTIONS, &compile_options, FALSE); - pattern_info(PCRE2_INFO_ALLOPTIONS, &overall_options, FALSE); - - /* Remove UTF/UCP if they were there only because of forbid_utf. This saves - cluttering up the verification output of non-UTF test files. */ - - if ((pat_patctl.options & PCRE2_NEVER_UTF) == 0) - { - compile_options &= ~PCRE2_NEVER_UTF; - overall_options &= ~PCRE2_NEVER_UTF; - } - - if ((pat_patctl.options & PCRE2_NEVER_UCP) == 0) - { - compile_options &= ~PCRE2_NEVER_UCP; - overall_options &= ~PCRE2_NEVER_UCP; - } - - if ((compile_options|overall_options) != 0) - { - if (compile_options == overall_options) - show_compile_options(compile_options, "Options:", "\n"); - else - { - show_compile_options(compile_options, "Compile options:", "\n"); - show_compile_options(overall_options, "Overall options:", "\n"); - } - } - - if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); - - if ((pat_patctl.control & CTL_BSR_SET) != 0 || - (FLD(compiled_code, flags) & PCRE2_BSR_SET) != 0) - fprintf(outfile, "\\R matches %s\n", (bsr_convention == PCRE2_BSR_UNICODE)? - "any Unicode newline" : "CR, LF, or CRLF"); - - if ((FLD(compiled_code, flags) & PCRE2_NL_SET) != 0) - { - switch (newline_convention) - { - case PCRE2_NEWLINE_CR: - fprintf(outfile, "Forced newline is CR\n"); - break; - - case PCRE2_NEWLINE_LF: - fprintf(outfile, "Forced newline is LF\n"); - break; - - case PCRE2_NEWLINE_CRLF: - fprintf(outfile, "Forced newline is CRLF\n"); - break; - - case PCRE2_NEWLINE_ANYCRLF: - fprintf(outfile, "Forced newline is CR, LF, or CRLF\n"); - break; - - case PCRE2_NEWLINE_ANY: - fprintf(outfile, "Forced newline is any Unicode newline\n"); - break; - - default: - break; - } - } - - if (first_ctype == 2) - { - fprintf(outfile, "First code unit at start or follows newline\n"); - } - else if (first_ctype == 1) - { - const char *caseless = - ((FLD(compiled_code, flags) & PCRE2_FIRSTCASELESS) == 0)? - "" : " (caseless)"; - if (PRINTOK(first_cunit)) - fprintf(outfile, "First code unit = \'%c\'%s\n", first_cunit, caseless); - else - { - fprintf(outfile, "First code unit = "); - pchar(first_cunit, FALSE, outfile); - fprintf(outfile, "%s\n", caseless); - } - } - else if (start_bits != NULL) - { - int i; - int c = 24; - fprintf(outfile, "Starting code units: "); - for (i = 0; i < 256; i++) - { - if ((start_bits[i/8] & (1<<(i&7))) != 0) - { - if (c > 75) - { - fprintf(outfile, "\n "); - c = 2; - } - if (PRINTOK(i) && i != ' ') - { - fprintf(outfile, "%c ", i); - c += 2; - } - else - { - fprintf(outfile, "\\x%02x ", i); - c += 5; - } - } - } - fprintf(outfile, "\n"); - } - - if (last_ctype != 0) - { - const char *caseless = - ((FLD(compiled_code, flags) & PCRE2_LASTCASELESS) == 0)? - "" : " (caseless)"; - if (PRINTOK(last_cunit)) - fprintf(outfile, "Last code unit = \'%c\'%s\n", last_cunit, caseless); - else - { - fprintf(outfile, "Last code unit = "); - pchar(last_cunit, FALSE, outfile); - fprintf(outfile, "%s\n", caseless); - } - } - - fprintf(outfile, "Subject length lower bound = %d\n", minlength); - - if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0) - { - if (FLD(compiled_code, executable_jit) != NULL) - fprintf(outfile, "JIT compilation was successful\n"); - else - { -#ifdef SUPPORT_JIT - int len; - fprintf(outfile, "JIT compilation was not successful"); - if (jitrc != 0) - { - fprintf(outfile, " ("); - PCRE2_GET_ERROR_MESSAGE(len, jitrc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); - fprintf(outfile, ")"); - } - fprintf(outfile, "\n"); -#else - fprintf(outfile, "JIT support is not available in this version of PCRE2\n"); -#endif - } - } - } - -if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0) - { - int errorcode; - PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0); - if (errorcode != 0) - { - int len; - fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode); - if (errorcode < 0) - { - PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); - } - fprintf(outfile, "\n"); - return PR_SKIP; - } - } - -return PR_OK; -} - - - -/************************************************* -* Handle serialization error * -*************************************************/ - -/* Print an error message after a serialization failure. - -Arguments: - rc the error code - msg an initial message for what failed - -Returns: nothing -*/ - -static void -serial_error(int rc, const char *msg) -{ -fprintf(outfile, "%s failed: error %d: ", msg, rc); -PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); -PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); -fprintf(outfile, "\n"); -} - - - -/************************************************* -* Open file for save/load commands * -*************************************************/ - -/* This function decodes the file name and opens the file. - -Arguments: - buffptr point after the #command - mode open mode - fptr points to the FILE variable - -Returns: PR_OK or PR_ABEND -*/ - -static int -open_file(uint8_t *buffptr, const char *mode, FILE **fptr) -{ -char *endf; -char *filename = (char *)buffptr; -while (isspace(*filename)) filename++; -endf = filename + strlen8(filename); -while (endf > filename && isspace(endf[-1])) endf--; - -if (endf == filename) - { - fprintf(outfile, "** File name expected after #save\n"); - return PR_ABEND; - } - -*endf = 0; -*fptr = fopen((const char *)filename, mode); -if (*fptr == NULL) - { - fprintf(outfile, "** Failed to open '%s'\n", filename); - return PR_ABEND; - } - -return PR_OK; -} - - - -/************************************************* -* Process command line * -*************************************************/ - -/* This function is called for lines beginning with # and a character that is -not ! or whitespace, when encountered between tests, which means that there is -no compiled pattern (compiled_code is NULL). The line is in buffer. - -Arguments: none - -Returns: PR_OK continue processing next line - PR_SKIP skip to a blank line - PR_ABEND abort the pcre2test run -*/ - -static int -process_command(void) -{ -FILE *f; -PCRE2_SIZE serial_size; -size_t i; -int rc, cmd, cmdlen; -uint16_t first_listed_newline; -const char *cmdname; -uint8_t *argptr, *serial; - -if (restrict_for_perl_test) - { - fprintf(outfile, "** #-commands are not allowed after #perltest\n"); - return PR_ABEND; - } - -cmd = CMD_UNKNOWN; -cmdlen = 0; - -for (i = 0; i < cmdlistcount; i++) - { - cmdname = cmdlist[i].name; - cmdlen = strlen(cmdname); - if (strncmp((char *)(buffer+1), cmdname, cmdlen) == 0 && - isspace(buffer[cmdlen+1])) - { - cmd = cmdlist[i].value; - break; - } - } - -argptr = buffer + cmdlen + 1; - -switch(cmd) - { - case CMD_UNKNOWN: - fprintf(outfile, "** Unknown command: %s", buffer); - break; - - case CMD_FORBID_UTF: - forbid_utf = PCRE2_NEVER_UTF|PCRE2_NEVER_UCP; - break; - - case CMD_PERLTEST: - restrict_for_perl_test = TRUE; - break; - - /* Set default pattern modifiers */ - - case CMD_PATTERN: - (void)decode_modifiers(argptr, CTX_DEFPAT, &def_patctl, NULL); - if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0) - def_patctl.jit = 7; - break; - - /* Set default subject modifiers */ - - case CMD_SUBJECT: - (void)decode_modifiers(argptr, CTX_DEFDAT, NULL, &def_datctl); - break; - - /* Check the default newline, and if not one of those listed, set up the - first one to be forced. An empty list unsets. */ - - case CMD_NEWLINE_DEFAULT: - local_newline_default = 0; /* Unset */ - first_listed_newline = 0; - for (;;) - { - while (isspace(*argptr)) argptr++; - if (*argptr == 0) break; - for (i = 1; i < sizeof(newlines)/sizeof(char *); i++) - { - size_t nlen = strlen(newlines[i]); - if (strncmpic(argptr, (const uint8_t *)newlines[i], nlen) == 0 && - isspace(argptr[nlen])) - { - if (i == NEWLINE_DEFAULT) return PR_OK; /* Default is valid */ - if (first_listed_newline == 0) first_listed_newline = i; - } - } - while (*argptr != 0 && !isspace(*argptr)) argptr++; - } - local_newline_default = first_listed_newline; - break; - - /* Pop a compiled pattern off the stack. Modifiers that do not affect the - compiled pattern (e.g. to give information) are permitted. The default - pattern modifiers are ignored. */ - - case CMD_POP: - if (patstacknext <= 0) - { - fprintf(outfile, "** Can't pop off an empty stack\n"); - return PR_SKIP; - } - memset(&pat_patctl, 0, sizeof(patctl)); /* Completely unset */ - if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL)) - return PR_SKIP; - SET(compiled_code, patstack[--patstacknext]); - if (pat_patctl.jit != 0) - { - PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit); - } - if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info(); - if ((pat_patctl.control & CTL_ANYINFO) != 0) - { - rc = show_pattern_info(); - if (rc != PR_OK) return rc; - } - break; - - /* Save the stack of compiled patterns to a file, then empty the stack. */ - - case CMD_SAVE: - if (patstacknext <= 0) - { - fprintf(outfile, "** No stacked patterns to save\n"); - return PR_OK; - } - - rc = open_file(argptr+1, BINARY_OUTPUT_MODE, &f); - if (rc != PR_OK) return rc; - - PCRE2_SERIALIZE_ENCODE(rc, patstack, patstacknext, &serial, &serial_size, - general_context); - if (rc < 0) - { - serial_error(rc, "Serialization"); - break; - } - - /* Write the length at the start of the file to make it straightforward to - get the right memory when re-loading. This saves having to read the file size - in different operating systems. To allow for different endianness (even - though reloading with the opposite endianness does not work), write the - length byte-by-byte. */ - - for (i = 0; i < 4; i++) fputc((serial_size >> (i*8)) & 255, f); - if (fwrite(serial, 1, serial_size, f) != serial_size) - { - fprintf(outfile, "** Wrong return from fwrite()\n"); - return PR_ABEND; - } - - fclose(f); - PCRE2_SERIALIZE_FREE(serial); - while(patstacknext > 0) - { - SET(compiled_code, patstack[--patstacknext]); - SUB1(pcre2_code_free, compiled_code); - } - SET(compiled_code, NULL); - break; - - /* Load a set of compiled patterns from a file onto the stack */ - - case CMD_LOAD: - rc = open_file(argptr+1, BINARY_INPUT_MODE, &f); - if (rc != PR_OK) return rc; - - serial_size = 0; - for (i = 0; i < 4; i++) serial_size |= fgetc(f) << (i*8); - - serial = malloc(serial_size); - if (serial == NULL) - { - fprintf(outfile, "** Failed to get memory (size %lu) for #load\n", - (unsigned long int)serial_size); - return PR_ABEND; - } - - if (fread(serial, 1, serial_size, f) != serial_size) - { - fprintf(outfile, "** Wrong return from fread()\n"); - return PR_ABEND; - } - fclose(f); - - PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial); - if (rc < 0) serial_error(rc, "Get number of codes"); else - { - if (rc + patstacknext > PATSTACKSIZE) - { - fprintf(outfile, "** Not enough space on pattern stack for %d pattern%s\n", - rc, (rc == 1)? "" : "s"); - rc = PATSTACKSIZE - patstacknext; - fprintf(outfile, "** Decoding %d pattern%s\n", rc, - (rc == 1)? "" : "s"); - } - PCRE2_SERIALIZE_DECODE(rc, patstack + patstacknext, rc, serial, - general_context); - if (rc < 0) serial_error(rc, "Deserialization"); - else patstacknext += rc; - } - - free(serial); - break; - } - -return PR_OK; -} - - - -/************************************************* -* Process pattern line * -*************************************************/ - -/* This function is called when the input buffer contains the start of a -pattern. The first character is known to be a valid delimiter. The pattern is -read, modifiers are interpreted, and a suitable local context is set up for -this test. The pattern is then compiled. - -Arguments: none - -Returns: PR_OK continue processing next line - PR_SKIP skip to a blank line - PR_ABEND abort the pcre2test run -*/ - -static int -process_pattern(void) -{ -BOOL utf; -uint32_t k; -uint8_t *p = buffer; -const uint8_t *use_tables; -unsigned int delimiter = *p++; -int errorcode; -void *use_pat_context; -PCRE2_SIZE patlen; -PCRE2_SIZE erroroffset; - -/* Initialize the context and pattern/data controls for this test from the -defaults. */ - -PATCTXCPY(pat_context, default_pat_context); -memcpy(&pat_patctl, &def_patctl, sizeof(patctl)); - -/* Find the end of the pattern, reading more lines if necessary. */ - -for(;;) - { - while (*p != 0) - { - if (*p == '\\' && p[1] != 0) p++; - else if (*p == delimiter) break; - p++; - } - if (*p != 0) break; - if ((p = extend_inputline(infile, p, " > ")) == NULL) - { - fprintf(outfile, "** Unexpected EOF\n"); - return PR_ABEND; - } - if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)p); - } - -/* If the first character after the delimiter is backslash, make the pattern -end with backslash. This is purely to provide a way of testing for the error -message when a pattern ends with backslash. */ - -if (p[1] == '\\') *p++ = '\\'; - -/* Terminate the pattern at the delimiter, and compute the length. */ - -*p++ = 0; -patlen = p - buffer - 2; - -/* Look for modifiers and options after the final delimiter. */ - -if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP; -utf = (pat_patctl.options & PCRE2_UTF) != 0; - -/* Check for mutually exclusive modifiers. At present, these are all in the -first control word. */ - -for (k = 0; k < sizeof(exclusive_pat_controls)/sizeof(uint32_t); k++) - { - uint32_t c = pat_patctl.control & exclusive_pat_controls[k]; - if (c != 0 && c != (c & (~c+1))) - { - show_controls(c, 0, "** Not allowed together:"); - fprintf(outfile, "\n"); - return PR_SKIP; - } - } - -/* Assume full JIT compile for jitverify and/or jitfast if nothing else was -specified. */ - -if (pat_patctl.jit == 0 && - (pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0) - pat_patctl.jit = 7; - -/* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting -in callouts. Convert from hex if required; this must necessarily be fewer -characters so will always fit in pbuffer8. Alternatively, process for -repetition if requested. */ - -if ((pat_patctl.control & CTL_HEXPAT) != 0) - { - uint8_t *pp, *pt; - uint32_t c, d; - - pt = pbuffer8; - for (pp = buffer + 1; *pp != 0; pp++) - { - if (isspace(*pp)) continue; - c = toupper(*pp++); - if (*pp == 0) - { - fprintf(outfile, "** Odd number of digits in hex pattern.\n"); - return PR_SKIP; - } - d = toupper(*pp); - if (!isxdigit(c) || !isxdigit(d)) - { - fprintf(outfile, "** Non-hex-digit in hex pattern.\n"); - return PR_SKIP; - } - *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) + - (isdigit(d)? (d - '0') : (d - 'A' + 10)); - } - *pt = 0; - patlen = pt - pbuffer8; - } - -else if ((pat_patctl.control & CTL_EXPAND) != 0) - { - uint8_t *pp, *pt; - - pt = pbuffer8; - for (pp = buffer + 1; *pp != 0; pp++) - { - uint8_t *pc = pp; - uint32_t count = 1; - size_t length = 1; - - /* Check for replication syntax; if not found, the defaults just set will - prevail and one character will be copied. */ - - if (pp[0] == '\\' && pp[1] == '[') - { - uint8_t *pe; - for (pe = pp + 2; *pe != 0; pe++) - { - if (pe[0] == ']' && pe[1] == '{') - { - uint32_t clen = pe - pc - 2; - uint32_t i = 0; - pe += 2; - while (isdigit(*pe)) i = i * 10 + *pe++ - '0'; - if (*pe == '}') - { - if (i == 0) - { - fprintf(outfile, "** Zero repeat not allowed\n"); - return PR_SKIP; - } - pc += 2; - count = i; - length = clen; - pp = pe; - break; - } - } - } - } - - /* Add to output. If the buffer is too small expand it. The function for - expanding buffers always keeps buffer and pbuffer8 in step as far as their - size goes. */ - - while (pt + count * length > pbuffer8 + pbuffer8_size) - { - size_t pc_offset = pc - buffer; - size_t pp_offset = pp - buffer; - size_t pt_offset = pt - pbuffer8; - expand_input_buffers(); - pc = buffer + pc_offset; - pp = buffer + pp_offset; - pt = pbuffer8 + pt_offset; - } - - while (count-- > 0) - { - memcpy(pt, pc, length); - pt += length; - } - } - - *pt = 0; - patlen = pt - pbuffer8; - - if ((pat_patctl.control & CTL_INFO) != 0) - fprintf(outfile, "Expanded: %s\n", pbuffer8); - } - -/* Neither hex nor expanded, just copy the input verbatim. */ - -else - { - strncpy((char *)pbuffer8, (char *)(buffer+1), patlen + 1); - } - -/* Sort out character tables */ - -if (pat_patctl.locale[0] != 0) - { - if (pat_patctl.tables_id != 0) - { - fprintf(outfile, "** 'Locale' and 'tables' must not both be set.\n"); - return PR_SKIP; - } - if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale) == NULL) - { - fprintf(outfile, "** Failed to set locale '%s'\n", pat_patctl.locale); - return PR_SKIP; - } - if (strcmp((const char *)pat_patctl.locale, (const char *)locale_name) != 0) - { - strcpy((char *)locale_name, (char *)pat_patctl.locale); - if (locale_tables != NULL) free((void *)locale_tables); - PCRE2_MAKETABLES(locale_tables); - } - use_tables = locale_tables; - } - -else switch (pat_patctl.tables_id) - { - case 0: use_tables = NULL; break; - case 1: use_tables = tables1; break; - case 2: use_tables = tables2; break; - default: - fprintf(outfile, "** 'Tables' must specify 0, 1, or 2.\n"); - return PR_SKIP; - } - -PCRE2_SET_CHARACTER_TABLES(pat_context, use_tables); - -/* Set up for the stackguard test. */ - -if (pat_patctl.stackguard_test != 0) - { - PCRE2_SET_COMPILE_RECURSION_GUARD(pat_context, stack_guard, NULL); - } - -/* Handle compiling via the POSIX interface, which doesn't support the -timing, showing, or debugging options, nor the ability to pass over -local character tables. Neither does it have 16-bit or 32-bit support. */ - -if ((pat_patctl.control & CTL_POSIX) != 0) - { -#ifdef SUPPORT_PCRE2_8 - int rc; - int cflags = 0; - const char *msg = "** Ignored with POSIX interface:"; -#endif - - if (test_mode != 8) - { - fprintf(outfile, "** The POSIX interface is available only in 8-bit mode\n"); - return PR_SKIP; - } - -#ifdef SUPPORT_PCRE2_8 - /* Check for features that the POSIX interface does not support. */ - - if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale"); - if (pat_patctl.replacement[0] != 0) prmsg(&msg, "replace"); - if (pat_patctl.tables_id != 0) prmsg(&msg, "tables"); - if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard"); - if (timeit > 0) prmsg(&msg, "timing"); - if (pat_patctl.jit != 0) prmsg(&msg, "JIT"); - - if ((pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS) != 0) - { - show_compile_options( - pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS, msg, ""); - msg = ""; - } - if ((pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS) != 0 || - (pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2) != 0) - { - show_controls(pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS, - pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2, msg); - msg = ""; - } - - if (local_newline_default != 0) prmsg(&msg, "#newline_default"); - - if (msg[0] == 0) fprintf(outfile, "\n"); - - /* Translate PCRE2 options to POSIX options and then compile. On success, set - up a match_data block to be used for all matches. */ - - if (utf) cflags |= REG_UTF; - if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP; - if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE; - if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE; - if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL; - if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; - if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY; - - rc = regcomp(&preg, (char *)pbuffer8, cflags); - if (rc != 0) /* Failure */ - { - size_t bsize, usize; - - preg.re_pcre2_code = NULL; /* In case something was left in there */ - preg.re_match_data = NULL; - - bsize = (pat_patctl.regerror_buffsize != 0)? - pat_patctl.regerror_buffsize : pbuffer8_size; - if (bsize + 8 < pbuffer8_size) - memcpy(pbuffer8 + bsize, "DEADBEEF", 8); - usize = regerror(rc, &preg, (char *)pbuffer8, bsize); - - fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, pbuffer8); - if (usize > bsize) - { - fprintf(outfile, "** regerror() message truncated\n"); - if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0) - fprintf(outfile, "** regerror() buffer overflow\n"); - } - return PR_SKIP; - } - return PR_OK; -#endif /* SUPPORT_PCRE2_8 */ - } - -/* Handle compiling via the native interface. Controls that act later are -ignored with "push". Replacements are locked out. */ - -if ((pat_patctl.control & CTL_PUSH) != 0) - { - if (pat_patctl.replacement[0] != 0) - { - fprintf(outfile, "** Replacement text is not supported with 'push'.\n"); - return PR_OK; - } - if ((pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS) != 0 || - (pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2) != 0) - { - show_controls(pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS, - pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2, - "** Ignored when compiled pattern is stacked with 'push':"); - fprintf(outfile, "\n"); - } - if ((pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS) != 0 || - (pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2) != 0) - { - show_controls(pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS, - pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2, - "** Applies only to compile when pattern is stacked with 'push':"); - fprintf(outfile, "\n"); - } - } - -/* Convert the input in non-8-bit modes. */ - -#ifdef SUPPORT_PCRE2_8 -if (test_mode == PCRE8_MODE) errorcode = 0; -#endif - -#ifdef SUPPORT_PCRE2_16 -if (test_mode == PCRE16_MODE) errorcode = to16(pbuffer8, utf, &patlen); -#endif - -#ifdef SUPPORT_PCRE2_32 -if (test_mode == PCRE32_MODE) errorcode = to32(pbuffer8, utf, &patlen); -#endif - -switch(errorcode) - { - case -1: - fprintf(outfile, "** Failed: invalid UTF-8 string cannot be " - "converted to %d-bit string\n", (test_mode == PCRE16_MODE)? 16:32); - return PR_SKIP; - - case -2: - fprintf(outfile, "** Failed: character value greater than 0x10ffff " - "cannot be converted to UTF\n"); - return PR_SKIP; - - case -3: - fprintf(outfile, "** Failed: character value greater than 0xffff " - "cannot be converted to 16-bit in non-UTF mode\n"); - return PR_SKIP; - - default: - break; - } - -/* The pattern is now in pbuffer[8|16|32], with the length in patlen. By -default, however, we pass a zero-terminated pattern. The length is passed only -if we had a hex pattern. */ - -if ((pat_patctl.control & CTL_HEXPAT) == 0) patlen = PCRE2_ZERO_TERMINATED; - -/* If #newline_default has been used and the library was not compiled with an -appropriate default newline setting, local_newline_default will be non-zero. We -use this if there is no explicit newline modifier. */ - -if ((pat_patctl.control & CTL_NL_SET) == 0 && local_newline_default != 0) - { - SETFLD(pat_context, newline_convention, local_newline_default); - } - -/* The nullcontext modifier is used to test calling pcre2_compile() with a NULL -context. */ - -use_pat_context = ((pat_patctl.control & CTL_NULLCONTEXT) != 0)? - NULL : PTR(pat_context); - -/* Compile many times when timing. */ - -if (timeit > 0) - { - register int i; - clock_t time_taken = 0; - for (i = 0; i < timeit; i++) - { - clock_t start_time = clock(); - PCRE2_COMPILE(compiled_code, pbuffer, patlen, - pat_patctl.options|forbid_utf, &errorcode, &erroroffset, use_pat_context); - time_taken += clock() - start_time; - if (TEST(compiled_code, !=, NULL)) - { SUB1(pcre2_code_free, compiled_code); } - } - total_compile_time += time_taken; - fprintf(outfile, "Compile time %.4f milliseconds\n", - (((double)time_taken * 1000.0) / (double)timeit) / - (double)CLOCKS_PER_SEC); - } - -/* A final compile that is used "for real". */ - -PCRE2_COMPILE(compiled_code, pbuffer, patlen, pat_patctl.options|forbid_utf, - &errorcode, &erroroffset, use_pat_context); - -/* Compilation failed; go back for another re, skipping to blank line -if non-interactive. */ - -if (TEST(compiled_code, ==, NULL)) - { - int len; - fprintf(outfile, "Failed: error %d at offset %d: ", errorcode, - (int)erroroffset); - PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile); - fprintf(outfile, "\n"); - return PR_SKIP; - } - -/* If forbid_utf is non-zero, we are running a non-UTF test. UTF and UCP are -locked out at compile time, but we must also check for occurrences of \P, \p, -and \X, which are only supported when Unicode is supported. */ - -if (forbid_utf != 0) - { - if ((FLD(compiled_code, flags) & PCRE2_HASBKPORX) != 0) - { - fprintf(outfile, "** \\P, \\p, and \\X are not allowed after the " - "#forbid_utf command\n"); - return PR_SKIP; - } - } - -/* Remember the maximum lookbehind, for partial matching. */ - -if (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0) - return PR_ABEND; - -/* Call the JIT compiler if requested. When timing, we must free and recompile -the pattern each time because that is the only way to free the JIT compiled -code. We know that compilation will always succeed. */ - -if (pat_patctl.jit != 0) - { - if (timeit > 0) - { - register int i; - clock_t time_taken = 0; - for (i = 0; i < timeit; i++) - { - clock_t start_time; - SUB1(pcre2_code_free, compiled_code); - PCRE2_COMPILE(compiled_code, pbuffer, patlen, - pat_patctl.options|forbid_utf, &errorcode, &erroroffset, - use_pat_context); - start_time = clock(); - PCRE2_JIT_COMPILE(jitrc,compiled_code, pat_patctl.jit); - time_taken += clock() - start_time; - } - total_jit_compile_time += time_taken; - fprintf(outfile, "JIT compile %.4f milliseconds\n", - (((double)time_taken * 1000.0) / (double)timeit) / - (double)CLOCKS_PER_SEC); - } - else - { - PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit); - } - } - -/* If an explicit newline modifier was given, set the information flag in the -pattern so that it is preserved over push/pop. */ - -if ((pat_patctl.control & CTL_NL_SET) != 0) - { - SETFLD(compiled_code, flags, FLD(compiled_code, flags) | PCRE2_NL_SET); - } - -/* Output code size and other information if requested. */ - -if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info(); -if ((pat_patctl.control & CTL_ANYINFO) != 0) - { - int rc = show_pattern_info(); - if (rc != PR_OK) return rc; - } - -/* The "push" control requests that the compiled pattern be remembered on a -stack. This is mainly for testing the serialization functionality. */ - -if ((pat_patctl.control & CTL_PUSH) != 0) - { - if (patstacknext >= PATSTACKSIZE) - { - fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE); - return PR_ABEND; - } - patstack[patstacknext++] = PTR(compiled_code); - SET(compiled_code, NULL); - } - -return PR_OK; -} - - - -/************************************************* -* Check match or recursion limit * -*************************************************/ - -static int -check_match_limit(uint8_t *pp, size_t ulen, int errnumber, const char *msg) -{ -int capcount; -uint32_t min = 0; -uint32_t mid = 64; -uint32_t max = UINT32_MAX; - -PCRE2_SET_MATCH_LIMIT(dat_context, max); -PCRE2_SET_RECURSION_LIMIT(dat_context, max); - -for (;;) - { - if (errnumber == PCRE2_ERROR_MATCHLIMIT) - { - PCRE2_SET_MATCH_LIMIT(dat_context, mid); - } - else - { - PCRE2_SET_RECURSION_LIMIT(dat_context, mid); - } - - if ((pat_patctl.control & CTL_JITFAST) != 0) - PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, - dat_datctl.options, match_data, PTR(dat_context)); - else - PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, - dat_datctl.options, match_data, PTR(dat_context)); - - if (capcount == errnumber) - { - min = mid; - mid = (mid == max - 1)? max : (max != UINT32_MAX)? (min + max)/2 : mid*2; - } - else if (capcount >= 0 || - capcount == PCRE2_ERROR_NOMATCH || - capcount == PCRE2_ERROR_PARTIAL) - { - if (mid == min + 1) - { - fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); - break; - } - max = mid; - mid = (min + mid)/2; - } - else break; /* Some other error */ - } - -return capcount; -} - - - -/************************************************* -* Callout function * -*************************************************/ - -/* Called from a PCRE2 library as a result of the (?C) item. We print out where -we are in the match. Yield zero unless more callouts than the fail count, or -the callout data is not zero. The only differences in the callout block for -different code unit widths are that the pointers to the subject, the most -recent MARK, and a callout argument string point to strings of the appropriate -width. Casts can be used to deal with this. - -Argument: a pointer to a callout block -Return: -*/ - -static int -callout_function(pcre2_callout_block_8 *cb, void *callout_data_ptr) -{ -uint32_t i, pre_start, post_start, subject_length; -BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; -BOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0; - -/* This FILE is used for echoing the subject. This is done only once in simple -cases. */ - -FILE *f = (first_callout || callout_capture || cb->callout_string != NULL)? - outfile : NULL; - -/* For a callout with a string argument, show the string first because there -isn't a tidy way to fit it in the rest of the data. */ - -if (cb->callout_string != NULL) - { - uint32_t delimiter = CODE_UNIT(cb->callout_string, -1); - fprintf(outfile, "Callout (%lu): %c", - (unsigned long int)cb->callout_string_offset, delimiter); - PCHARSV(cb->callout_string, 0, - cb->callout_string_length, utf, outfile); - for (i = 0; callout_start_delims[i] != 0; i++) - if (delimiter == callout_start_delims[i]) - { - delimiter = callout_end_delims[i]; - break; - } - fprintf(outfile, "%c", delimiter); - if (!callout_capture) fprintf(outfile, "\n"); - } - -/* Show captured strings if required */ - -if (callout_capture) - { - if (cb->callout_string == NULL) - fprintf(outfile, "Callout %d:", cb->callout_number); - fprintf(outfile, " last capture = %d\n", cb->capture_last); - for (i = 0; i < cb->capture_top * 2; i += 2) - { - fprintf(outfile, "%2d: ", i/2); - if (cb->offset_vector[i] == PCRE2_UNSET) - fprintf(outfile, ""); - else - { - PCHARSV(cb->subject, cb->offset_vector[i], - cb->offset_vector[i+1] - cb->offset_vector[i], utf, f); - } - fprintf(outfile, "\n"); - } - } - -/* Re-print the subject in canonical form, the first time or if giving full -datails. On subsequent calls in the same match, we use pchars just to find the -printed lengths of the substrings. */ - -if (f != NULL) fprintf(f, "--->"); - -PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f); - -PCHARS(post_start, cb->subject, cb->start_match, - cb->current_position - cb->start_match, utf, f); - -PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL); - -PCHARSV(cb->subject, cb->current_position, - cb->subject_length - cb->current_position, utf, f); - -if (f != NULL) fprintf(f, "\n"); - -/* For automatic callouts, show the pattern offset. Otherwise, for a numerical -callout whose number has not already been shown with captured strings, show the -number here. A callout with a string argument has been displayed above. */ - -if (cb->callout_number == 255) - { - fprintf(outfile, "%+3d ", (int)cb->pattern_position); - if (cb->pattern_position > 99) fprintf(outfile, "\n "); - } -else - { - if (callout_capture || cb->callout_string != NULL) fprintf(outfile, " "); - else fprintf(outfile, "%3d ", cb->callout_number); - } - -/* Now show position indicators */ - -for (i = 0; i < pre_start; i++) fprintf(outfile, " "); -fprintf(outfile, "^"); - -if (post_start > 0) - { - for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); - fprintf(outfile, "^"); - } - -for (i = 0; i < subject_length - pre_start - post_start + 4; i++) - fprintf(outfile, " "); - -fprintf(outfile, "%.*s", - (int)((cb->next_item_length == 0)? 1 : cb->next_item_length), - pbuffer8 + cb->pattern_position); - -fprintf(outfile, "\n"); -first_callout = FALSE; - -if (cb->mark != last_callout_mark) - { - if (cb->mark == NULL) - fprintf(outfile, "Latest Mark: \n"); - else - { - fprintf(outfile, "Latest Mark: "); - PCHARSV(cb->mark, 0, -1, utf, outfile); - putc('\n', outfile); - } - last_callout_mark = cb->mark; - } - -if (callout_data_ptr != NULL) - { - int callout_data = *((int32_t *)callout_data_ptr); - if (callout_data != 0) - { - fprintf(outfile, "Callout data = %d\n", callout_data); - return callout_data; - } - } - -return (cb->callout_number != dat_datctl.cfail[0])? 0 : - (++callout_count >= dat_datctl.cfail[1])? 1 : 0; -} - - - -/************************************************* -* Handle *MARK and copy/get tests * -*************************************************/ - -/* This function is called after complete and partial matches. It runs the -tests for substring extraction. - -Arguments: - utf TRUE for utf - capcount return from pcre2_match() - -Returns: nothing -*/ - -static void -copy_and_get(BOOL utf, int capcount) -{ -int i; -uint8_t *nptr; - -/* Test copy strings by number */ - -for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++) - { - int rc; - PCRE2_SIZE length, length2; - uint32_t copybuffer[256]; - uint32_t n = (uint32_t)(dat_datctl.copy_numbers[i]); - length = sizeof(copybuffer)/code_unit_size; - PCRE2_SUBSTRING_COPY_BYNUMBER(rc, match_data, n, copybuffer, &length); - if (rc < 0) - { - fprintf(outfile, "Copy substring %d failed (%d): ", n, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else - { - PCRE2_SUBSTRING_LENGTH_BYNUMBER(rc, match_data, n, &length2); - if (rc < 0) - { - fprintf(outfile, "Get substring %d length failed (%d): ", n, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else if (length2 != length) - { - fprintf(outfile, "Mismatched substring lengths: %lu %lu\n", - (unsigned long int)length, (unsigned long int)length2); - } - fprintf(outfile, "%2dC ", n); - PCHARSV(copybuffer, 0, length, utf, outfile); - fprintf(outfile, " (%lu)\n", (unsigned long)length); - } - } - -/* Test copy strings by name */ - -nptr = dat_datctl.copy_names; -for (;;) - { - int rc; - int groupnumber; - PCRE2_SIZE length, length2; - uint32_t copybuffer[256]; - int namelen = strlen((const char *)nptr); -#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32 - PCRE2_SIZE cnl = namelen; -#endif - if (namelen == 0) break; - -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr); -#endif -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl); -#endif -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl); -#endif - - PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer); - if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING) - fprintf(outfile, "Number not found for group '%s'\n", nptr); - - length = sizeof(copybuffer)/code_unit_size; - PCRE2_SUBSTRING_COPY_BYNAME(rc, match_data, pbuffer, copybuffer, &length); - if (rc < 0) - { - fprintf(outfile, "Copy substring '%s' failed (%d): ", nptr, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else - { - PCRE2_SUBSTRING_LENGTH_BYNAME(rc, match_data, pbuffer, &length2); - if (rc < 0) - { - fprintf(outfile, "Get substring '%s' length failed (%d): ", nptr, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else if (length2 != length) - { - fprintf(outfile, "Mismatched substring lengths: %lu %lu\n", - (unsigned long int)length, (unsigned long int)length2); - } - fprintf(outfile, " C "); - PCHARSV(copybuffer, 0, length, utf, outfile); - fprintf(outfile, " (%lu) %s", (unsigned long)length, nptr); - if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber); - else fprintf(outfile, " (non-unique)\n"); - } - nptr += namelen + 1; - } - -/* Test get strings by number */ - -for (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++) - { - int rc; - PCRE2_SIZE length; - void *gotbuffer; - uint32_t n = (uint32_t)(dat_datctl.get_numbers[i]); - PCRE2_SUBSTRING_GET_BYNUMBER(rc, match_data, n, &gotbuffer, &length); - if (rc < 0) - { - fprintf(outfile, "Get substring %d failed (%d): ", n, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else - { - fprintf(outfile, "%2dG ", n); - PCHARSV(gotbuffer, 0, length, utf, outfile); - fprintf(outfile, " (%lu)\n", (unsigned long)length); - PCRE2_SUBSTRING_FREE(gotbuffer); - } - } - -/* Test get strings by name */ - -nptr = dat_datctl.get_names; -for (;;) - { - PCRE2_SIZE length; - void *gotbuffer; - int rc; - int groupnumber; - int namelen = strlen((const char *)nptr); -#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32 - PCRE2_SIZE cnl = namelen; -#endif - if (namelen == 0) break; - -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr); -#endif -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl); -#endif -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl); -#endif - - PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer); - if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING) - fprintf(outfile, "Number not found for group '%s'\n", nptr); - - PCRE2_SUBSTRING_GET_BYNAME(rc, match_data, pbuffer, &gotbuffer, &length); - if (rc < 0) - { - fprintf(outfile, "Get substring '%s' failed (%d): ", nptr, rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else - { - fprintf(outfile, " G "); - PCHARSV(gotbuffer, 0, length, utf, outfile); - fprintf(outfile, " (%lu) %s", (unsigned long)length, nptr); - if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber); - else fprintf(outfile, " (non-unique)\n"); - PCRE2_SUBSTRING_FREE(gotbuffer); - } - nptr += namelen + 1; - } - -/* Test getting the complete list of captured strings. */ - -if ((dat_datctl.control & CTL_GETALL) != 0) - { - int rc; - void **stringlist; - PCRE2_SIZE *lengths; - PCRE2_SUBSTRING_LIST_GET(rc, match_data, &stringlist, &lengths); - if (rc < 0) - { - fprintf(outfile, "get substring list failed (%d): ", rc); - PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile); - fprintf(outfile, "\n"); - } - else - { - for (i = 0; i < capcount; i++) - { - fprintf(outfile, "%2dL ", i); - PCHARSV(stringlist[i], 0, lengths[i], utf, outfile); - putc('\n', outfile); - } - if (stringlist[i] != NULL) - fprintf(outfile, "string list not terminated by NULL\n"); - PCRE2_SUBSTRING_LIST_FREE(stringlist); - } - } -} - - - -/************************************************* -* Process a data line * -*************************************************/ - -/* The line is in buffer; it will not be empty. - -Arguments: none - -Returns: PR_OK continue processing next line - PR_SKIP skip to a blank line - PR_ABEND abort the pcre2test run -*/ - -static int -process_data(void) -{ -PCRE2_SIZE len, ulen; -uint32_t gmatched; -uint32_t c, k; -uint32_t g_notempty = 0; -uint8_t *p, *pp, *start_rep; -size_t needlen; -void *use_dat_context; -BOOL utf; - -#ifdef SUPPORT_PCRE2_8 -uint8_t *q8 = NULL; -#endif -#ifdef SUPPORT_PCRE2_16 -uint16_t *q16 = NULL; -#endif -#ifdef SUPPORT_PCRE2_32 -uint32_t *q32 = NULL; -#endif - -/* Copy the default context and data control blocks to the active ones. Then -copy from the pattern the controls that can be set in either the pattern or the -data. This allows them to be overridden in the data line. We do not do this for -options because those that are common apply separately to compiling and -matching. */ - -DATCTXCPY(dat_context, default_dat_context); -memcpy(&dat_datctl, &def_datctl, sizeof(datctl)); -dat_datctl.control |= (pat_patctl.control & CTL_ALLPD); -dat_datctl.control2 |= (pat_patctl.control2 & CTL2_ALLPD); -strcpy((char *)dat_datctl.replacement, (char *)pat_patctl.replacement); - -/* Initialize for scanning the data line. */ - -#ifdef SUPPORT_PCRE2_8 -utf = ((((pat_patctl.control & CTL_POSIX) != 0)? - ((pcre2_real_code_8 *)preg.re_pcre2_code)->overall_options : - FLD(compiled_code, overall_options)) & PCRE2_UTF) != 0; -#else -utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; -#endif - -start_rep = NULL; -len = strlen((const char *)buffer); -while (len > 0 && isspace(buffer[len-1])) len--; -buffer[len] = 0; -p = buffer; -while (isspace(*p)) p++; - -/* Check that the data is well-formed UTF-8 if we're in UTF mode. To create -invalid input to pcre2_match(), you must use \x?? or \x{} sequences. */ - -if (utf) - { - uint8_t *q; - uint32_t cc; - int n = 1; - for (q = p; n > 0 && *q; q += n) n = utf82ord(q, &cc); - if (n <= 0) - { - fprintf(outfile, "** Failed: invalid UTF-8 string cannot be used as input " - "in UTF mode\n"); - return PR_OK; - } - } - -#ifdef SUPPORT_VALGRIND -/* Mark the dbuffer as addressable but undefined again. */ -if (dbuffer != NULL) - { - VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size); - } -#endif - -/* Allocate a buffer to hold the data line; len+1 is an upper bound on -the number of code units that will be needed (though the buffer may have to be -extended if replication is involved). */ - -needlen = (size_t)((len+1) * code_unit_size); -if (dbuffer == NULL || needlen >= dbuffer_size) - { - while (needlen >= dbuffer_size) dbuffer_size *= 2; - dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size); - if (dbuffer == NULL) - { - fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size); - exit(1); - } - } -SETCASTPTR(q, dbuffer); /* Sets q8, q16, or q32, as appropriate. */ - -/* Scan the data line, interpreting data escapes, and put the result into a -buffer of the appropriate width. In UTF mode, input can be UTF-8. */ - -while ((c = *p++) != 0) - { - int i = 0; - size_t replen; - - /* ] may mark the end of a replicated sequence */ - - if (c == ']' && start_rep != NULL) - { - size_t qoffset = CAST8VAR(q) - dbuffer; - size_t rep_offset = start_rep - dbuffer; - - if (*p++ != '{') - { - fprintf(outfile, "** Expected '{' after \\[....]\n"); - return PR_OK; - } - while (isdigit(*p)) i = i * 10 + *p++ - '0'; - if (*p++ != '}') - { - fprintf(outfile, "** Expected '}' after \\[...]{...\n"); - return PR_OK; - } - if (i-- == 0) - { - fprintf(outfile, "** Zero repeat not allowed\n"); - return PR_OK; - } - - replen = CAST8VAR(q) - start_rep; - needlen += replen * i; - - if (needlen >= dbuffer_size) - { - while (needlen >= dbuffer_size) dbuffer_size *= 2; - dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size); - if (dbuffer == NULL) - { - fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size); - exit(1); - } - SETCASTPTR(q, dbuffer + qoffset); - start_rep = dbuffer + rep_offset; - } - - while (i-- > 0) - { - memcpy(CAST8VAR(q), start_rep, replen); - SETPLUS(q, replen/code_unit_size); - } - - start_rep = NULL; - continue; - } - - /* Handle a non-escaped character */ - - if (c != '\\') - { - if (utf && HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); } - } - - /* Handle backslash escapes */ - - else switch ((c = *p++)) - { - case '\\': break; - case 'a': c = CHAR_BEL; break; - case 'b': c = '\b'; break; - case 'e': c = CHAR_ESC; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - c -= '0'; - while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') - c = c * 8 + *p++ - '0'; - break; - - case 'o': - if (*p == '{') - { - uint8_t *pt = p; - c = 0; - for (pt++; isdigit(*pt) && *pt != '8' && *pt != '9'; pt++) - { - if (++i == 12) - fprintf(outfile, "** Too many octal digits in \\o{...} item; " - "using only the first twelve.\n"); - else c = c * 8 + *pt - '0'; - } - if (*pt == '}') p = pt + 1; - else fprintf(outfile, "** Missing } after \\o{ (assumed)\n"); - } - break; - - case 'x': - if (*p == '{') - { - uint8_t *pt = p; - c = 0; - - /* We used to have "while (isxdigit(*(++pt)))" here, but it fails - when isxdigit() is a macro that refers to its argument more than - once. This is banned by the C Standard, but apparently happens in at - least one MacOS environment. */ - - for (pt++; isxdigit(*pt); pt++) - { - if (++i == 9) - fprintf(outfile, "** Too many hex digits in \\x{...} item; " - "using only the first eight.\n"); - else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10); - } - if (*pt == '}') - { - p = pt + 1; - break; - } - /* Not correct form for \x{...}; fall through */ - } - - /* \x without {} always defines just one byte in 8-bit mode. This - allows UTF-8 characters to be constructed byte by byte, and also allows - invalid UTF-8 sequences to be made. Just copy the byte in UTF-8 mode. - Otherwise, pass it down as data. */ - - c = 0; - while (i++ < 2 && isxdigit(*p)) - { - c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10); - p++; - } -#if defined SUPPORT_PCRE2_8 - if (utf && (test_mode == PCRE8_MODE)) - { - *q8++ = c; - continue; - } -#endif - break; - - case 0: /* \ followed by EOF allows for an empty line */ - p--; - continue; - - case '=': /* \= terminates the data, starts modifiers */ - goto ENDSTRING; - - case '[': /* \[ introduces a replicated character sequence */ - if (start_rep != NULL) - { - fprintf(outfile, "** Nested replication is not supported\n"); - return PR_OK; - } - start_rep = CAST8VAR(q); - continue; - - default: - if (isalnum(c)) - { - fprintf(outfile, "** Unrecognized escape sequence \"\\%c\"\n", c); - return PR_OK; - } - } - - /* We now have a character value in c that may be greater than 255. - In 8-bit mode we convert to UTF-8 if we are in UTF mode. Values greater - than 127 in UTF mode must have come from \x{...} or octal constructs - because values from \x.. get this far only in non-UTF mode. */ - -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) - { - if (utf) - { - if (c > 0x7fffffff) - { - fprintf(outfile, "** Character \\x{%x} is greater than 0x7fffffff " - "and so cannot be converted to UTF-8\n", c); - return PR_OK; - } - q8 += ord2utf8(c, q8); - } - else - { - if (c > 0xffu) - { - fprintf(outfile, "** Character \\x{%x} is greater than 255 " - "and UTF-8 mode is not enabled.\n", c); - fprintf(outfile, "** Truncation will probably give the wrong " - "result.\n"); - } - *q8++ = c; - } - } -#endif -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE) - { - if (utf) - { - if (c > 0x10ffffu) - { - fprintf(outfile, "** Failed: character \\x{%x} is greater than " - "0x10ffff and so cannot be converted to UTF-16\n", c); - return PR_OK; - } - else if (c >= 0x10000u) - { - c-= 0x10000u; - *q16++ = 0xD800 | (c >> 10); - *q16++ = 0xDC00 | (c & 0x3ff); - } - else - *q16++ = c; - } - else - { - if (c > 0xffffu) - { - fprintf(outfile, "** Character \\x{%x} is greater than 0xffff " - "and UTF-16 mode is not enabled.\n", c); - fprintf(outfile, "** Truncation will probably give the wrong " - "result.\n"); - } - - *q16++ = c; - } - } -#endif -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE) - { - *q32++ = c; - } -#endif - } - -ENDSTRING: -SET(*q, 0); -len = CASTVAR(uint8_t *, q) - dbuffer; /* Length in bytes */ -ulen = len/code_unit_size; /* Length in code units */ - -/* If the string was terminated by \= we must now interpret modifiers. */ - -if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl)) - return PR_OK; - -/* Check for mutually exclusive modifiers. At present, these are all in the -first control word. */ - -for (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++) - { - c = dat_datctl.control & exclusive_dat_controls[k]; - if (c != 0 && c != (c & (~c+1))) - { - show_controls(c, 0, "** Not allowed together:"); - fprintf(outfile, "\n"); - return PR_OK; - } - } - -if (pat_patctl.replacement[0] != 0 && - (dat_datctl.control & CTL_NULLCONTEXT) != 0) - { - fprintf(outfile, "** Replacement text is not supported with null_context.\n"); - return PR_OK; - } - -/* We now have the subject in dbuffer, with len containing the byte length, and -ulen containing the code unit length. Move the data to the end of the buffer so -that a read over the end can be caught by valgrind or other means. If we have -explicit valgrind support, mark the unused start of the buffer unaddressable. -If we are using the POSIX interface, or testing zero-termination, we must -include the terminating zero in the usable data. */ - -c = code_unit_size * (((pat_patctl.control & CTL_POSIX) + - (dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1:0); -pp = memmove(dbuffer + dbuffer_size - len - c, dbuffer, len + c); -#ifdef SUPPORT_VALGRIND - VALGRIND_MAKE_MEM_NOACCESS(dbuffer, dbuffer_size - (len + c)); -#endif - -/* Now pp points to the subject string. POSIX matching is only possible in -8-bit mode, and it does not support timing or other fancy features. Some were -checked at compile time, but we need to check the match-time settings here. */ - -#ifdef SUPPORT_PCRE2_8 -if ((pat_patctl.control & CTL_POSIX) != 0) - { - int rc; - int eflags = 0; - regmatch_t *pmatch = NULL; - const char *msg = "** Ignored with POSIX interface:"; - - if (dat_datctl.cfail[0] != CFAIL_UNSET || dat_datctl.cfail[1] != CFAIL_UNSET) - prmsg(&msg, "callout_fail"); - if (dat_datctl.copy_numbers[0] >= 0 || dat_datctl.copy_names[0] != 0) - prmsg(&msg, "copy"); - if (dat_datctl.get_numbers[0] >= 0 || dat_datctl.get_names[0] != 0) - prmsg(&msg, "get"); - if (dat_datctl.jitstack != 0) prmsg(&msg, "jitstack"); - - if ((dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS) != 0) - { - fprintf(outfile, "%s", msg); - show_match_options(dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS); - msg = ""; - } - if ((dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS) != 0 || - (dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2) != 0) - { - show_controls(dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS, - dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2, msg); - msg = ""; - } - - if (msg[0] == 0) fprintf(outfile, "\n"); - - if (dat_datctl.oveccount > 0) - pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount); - if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL; - if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL; - if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY; - - rc = regexec(&preg, (const char *)pp + dat_datctl.offset, - dat_datctl.oveccount, pmatch, eflags); - if (rc != 0) - { - (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size); - fprintf(outfile, "No match: POSIX code %d: %s\n", rc, pbuffer8); - } - else if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) - fprintf(outfile, "Matched with REG_NOSUB\n"); - else if (dat_datctl.oveccount == 0) - fprintf(outfile, "Matched without capture\n"); - else - { - size_t i; - for (i = 0; i < (size_t)dat_datctl.oveccount; i++) - { - if (pmatch[i].rm_so >= 0) - { - fprintf(outfile, "%2d: ", (int)i); - PCHARSV(pp, pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so, utf, outfile); - fprintf(outfile, "\n"); - if ((i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0) || - (dat_datctl.control & CTL_ALLAFTERTEXT) != 0) - { - fprintf(outfile, "%2d+ ", (int)i); - PCHARSV(pp, pmatch[i].rm_eo, len - pmatch[i].rm_eo, - utf, outfile); - fprintf(outfile, "\n"); - } - } - } - } - free(pmatch); - return PR_OK; - } -#endif /* SUPPORT_PCRE2_8 */ - - /* Handle matching via the native interface. Check for consistency of -modifiers. */ - -if ((dat_datctl.control & (CTL_DFA|CTL_FINDLIMITS)) == (CTL_DFA|CTL_FINDLIMITS)) - { - fprintf(outfile, "** Finding match limits is not relevant for DFA matching: ignored\n"); - dat_datctl.control &= ~CTL_FINDLIMITS; - } - -/* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA -matching, even if the JIT compiler was used. */ - -if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT && - FLD(compiled_code, executable_jit) != NULL) - { - fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n"); - dat_datctl.control &= ~CTL_ALLUSEDTEXT; - } - -/* Handle passing the subject as zero-terminated. */ - -if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0) - ulen = PCRE2_ZERO_TERMINATED; - -/* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a -NULL context. */ - -use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)? - NULL : PTR(dat_context); - -/* Enable display of malloc/free if wanted. */ - -show_memory = (dat_datctl.control & CTL_MEMORY) != 0; - -/* Create and assign a JIT stack if requested. */ - -if (dat_datctl.jitstack != 0) - { - if (dat_datctl.jitstack != jit_stack_size) - { - PCRE2_JIT_STACK_FREE(jit_stack); - PCRE2_JIT_STACK_CREATE(jit_stack, 1, dat_datctl.jitstack * 1024, NULL); - jit_stack_size = dat_datctl.jitstack; - } - PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, jit_stack); - } - -/* Or de-assign */ - -else if (jit_stack != NULL) - { - PCRE2_JIT_STACK_ASSIGN(dat_context, NULL, NULL); - PCRE2_JIT_STACK_FREE(jit_stack); - jit_stack = NULL; - jit_stack_size = 0; - } - -/* When no JIT stack is assigned, we must ensure that there is a JIT callback -if we want to verify that JIT was actually used. */ - -if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL) - { - PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, NULL); - } - -/* Adjust match_data according to size of offsets required. A size of zero -causes a new match data block to be obtained that exactly fits the pattern. */ - -if (dat_datctl.oveccount == 0) - { - PCRE2_MATCH_DATA_FREE(match_data); - PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(match_data, compiled_code, NULL); - PCRE2_GET_OVECTOR_COUNT(max_oveccount, match_data); - } -else if (dat_datctl.oveccount <= max_oveccount) - { - SETFLD(match_data, oveccount, dat_datctl.oveccount); - } -else - { - max_oveccount = dat_datctl.oveccount; - PCRE2_MATCH_DATA_FREE(match_data); - PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, NULL); - } - -/* Replacement processing is ignored for DFA matching. */ - -if (dat_datctl.replacement[0] != 0 && (dat_datctl.control & CTL_DFA) != 0) - { - fprintf(outfile, "** Ignored for DFA matching: replace\n"); - dat_datctl.replacement[0] = 0; - } - -/* If a replacement string is provided, call pcre2_substitute() instead of one -of the matching functions. First we have to convert the replacement string to -the appropriate width. */ - -if (dat_datctl.replacement[0] != 0) - { - int rc; - uint8_t *pr; - uint8_t rbuffer[REPLACE_BUFFSIZE]; - uint8_t nbuffer[REPLACE_BUFFSIZE]; - uint32_t xoptions; - PCRE2_SIZE rlen, nsize, erroroffset; - BOOL badutf = FALSE; - -#ifdef SUPPORT_PCRE2_8 - uint8_t *r8 = NULL; -#endif -#ifdef SUPPORT_PCRE2_16 - uint16_t *r16 = NULL; -#endif -#ifdef SUPPORT_PCRE2_32 - uint32_t *r32 = NULL; -#endif - - if (timeitm) - fprintf(outfile, "** Timing is not supported with replace: ignored\n"); - - xoptions = (((dat_datctl.control & CTL_GLOBAL) == 0)? 0 : - PCRE2_SUBSTITUTE_GLOBAL) | - (((dat_datctl.control2 & CTL2_SUBSTITUTE_EXTENDED) == 0)? 0 : - PCRE2_SUBSTITUTE_EXTENDED) | - (((dat_datctl.control2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) == 0)? 0 : - PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) | - (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) == 0)? 0 : - PCRE2_SUBSTITUTE_UNKNOWN_UNSET) | - (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNSET_EMPTY) == 0)? 0 : - PCRE2_SUBSTITUTE_UNSET_EMPTY); - - SETCASTPTR(r, rbuffer); /* Sets r8, r16, or r32, as appropriate. */ - pr = dat_datctl.replacement; - - /* If the replacement starts with '[]' we interpret that as length - value for the replacement buffer. */ - - nsize = REPLACE_BUFFSIZE/code_unit_size; - if (*pr == '[') - { - PCRE2_SIZE n = 0; - while ((c = *(++pr)) >= CHAR_0 && c <= CHAR_9) n = n * 10 + c - CHAR_0; - if (*pr++ != ']') - { - fprintf(outfile, "Bad buffer size in replacement string\n"); - return PR_OK; - } - if (n > nsize) - { - fprintf(outfile, "Replacement buffer setting (%lu) is too large " - "(max %lu)\n", (unsigned long int)n, (unsigned long int)nsize); - return PR_OK; - } - nsize = n; - } - - /* Now copy the replacement string to a buffer of the appropriate width. No - escape processing is done for replacements. In UTF mode, check for an invalid - UTF-8 input string, and if it is invalid, just copy its code units without - UTF interpretation. This provides a means of checking that an invalid string - is detected. Otherwise, UTF-8 can be used to include wide characters in a - replacement. */ - - if (utf) badutf = valid_utf(pr, strlen((const char *)pr), &erroroffset); - - /* Not UTF or invalid UTF-8: just copy the code units. */ - - if (!utf || badutf) - { - while ((c = *pr++) != 0) - { -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) *r8++ = c; -#endif -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE) *r16++ = c; -#endif -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE) *r32++ = c; -#endif - } - } - - /* Valid UTF-8 replacement string */ - - else while ((c = *pr++) != 0) - { - if (HASUTF8EXTRALEN(c)) { GETUTF8INC(c, pr); } - -#ifdef SUPPORT_PCRE2_8 - if (test_mode == PCRE8_MODE) r8 += ord2utf8(c, r8); -#endif - -#ifdef SUPPORT_PCRE2_16 - if (test_mode == PCRE16_MODE) - { - if (c >= 0x10000u) - { - c-= 0x10000u; - *r16++ = 0xD800 | (c >> 10); - *r16++ = 0xDC00 | (c & 0x3ff); - } - else *r16++ = c; - } -#endif - -#ifdef SUPPORT_PCRE2_32 - if (test_mode == PCRE32_MODE) *r32++ = c; -#endif - } - - SET(*r, 0); - if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0) - rlen = PCRE2_ZERO_TERMINATED; - else - rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size; - PCRE2_SUBSTITUTE(rc, compiled_code, pp, ulen, dat_datctl.offset, - dat_datctl.options|xoptions, match_data, dat_context, - rbuffer, rlen, nbuffer, &nsize); - - if (rc < 0) - { - PCRE2_SIZE msize; - fprintf(outfile, "Failed: error %d", rc); - if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET) - fprintf(outfile, " at offset %ld in replacement", (long int)nsize); - fprintf(outfile, ": "); - PCRE2_GET_ERROR_MESSAGE(msize, rc, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, msize, FALSE, outfile); - if (rc == PCRE2_ERROR_NOMEMORY && - (xoptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0) - fprintf(outfile, ": %ld code units are needed", (long int)nsize); - } - else - { - fprintf(outfile, "%2d: ", rc); - PCHARSV(nbuffer, 0, nsize, utf, outfile); - } - - fprintf(outfile, "\n"); - } /* End of substitution handling */ - -/* When a replacement string is not provided, run a loop for global matching -with one of the basic matching functions. */ - -else for (gmatched = 0;; gmatched++) - { - PCRE2_SIZE j; - int capcount; - PCRE2_SIZE *ovector; - PCRE2_SIZE ovecsave[2]; - - ovector = FLD(match_data, ovector); - - /* After the first time round a global loop, for a normal global (/g) - iteration, save the current ovector[0,1] so that we can check that they do - change each time. Otherwise a matching bug that returns the same string - causes an infinite loop. It has happened! */ - - if (gmatched > 0 && (dat_datctl.control & CTL_GLOBAL) != 0) - { - ovecsave[0] = ovector[0]; - ovecsave[1] = ovector[1]; - } - - /* For altglobal (or first time round the loop), set an "unset" value. */ - - else ovecsave[0] = ovecsave[1] = PCRE2_UNSET; - - /* Fill the ovector with junk to detect elements that do not get set - when they should be. */ - - for (j = 0; j < 2*dat_datctl.oveccount; j++) ovector[j] = JUNK_OFFSET; - - /* When matching is via pcre2_match(), we will detect the use of JIT via the - stack callback function. */ - - jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0; - - /* Do timing if required. */ - - if (timeitm > 0) - { - register int i; - clock_t start_time, time_taken; - - if ((dat_datctl.control & CTL_DFA) != 0) - { - if ((dat_datctl.options & PCRE2_DFA_RESTART) != 0) - { - fprintf(outfile, "Timing DFA restarts is not supported\n"); - return PR_OK; - } - if (dfa_workspace == NULL) - dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); - start_time = clock(); - for (i = 0; i < timeitm; i++) - { - PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, - dat_datctl.offset, dat_datctl.options | g_notempty, match_data, - use_dat_context, dfa_workspace, DFA_WS_DIMENSION); - } - } - - else if ((pat_patctl.control & CTL_JITFAST) != 0) - { - start_time = clock(); - for (i = 0; i < timeitm; i++) - { - PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, - dat_datctl.offset, dat_datctl.options | g_notempty, match_data, - use_dat_context); - } - } - - else - { - start_time = clock(); - for (i = 0; i < timeitm; i++) - { - PCRE2_MATCH(capcount, compiled_code, pp, ulen, - dat_datctl.offset, dat_datctl.options | g_notempty, match_data, - use_dat_context); - } - } - total_match_time += (time_taken = clock() - start_time); - fprintf(outfile, "Match time %.4f milliseconds\n", - (((double)time_taken * 1000.0) / (double)timeitm) / - (double)CLOCKS_PER_SEC); - } - - /* Find the match and recursion limits if requested. The recursion limit - is not relevant for JIT. */ - - if ((dat_datctl.control & CTL_FINDLIMITS) != 0) - { - capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match"); - if (FLD(compiled_code, executable_jit) == NULL) - (void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, - "recursion"); - } - - /* Otherwise just run a single match, setting up a callout if required (the - default). */ - - else - { - if ((dat_datctl.control & CTL_CALLOUT_NONE) == 0) - { - PCRE2_SET_CALLOUT(dat_context, callout_function, - (void *)(&dat_datctl.callout_data)); - first_callout = TRUE; - last_callout_mark = NULL; - callout_count = 0; - } - else - { - PCRE2_SET_CALLOUT(dat_context, NULL, NULL); /* No callout */ - } - - /* Run a single DFA or NFA match. */ - - if ((dat_datctl.control & CTL_DFA) != 0) - { - if (dfa_workspace == NULL) - dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); - if (dfa_matched++ == 0) - dfa_workspace[0] = -1; /* To catch bad restart */ - PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, - dat_datctl.offset, dat_datctl.options | g_notempty, match_data, - use_dat_context, dfa_workspace, DFA_WS_DIMENSION); - if (capcount == 0) - { - fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n"); - capcount = dat_datctl.oveccount; - } - } - else - { - if ((pat_patctl.control & CTL_JITFAST) != 0) - PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, - dat_datctl.options | g_notempty, match_data, use_dat_context); - else - PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset, - dat_datctl.options | g_notempty, match_data, use_dat_context); - if (capcount == 0) - { - fprintf(outfile, "Matched, but too many substrings\n"); - capcount = dat_datctl.oveccount; - } - } - } - - /* The result of the match is now in capcount. First handle a successful - match. */ - - if (capcount >= 0) - { - int i; - uint32_t oveccount; - - /* This is a check against a lunatic return value. */ - - PCRE2_GET_OVECTOR_COUNT(oveccount, match_data); - if (capcount > (int)oveccount) - { - fprintf(outfile, - "** PCRE2 error: returned count %d is too big for ovector count %d\n", - capcount, oveccount); - capcount = oveccount; - if ((dat_datctl.control & CTL_ANYGLOB) != 0) - { - fprintf(outfile, "** Global loop abandoned\n"); - dat_datctl.control &= ~CTL_ANYGLOB; /* Break g/G loop */ - } - } - - /* If this is not the first time round a global loop, check that the - returned string has changed. If not, there is a bug somewhere and we must - break the loop because it will go on for ever. We know that there are - always at least two elements in the ovector. */ - - if (gmatched > 0 && ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1]) - { - fprintf(outfile, - "** PCRE2 error: global repeat returned the same string as previous\n"); - fprintf(outfile, "** Global loop abandoned\n"); - dat_datctl.control &= ~CTL_ANYGLOB; /* Break g/G loop */ - } - - /* "allcaptures" requests showing of all captures in the pattern, to check - unset ones at the end. It may be set on the pattern or the data. Implement - by setting capcount to the maximum. */ - - if ((dat_datctl.control & CTL_ALLCAPTURES) != 0) - { - uint32_t maxcapcount; - if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0) - return PR_SKIP; - capcount = maxcapcount + 1; /* Allow for full match */ - if (capcount > (int)oveccount) capcount = oveccount; - } - - /* Output the captured substrings. Note that, for the matched string, - the use of \K in an assertion can make the start later than the end. */ - - for (i = 0; i < 2*capcount; i += 2) - { - PCRE2_SIZE lleft, lmiddle, lright; - PCRE2_SIZE start = ovector[i]; - PCRE2_SIZE end = ovector[i+1]; - - if (start > end) - { - start = ovector[i+1]; - end = ovector[i]; - fprintf(outfile, "Start of matched string is beyond its end - " - "displaying from end to start.\n"); - } - - fprintf(outfile, "%2d: ", i/2); - - /* Check for an unset group */ - - if (start == PCRE2_UNSET) - { - fprintf(outfile, "\n"); - continue; - } - - /* Check for silly offsets, in particular, values that have not been - set when they should have been. */ - - if (start > ulen || end > ulen) - { - fprintf(outfile, "ERROR: bad value(s) for offset(s): 0x%lx 0x%lx\n", - (unsigned long int)start, (unsigned long int)end); - continue; - } - - /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with - JIT, it is disabled above, with a comment.) When the match is done by the - interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is - set, and if the leftmost consulted character is before the start of the - match or the rightmost consulted character is past the end of the match, - we want to show all consulted characters for the main matched string, and - indicate which were lookarounds. */ - - if (i == 0) - { - BOOL showallused; - PCRE2_SIZE leftchar, rightchar; - - if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0) - { - leftchar = FLD(match_data, leftchar); - rightchar = FLD(match_data, rightchar); - showallused = i == 0 && (leftchar < start || rightchar > end); - } - else showallused = FALSE; - - if (showallused) - { - PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile); - PCHARS(lmiddle, pp, start, end - start, utf, outfile); - PCHARS(lright, pp, end, rightchar - end, utf, outfile); - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); - fprintf(outfile, "\n "); - for (j = 0; j < lleft; j++) fprintf(outfile, "<"); - for (j = 0; j < lmiddle; j++) fprintf(outfile, " "); - for (j = 0; j < lright; j++) fprintf(outfile, ">"); - } - - /* When a pattern contains \K, the start of match position may be - different to the start of the matched string. When this is the case, - show it when requested. */ - - else if ((dat_datctl.control & CTL_STARTCHAR) != 0) - { - PCRE2_SIZE startchar; - PCRE2_GET_STARTCHAR(startchar, match_data); - PCHARS(lleft, pp, startchar, start - startchar, utf, outfile); - PCHARSV(pp, start, end - start, utf, outfile); - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); - if (startchar != start) - { - fprintf(outfile, "\n "); - for (j = 0; j < lleft; j++) fprintf(outfile, "^"); - } - } - - /* Otherwise, just show the matched string. */ - - else - { - PCHARSV(pp, start, end - start, utf, outfile); - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); - } - } - - /* Not the main matched string. Just show it unadorned. */ - - else - { - PCHARSV(pp, start, end - start, utf, outfile); - } - - fprintf(outfile, "\n"); - - /* Note: don't use the start/end variables here because we want to - show the text from what is reported as the end. */ - - if ((dat_datctl.control & CTL_ALLAFTERTEXT) != 0 || - (i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0)) - { - fprintf(outfile, "%2d+ ", i/2); - PCHARSV(pp, ovector[i+1], ulen - ovector[i+1], utf, outfile); - fprintf(outfile, "\n"); - } - } - - /* Output (*MARK) data if requested */ - - if ((dat_datctl.control & CTL_MARK) != 0 && - TESTFLD(match_data, mark, !=, NULL)) - { - fprintf(outfile, "MK: "); - PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); - fprintf(outfile, "\n"); - } - - /* Process copy/get strings */ - - copy_and_get(utf, capcount); - - } /* End of handling a successful match */ - - /* There was a partial match. The value of ovector[0] is the bumpalong point, - that is, startchar, not any \K point that might have been passed. */ - - else if (capcount == PCRE2_ERROR_PARTIAL) - { - PCRE2_SIZE poffset; - int backlength; - int rubriclength = 0; - - fprintf(outfile, "Partial match"); - if ((dat_datctl.control & CTL_MARK) != 0 && - TESTFLD(match_data, mark, !=, NULL)) - { - fprintf(outfile, ", mark="); - PCHARS(rubriclength, CASTFLD(void *, match_data, mark), 0, -1, utf, - outfile); - rubriclength += 7; - } - fprintf(outfile, ": "); - rubriclength += 15; - - poffset = backchars(pp, ovector[0], maxlookbehind, utf); - PCHARS(backlength, pp, poffset, ovector[0] - poffset, utf, outfile); - PCHARSV(pp, ovector[0], ulen - ovector[0], utf, outfile); - - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); - fprintf(outfile, "\n"); - - if (backlength != 0) - { - int i; - for (i = 0; i < rubriclength; i++) fprintf(outfile, " "); - for (i = 0; i < backlength; i++) fprintf(outfile, "<"); - fprintf(outfile, "\n"); - } - - /* Process copy/get strings */ - - copy_and_get(utf, 1); - - break; /* Out of the /g loop */ - } /* End of handling partial match */ - - /* Failed to match. If this is a /g or /G loop, we might previously have - set g_notempty (to PCRE2_NOTEMPTY_ATSTART|PCRE2_ANCHORED) after a null match. - If that is the case, this is not necessarily the end. We want to advance the - start offset, and continue. We won't be at the end of the string - that was - checked before setting g_notempty. We achieve the effect by pretending that a - single character was matched. - - Complication arises in the case when the newline convention is "any", "crlf", - or "anycrlf". If the previous match was at the end of a line terminated by - CRLF, an advance of one character just passes the CR, whereas we should - prefer the longer newline sequence, as does the code in pcre2_match(). - - Otherwise, in the case of UTF-8 or UTF-16 matching, the advance must be one - character, not one byte. */ - - else if (g_notempty != 0) /* There was a previous null match */ - { - uint16_t nl = FLD(compiled_code, newline_convention); - PCRE2_SIZE start_offset = dat_datctl.offset; /* Where the match was */ - PCRE2_SIZE end_offset = start_offset + 1; - - if ((nl == PCRE2_NEWLINE_CRLF || nl == PCRE2_NEWLINE_ANY || - nl == PCRE2_NEWLINE_ANYCRLF) && - start_offset < ulen - 1 && - CODE_UNIT(pp, start_offset) == '\r' && - CODE_UNIT(pp, end_offset) == '\n') - end_offset++; - - else if (utf && test_mode != PCRE32_MODE) - { - if (test_mode == PCRE8_MODE) - { - for (; end_offset < ulen; end_offset++) - if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break; - } - else /* 16-bit mode */ - { - for (; end_offset < ulen; end_offset++) - if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break; - } - } - - SETFLDVEC(match_data, ovector, 0, start_offset); - SETFLDVEC(match_data, ovector, 1, end_offset); - } /* End of handling null match in a global loop */ - - /* A "normal" match failure. There will be a negative error number in - capcount. */ - - else - { - int mlen; - - switch(capcount) - { - case PCRE2_ERROR_NOMATCH: - if (gmatched == 0) - { - fprintf(outfile, "No match"); - if ((dat_datctl.control & CTL_MARK) != 0 && - TESTFLD(match_data, mark, !=, NULL)) - { - fprintf(outfile, ", mark = "); - PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); - } - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); - fprintf(outfile, "\n"); - } - break; - - case PCRE2_ERROR_BADUTFOFFSET: - fprintf(outfile, "Error %d (bad UTF-%d offset)\n", capcount, test_mode); - break; - - default: - fprintf(outfile, "Failed: error %d: ", capcount); - PCRE2_GET_ERROR_MESSAGE(mlen, capcount, pbuffer); - PCHARSV(CASTVAR(void *, pbuffer), 0, mlen, FALSE, outfile); - if (capcount <= PCRE2_ERROR_UTF8_ERR1 && - capcount >= PCRE2_ERROR_UTF32_ERR2) - { - PCRE2_SIZE startchar; - PCRE2_GET_STARTCHAR(startchar, match_data); - fprintf(outfile, " at offset %lu", (unsigned long int)startchar); - } - fprintf(outfile, "\n"); - break; - } - - break; /* Out of the /g loop */ - } /* End of failed match handling */ - - /* Control reaches here in two circumstances: (a) after a match, and (b) - after a non-match that immediately followed a match on an empty string when - doing a global search. Such a match is done with PCRE2_NOTEMPTY_ATSTART and - PCRE2_ANCHORED set in g_notempty. The code above turns it into a fake match - of one character. So effectively we get here only after a match. If we - are not doing a global search, we are done. */ - - if ((dat_datctl.control & CTL_ANYGLOB) == 0) break; else - { - PCRE2_SIZE end_offset = FLD(match_data, ovector)[1]; - - /* We must now set up for the next iteration of a global search. If we have - matched an empty string, first check to see if we are at the end of the - subject. If so, the loop is over. Otherwise, mimic what Perl's /g option - does. Set PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED and try the match again - at the same point. If this fails it will be picked up above, where a fake - match is set up so that at this point we advance to the next character. */ - - if (FLD(match_data, ovector)[0] == end_offset) - { - if (end_offset == ulen) break; /* End of subject */ - g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; - } - - /* However, even after matching a non-empty string, there is still one - tricky case. If a pattern contains \K within a lookbehind assertion at the - start, the end of the matched string can be at the offset where the match - started. In the case of a normal /g iteration without special action, this - leads to a loop that keeps on returning the same substring. The loop would - be caught above, but we really want to move on to the next match. */ - - else - { - g_notempty = 0; /* Set for a "normal" repeat */ - if ((dat_datctl.control & CTL_GLOBAL) != 0) - { - PCRE2_SIZE startchar; - PCRE2_GET_STARTCHAR(startchar, match_data); - if (end_offset <= startchar) - { - if (startchar >= ulen) break; /* End of subject */ - end_offset = startchar + 1; - if (utf && test_mode != PCRE32_MODE) - { - if (test_mode == PCRE8_MODE) - { - for (; end_offset < ulen; end_offset++) - if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break; - } - else /* 16-bit mode */ - { - for (; end_offset < ulen; end_offset++) - if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break; - } - } - } - } - } - - /* For /g (global), update the start offset, leaving the rest alone. */ - - if ((dat_datctl.control & CTL_GLOBAL) != 0) - dat_datctl.offset = end_offset; - - /* For altglobal, just update the pointer and length. */ - - else - { - pp += end_offset * code_unit_size; - len -= end_offset * code_unit_size; - ulen -= end_offset; - } - } - } /* End of global loop */ - -show_memory = FALSE; -return PR_OK; -} - - - - -/************************************************* -* Print PCRE2 version * -*************************************************/ - -static void -print_version(FILE *f) -{ -VERSION_TYPE *vp; -fprintf(f, "PCRE2 version "); -for (vp = version; *vp != 0; vp++) fprintf(f, "%c", *vp); -fprintf(f, "\n"); -} - - - -/************************************************* -* Print Unicode version * -*************************************************/ - -static void -print_unicode_version(FILE *f) -{ -VERSION_TYPE *vp; -fprintf(f, "Unicode version "); -for (vp = uversion; *vp != 0; vp++) fprintf(f, "%c", *vp); -} - - - -/************************************************* -* Print JIT target * -*************************************************/ - -static void -print_jit_target(FILE *f) -{ -VERSION_TYPE *vp; -for (vp = jittarget; *vp != 0; vp++) fprintf(f, "%c", *vp); -} - - - -/************************************************* -* Print newline configuration * -*************************************************/ - -/* Output is always to stdout. - -Arguments: - rc the return code from PCRE2_CONFIG_NEWLINE - isc TRUE if called from "-C newline" -Returns: nothing -*/ - -static void -print_newline_config(uint32_t optval, BOOL isc) -{ -if (!isc) printf(" Newline sequence is "); -if (optval < sizeof(newlines)/sizeof(char *)) - printf("%s\n", newlines[optval]); -else - printf("a non-standard value: %d\n", optval); -} - - - -/************************************************* -* Usage function * -*************************************************/ - -static void -usage(void) -{ -printf("Usage: pcre2test [options] [ []]\n\n"); -printf("Input and output default to stdin and stdout.\n"); -#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) -printf("If input is a terminal, readline() is used to read from it.\n"); -#else -printf("This version of pcre2test is not linked with readline().\n"); -#endif -printf("\nOptions:\n"); -#ifdef SUPPORT_PCRE2_8 -printf(" -8 use the 8-bit library\n"); -#endif -#ifdef SUPPORT_PCRE2_16 -printf(" -16 use the 16-bit library\n"); -#endif -#ifdef SUPPORT_PCRE2_32 -printf(" -32 use the 32-bit library\n"); -#endif -printf(" -b set default pattern control 'fullbincode'\n"); -printf(" -C show PCRE2 compile-time options and exit\n"); -printf(" -C arg show a specific compile-time option and exit with its\n"); -printf(" value if numeric (else 0). The arg can be:\n"); -printf(" backslash-C use of \\C is enabled [0, 1]\n"); -printf(" bsr \\R type [ANYCRLF, ANY]\n"); -printf(" ebcdic compiled for EBCDIC character code [0,1]\n"); -printf(" ebcdic-nl NL code if compiled for EBCDIC\n"); -printf(" jit just-in-time compiler supported [0, 1]\n"); -printf(" linksize internal link size [2, 3, 4]\n"); -printf(" newline newline type [CR, LF, CRLF, ANYCRLF, ANY]\n"); -printf(" pcre2-8 8 bit library support enabled [0, 1]\n"); -printf(" pcre2-16 16 bit library support enabled [0, 1]\n"); -printf(" pcre2-32 32 bit library support enabled [0, 1]\n"); -printf(" unicode Unicode and UTF support enabled [0, 1]\n"); -printf(" -d set default pattern control 'debug'\n"); -printf(" -dfa set default subject control 'dfa'\n"); -printf(" -help show usage information\n"); -printf(" -i set default pattern control 'info'\n"); -printf(" -jit set default pattern control 'jit'\n"); -printf(" -q quiet: do not output PCRE2 version number at start\n"); -printf(" -pattern set default pattern control fields\n"); -printf(" -subject set default subject control fields\n"); -printf(" -S set stack size to megabytes\n"); -printf(" -t [] time compilation and execution, repeating times\n"); -printf(" -tm [] time execution (matching) only, repeating times\n"); -printf(" -T same as -t, but show total times at the end\n"); -printf(" -TM same as -tm, but show total time at the end\n"); -printf(" -version show PCRE2 version and exit\n"); -} - - - -/************************************************* -* Handle -C option * -*************************************************/ - -/* This option outputs configuration options and sets an appropriate return -code when asked for a single option. The code is abstracted into a separate -function because of its size. Use whichever pcre2_config() function is -available. - -Argument: an option name or NULL -Returns: the return code -*/ - -static int -c_option(const char *arg) -{ -uint32_t optval; -int yield = 0; - -if (arg != NULL) - { - unsigned int i; - - for (i = 0; i < COPTLISTCOUNT; i++) - if (strcmp(arg, coptlist[i].name) == 0) break; - - if (i >= COPTLISTCOUNT) - { - fprintf(stderr, "** Unknown -C option '%s'\n", arg); - return -1; - } - - switch (coptlist[i].type) - { - case CONF_BSR: - (void)PCRE2_CONFIG(coptlist[i].value, &optval); - printf("%s\n", optval? "ANYCRLF" : "ANY"); - break; - - case CONF_FIX: - yield = coptlist[i].value; - printf("%d\n", yield); - break; - - case CONF_FIZ: - optval = coptlist[i].value; - printf("%d\n", optval); - break; - - case CONF_INT: - (void)PCRE2_CONFIG(coptlist[i].value, &yield); - printf("%d\n", yield); - break; - - case CONF_NL: - (void)PCRE2_CONFIG(coptlist[i].value, &optval); - print_newline_config(optval, TRUE); - break; - } - -/* For VMS, return the value by setting a symbol, for certain values only. */ - -#ifdef __VMS - if (copytlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT) - { - char ucname[16]; - strcpy(ucname, coptlist[i].name); - for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i]; - vms_setsymbol(ucname, 0, optval); - } -#endif - - return yield; - } - -/* No argument for -C: output all configuration information. */ - -print_version(stdout); -printf("Compiled with\n"); - -#ifdef EBCDIC -printf(" EBCDIC code support: LF is 0x%02x\n", CHAR_LF); -#if defined NATIVE_ZOS -printf(" EBCDIC code page %s or similar\n", pcrz_cpversion()); -#endif -#endif - -#ifdef SUPPORT_PCRE2_8 -printf(" 8-bit support\n"); -#endif -#ifdef SUPPORT_PCRE2_16 -printf(" 16-bit support\n"); -#endif -#ifdef SUPPORT_PCRE2_32 -printf(" 32-bit support\n"); -#endif - -(void)PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, &optval); -if (optval != 0) - { - printf(" UTF and UCP support ("); - print_unicode_version(stdout); - printf(")\n"); - } -else printf(" No Unicode support\n"); - -(void)PCRE2_CONFIG(PCRE2_CONFIG_JIT, &optval); -if (optval != 0) - { - printf(" Just-in-time compiler support: "); - print_jit_target(stdout); - printf("\n"); - } -else - { - printf(" No just-in-time compiler support\n"); - } - -(void)PCRE2_CONFIG(PCRE2_CONFIG_NEWLINE, &optval); -print_newline_config(optval, FALSE); -(void)PCRE2_CONFIG(PCRE2_CONFIG_BSR, &optval); -printf(" \\R matches %s\n", optval? "CR, LF, or CRLF only" : - "all Unicode newlines"); -#ifdef NEVER_BACKSLASH_C -printf(" \\C is not supported\n"); -#else -printf(" \\C is supported\n"); -#endif -(void)PCRE2_CONFIG(PCRE2_CONFIG_LINKSIZE, &optval); -printf(" Internal link size = %d\n", optval); -(void)PCRE2_CONFIG(PCRE2_CONFIG_PARENSLIMIT, &optval); -printf(" Parentheses nest limit = %d\n", optval); -(void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval); -printf(" Default match limit = %d\n", optval); -(void)PCRE2_CONFIG(PCRE2_CONFIG_RECURSIONLIMIT, &optval); -printf(" Default recursion depth limit = %d\n", optval); -(void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &optval); -printf(" Match recursion uses %s", optval? "stack" : "heap"); - -printf("\n"); -return 0; -} - - - -/************************************************* -* Main Program * -*************************************************/ - -int -main(int argc, char **argv) -{ -uint32_t yield = 0; -uint32_t op = 1; -uint32_t stack_size; -BOOL notdone = TRUE; -BOOL quiet = FALSE; -BOOL showtotaltimes = FALSE; -BOOL skipping = FALSE; -char *arg_subject = NULL; -char *arg_pattern = NULL; - -/* The offsets to the options and control bits fields of the pattern and data -control blocks must be the same so that common options and controls such as -"anchored" or "memory" can work for either of them from a single table entry. -We cannot test this till runtime because "offsetof" does not work in the -preprocessor. */ - -if (PO(options) != DO(options) || PO(control) != DO(control) || - PO(control2) != DO(control2)) - { - fprintf(stderr, "** Coding error: " - "options and control offsets for pattern and data must be the same.\n"); - return 1; - } - -/* Get the PCRE2 and Unicode version number and JIT target information, at the -same time checking that a request for the length gives the same answer. Also -check lengths for non-string items. */ - -if (PCRE2_CONFIG(PCRE2_CONFIG_VERSION, NULL) != - PCRE2_CONFIG(PCRE2_CONFIG_VERSION, version) || - - PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, NULL) != - PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, uversion) || - - PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, NULL) != - PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, jittarget) || - - PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, NULL) != sizeof(uint32_t) || - PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, NULL) != sizeof(uint32_t)) - { - fprintf(stderr, "** Error in pcre2_config(): bad length\n"); - return 1; - } - -/* Get buffers from malloc() so that valgrind will check their misuse when -debugging. They grow automatically when very long lines are read. The 16- -and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */ - -buffer = (uint8_t *)malloc(pbuffer8_size); -pbuffer8 = (uint8_t *)malloc(pbuffer8_size); - -/* The following _setmode() stuff is some Windows magic that tells its runtime -library to translate CRLF into a single LF character. At least, that's what -I've been told: never having used Windows I take this all on trust. Originally -it set 0x8000, but then I was advised that _O_BINARY was better. */ - -#if defined(_WIN32) || defined(WIN32) -_setmode( _fileno( stdout ), _O_BINARY ); -#endif - -/* Initialization that does not depend on the running mode. */ - -locale_name[0] = 0; -memset(&def_patctl, 0, sizeof(patctl)); -memset(&def_datctl, 0, sizeof(datctl)); -def_datctl.oveccount = DEFAULT_OVECCOUNT; -def_datctl.copy_numbers[0] = -1; -def_datctl.get_numbers[0] = -1; -def_datctl.cfail[0] = def_datctl.cfail[1] = CFAIL_UNSET; - -/* Scan command line options. */ - -while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) - { - char *endptr; - char *arg = argv[op]; - unsigned long uli; - - /* Display and/or set return code for configuration options. */ - - if (strcmp(arg, "-C") == 0) - { - yield = c_option(argv[op + 1]); - goto EXIT; - } - - /* Select operating mode */ - - if (strcmp(arg, "-8") == 0) - { -#ifdef SUPPORT_PCRE2_8 - test_mode = PCRE8_MODE; -#else - fprintf(stderr, - "** This version of PCRE2 was built without 8-bit support\n"); - exit(1); -#endif - } - else if (strcmp(arg, "-16") == 0) - { -#ifdef SUPPORT_PCRE2_16 - test_mode = PCRE16_MODE; -#else - fprintf(stderr, - "** This version of PCRE2 was built without 16-bit support\n"); - exit(1); -#endif - } - else if (strcmp(arg, "-32") == 0) - { -#ifdef SUPPORT_PCRE2_32 - test_mode = PCRE32_MODE; -#else - fprintf(stderr, - "** This version of PCRE2 was built without 32-bit support\n"); - exit(1); -#endif - } - - /* Set quiet (no version verification) */ - - else if (strcmp(arg, "-q") == 0) quiet = TRUE; - - /* Set system stack size */ - - else if (strcmp(arg, "-S") == 0 && argc > 2 && - ((uli = strtoul(argv[op+1], &endptr, 10)), *endptr == 0)) - { -#if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS) || defined(__VMS) - fprintf(stderr, "pcre2test: -S is not supported on this OS\n"); - exit(1); -#else - int rc; - struct rlimit rlim; - if (U32OVERFLOW(uli)) - { - fprintf(stderr, "+++ Argument for -S is too big\n"); - exit(1); - } - stack_size = (uint32_t)uli; - getrlimit(RLIMIT_STACK, &rlim); - rlim.rlim_cur = stack_size * 1024 * 1024; - if (rlim.rlim_cur > rlim.rlim_max) - { - fprintf(stderr, - "pcre2test: requested stack size %luM is greater than hard limit %lu\n", - (unsigned long int)stack_size, - (unsigned long int)(rlim.rlim_max)); - exit(1); - } - rc = setrlimit(RLIMIT_STACK, &rlim); - if (rc != 0) - { - fprintf(stderr, "pcre2test: setting stack size %luM failed: %s\n", - (unsigned long int)stack_size, strerror(errno)); - exit(1); - } - op++; - argc--; -#endif - } - - /* Set some common pattern and subject controls */ - - else if (strcmp(arg, "-dfa") == 0) def_datctl.control |= CTL_DFA; - else if (strcmp(arg, "-b") == 0) def_patctl.control |= CTL_FULLBINCODE; - else if (strcmp(arg, "-d") == 0) def_patctl.control |= CTL_DEBUG; - else if (strcmp(arg, "-i") == 0) def_patctl.control |= CTL_INFO; - else if (strcmp(arg, "-jit") == 0) - { - def_patctl.jit = 7; /* full & partial */ -#ifndef SUPPORT_JIT - fprintf(stderr, "** Warning: JIT support is not available: " - "-jit calls functions that do nothing.\n"); -#endif - } - - /* Set timing parameters */ - - else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0 || - strcmp(arg, "-T") == 0 || strcmp(arg, "-TM") == 0) - { - int both = arg[2] == 0; - showtotaltimes = arg[1] == 'T'; - if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0)) - { - if (U32OVERFLOW(uli)) - { - fprintf(stderr, "+++ Argument for %s is too big\n", arg); - exit(1); - } - timeitm = (int)uli; - op++; - argc--; - } - else timeitm = LOOPREPEAT; - if (both) timeit = timeitm; - } - - /* Give help */ - - else if (strcmp(arg, "-help") == 0 || - strcmp(arg, "--help") == 0) - { - usage(); - goto EXIT; - } - - /* Show version */ - - else if (strcmp(arg, "-version") == 0 || - strcmp(arg, "--version") == 0) - { - print_version(stdout); - goto EXIT; - } - - /* The following options save their data for processing once we know what - the running mode is. */ - - else if (strcmp(arg, "-subject") == 0) - { - arg_subject = argv[op+1]; - goto CHECK_VALUE_EXISTS; - } - - else if (strcmp(arg, "-pattern") == 0) - { - arg_pattern = argv[op+1]; - CHECK_VALUE_EXISTS: - if (argc <= 2) - { - fprintf(stderr, "** Missing value for %s\n", arg); - yield = 1; - goto EXIT; - } - op++; - argc--; - } - - /* Unrecognized option */ - - else - { - fprintf(stderr, "** Unknown or malformed option '%s'\n", arg); - usage(); - yield = 1; - goto EXIT; - } - op++; - argc--; - } - -/* Initialize things that cannot be done until we know which test mode we are -running in. When HEAP_MATCH_RECURSE is undefined, calling pcre2_set_recursion_ -memory_management() is a no-op, but we call it in order to exercise it. Also -exercise the general context copying function, which is not otherwise used. */ - -code_unit_size = test_mode/8; -max_oveccount = DEFAULT_OVECCOUNT; - -/* Use macros to save a lot of duplication. */ - -#define CREATECONTEXTS \ - G(general_context,BITS) = G(pcre2_general_context_create_,BITS)(&my_malloc, &my_free, NULL); \ - G(general_context_copy,BITS) = G(pcre2_general_context_copy_,BITS)(G(general_context,BITS)); \ - G(default_pat_context,BITS) = G(pcre2_compile_context_create_,BITS)(G(general_context,BITS)); \ - G(pat_context,BITS) = G(pcre2_compile_context_copy_,BITS)(G(default_pat_context,BITS)); \ - G(default_dat_context,BITS) = G(pcre2_match_context_create_,BITS)(G(general_context,BITS)); \ - G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \ - G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS)) - -#ifdef HEAP_MATCH_RECURSE -#define SETRECURSEMEMMAN \ - (void)G(pcre2_set_recursion_memory_management_,BITS) \ - (G(default_dat_context,BITS), \ - &my_stack_malloc, &my_stack_free, NULL) -#else -#define SETRECURSEMEMMAN \ - (void)G(pcre2_set_recursion_memory_management_,BITS)(NULL, NULL, NULL, NULL) -#endif - -/* Call the appropriate functions for the current mode. */ - -#ifdef SUPPORT_PCRE2_8 -#undef BITS -#define BITS 8 -if (test_mode == PCRE8_MODE) - { - CREATECONTEXTS; - SETRECURSEMEMMAN; - } -#endif - -#ifdef SUPPORT_PCRE2_16 -#undef BITS -#define BITS 16 -if (test_mode == PCRE16_MODE) - { - CREATECONTEXTS; - SETRECURSEMEMMAN; - } -#endif - -#ifdef SUPPORT_PCRE2_32 -#undef BITS -#define BITS 32 -if (test_mode == PCRE32_MODE) - { - CREATECONTEXTS; - SETRECURSEMEMMAN; - } -#endif - -/* Set a default parentheses nest limit that is large enough to run the -standard tests (this also exercises the function). */ - -PCRE2_SET_PARENS_NEST_LIMIT(default_pat_context, 220); - -/* Handle command line modifier settings, sending any error messages to -stderr. We need to know the mode before modifying the context, and it is tidier -to do them all in the same way. */ - -outfile = stderr; -if ((arg_pattern != NULL && - !decode_modifiers((uint8_t *)arg_pattern, CTX_DEFPAT, &def_patctl, NULL)) || - (arg_subject != NULL && - !decode_modifiers((uint8_t *)arg_subject, CTX_DEFDAT, NULL, &def_datctl))) - { - yield = 1; - goto EXIT; - } - -/* Sort out the input and output files, defaulting to stdin/stdout. */ - -infile = stdin; -outfile = stdout; - -if (argc > 1 && strcmp(argv[op], "-") != 0) - { - infile = fopen(argv[op], INPUT_MODE); - if (infile == NULL) - { - printf("** Failed to open '%s'\n", argv[op]); - yield = 1; - goto EXIT; - } - } - -if (argc > 2) - { - outfile = fopen(argv[op+1], OUTPUT_MODE); - if (outfile == NULL) - { - printf("** Failed to open '%s'\n", argv[op+1]); - yield = 1; - goto EXIT; - } - } - -/* Output a heading line unless quiet, then process input lines. */ - -if (!quiet) print_version(outfile); - -SET(compiled_code, NULL); - -#ifdef SUPPORT_PCRE2_8 -preg.re_pcre2_code = NULL; -preg.re_match_data = NULL; -#endif - -while (notdone) - { - uint8_t *p; - int rc = PR_OK; - BOOL expectdata = TEST(compiled_code, !=, NULL); -#ifdef SUPPORT_PCRE2_8 - expectdata |= preg.re_pcre2_code != NULL; -#endif - - if (extend_inputline(infile, buffer, expectdata? "data> " : " re> ") == NULL) - break; - if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)buffer); - fflush(outfile); - p = buffer; - - /* If we have a pattern set up for testing, or we are skipping after a - compile failure, a blank line terminates this test; otherwise process the - line as a data line. */ - - if (expectdata || skipping) - { - while (isspace(*p)) p++; - if (*p == 0) - { -#ifdef SUPPORT_PCRE2_8 - if (preg.re_pcre2_code != NULL) - { - regfree(&preg); - preg.re_pcre2_code = NULL; - preg.re_match_data = NULL; - } -#endif /* SUPPORT_PCRE2_8 */ - if (TEST(compiled_code, !=, NULL)) - { - SUB1(pcre2_code_free, compiled_code); - SET(compiled_code, NULL); - } - skipping = FALSE; - setlocale(LC_CTYPE, "C"); - } - else if (!skipping && !(p[0] == '\\' && p[1] == '=' && isspace(p[2]))) - rc = process_data(); - } - - /* We do not have a pattern set up for testing. Lines starting with # are - either comments or special commands. Blank lines are ignored. Otherwise, the - line must start with a valid delimiter. It is then processed as a pattern - line. */ - - else if (*p == '#') - { - if (isspace(p[1]) || p[1] == '!' || p[1] == 0) continue; - rc = process_command(); - } - - else if (strchr("/!\"'`%&-=_:;,@~", *p) != NULL) - { - rc = process_pattern(); - dfa_matched = 0; - } - - else - { - while (isspace(*p)) p++; - if (*p != 0) - { - fprintf(outfile, "** Invalid pattern delimiter '%c' (x%x).\n", *buffer, - *buffer); - rc = PR_SKIP; - } - } - - if (rc == PR_SKIP && !INTERACTIVE(infile)) skipping = TRUE; - else if (rc == PR_ABEND) - { - fprintf(outfile, "** pcre2test run abandoned\n"); - yield = 1; - goto EXIT; - } - } - -/* Finish off a normal run. */ - -if (INTERACTIVE(infile)) fprintf(outfile, "\n"); - -if (showtotaltimes) - { - const char *pad = ""; - fprintf(outfile, "--------------------------------------\n"); - if (timeit > 0) - { - fprintf(outfile, "Total compile time %.4f milliseconds\n", - (((double)total_compile_time * 1000.0) / (double)timeit) / - (double)CLOCKS_PER_SEC); - if (total_jit_compile_time > 0) - fprintf(outfile, "Total JIT compile %.4f milliseconds\n", - (((double)total_jit_compile_time * 1000.0) / (double)timeit) / - (double)CLOCKS_PER_SEC); - pad = " "; - } - fprintf(outfile, "Total match time %s%.4f milliseconds\n", pad, - (((double)total_match_time * 1000.0) / (double)timeitm) / - (double)CLOCKS_PER_SEC); - } - - -EXIT: - -if (infile != NULL && infile != stdin) fclose(infile); -if (outfile != NULL && outfile != stdout) fclose(outfile); - -free(buffer); -free(dbuffer); -free(pbuffer8); -free(dfa_workspace); -free((void *)locale_tables); -PCRE2_MATCH_DATA_FREE(match_data); -SUB1(pcre2_code_free, compiled_code); - -while(patstacknext-- > 0) - { - SET(compiled_code, patstack[patstacknext]); - SUB1(pcre2_code_free, compiled_code); - } - -PCRE2_JIT_FREE_UNUSED_MEMORY(general_context); -if (jit_stack != NULL) - { - PCRE2_JIT_STACK_FREE(jit_stack); - } - -#define FREECONTEXTS \ - G(pcre2_general_context_free_,BITS)(G(general_context,BITS)); \ - G(pcre2_general_context_free_,BITS)(G(general_context_copy,BITS)); \ - G(pcre2_compile_context_free_,BITS)(G(pat_context,BITS)); \ - G(pcre2_compile_context_free_,BITS)(G(default_pat_context,BITS)); \ - G(pcre2_match_context_free_,BITS)(G(dat_context,BITS)); \ - G(pcre2_match_context_free_,BITS)(G(default_dat_context,BITS)) - -#ifdef SUPPORT_PCRE2_8 -#undef BITS -#define BITS 8 -regfree(&preg); -FREECONTEXTS; -#endif - -#ifdef SUPPORT_PCRE2_16 -#undef BITS -#define BITS 16 -free(pbuffer16); -FREECONTEXTS; -#endif - -#ifdef SUPPORT_PCRE2_32 -#undef BITS -#define BITS 32 -free(pbuffer32); -FREECONTEXTS; -#endif - -#if defined(__VMS) - yield = SS$_NORMAL; /* Return values via DCL symbols */ -#endif - -return yield; -} - -/* End of pcre2test.c */ diff --git a/pcre2/src/sljit/sljitConfig.h b/pcre2/src/sljit/sljitConfig.h deleted file mode 100644 index 1c8a521aa..000000000 --- a/pcre2/src/sljit/sljitConfig.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SLJIT_CONFIG_H_ -#define _SLJIT_CONFIG_H_ - -/* --------------------------------------------------------------------- */ -/* Custom defines */ -/* --------------------------------------------------------------------- */ - -/* Put your custom defines here. This empty section will never change - which helps maintaining patches (with diff / patch utilities). */ - -/* --------------------------------------------------------------------- */ -/* Architecture */ -/* --------------------------------------------------------------------- */ - -/* Architecture selection. */ -/* #define SLJIT_CONFIG_X86_32 1 */ -/* #define SLJIT_CONFIG_X86_64 1 */ -/* #define SLJIT_CONFIG_ARM_V5 1 */ -/* #define SLJIT_CONFIG_ARM_V7 1 */ -/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ -/* #define SLJIT_CONFIG_ARM_64 1 */ -/* #define SLJIT_CONFIG_PPC_32 1 */ -/* #define SLJIT_CONFIG_PPC_64 1 */ -/* #define SLJIT_CONFIG_MIPS_32 1 */ -/* #define SLJIT_CONFIG_MIPS_64 1 */ -/* #define SLJIT_CONFIG_SPARC_32 1 */ -/* #define SLJIT_CONFIG_TILEGX 1 */ - -/* #define SLJIT_CONFIG_AUTO 1 */ -/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ - -/* --------------------------------------------------------------------- */ -/* Utilities */ -/* --------------------------------------------------------------------- */ - -/* Useful for thread-safe compiling of global functions. */ -#ifndef SLJIT_UTIL_GLOBAL_LOCK -/* Enabled by default */ -#define SLJIT_UTIL_GLOBAL_LOCK 1 -#endif - -/* Implements a stack like data structure (by using mmap / VirtualAlloc). */ -#ifndef SLJIT_UTIL_STACK -/* Enabled by default */ -#define SLJIT_UTIL_STACK 1 -#endif - -/* Single threaded application. Does not require any locks. */ -#ifndef SLJIT_SINGLE_THREADED -/* Disabled by default. */ -#define SLJIT_SINGLE_THREADED 0 -#endif - -/* --------------------------------------------------------------------- */ -/* Configuration */ -/* --------------------------------------------------------------------- */ - -/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should - define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */ -#ifndef SLJIT_STD_MACROS_DEFINED -/* Disabled by default. */ -#define SLJIT_STD_MACROS_DEFINED 0 -#endif - -/* Executable code allocation: - If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should - define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */ -#ifndef SLJIT_EXECUTABLE_ALLOCATOR -/* Enabled by default. */ -#define SLJIT_EXECUTABLE_ALLOCATOR 1 -#endif - -/* Force cdecl calling convention even if a better calling - convention (e.g. fastcall) is supported by the C compiler. - If this option is enabled, C functions without - SLJIT_CALL can also be called from JIT code. */ -#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION -/* Disabled by default */ -#define SLJIT_USE_CDECL_CALLING_CONVENTION 0 -#endif - -/* Return with error when an invalid argument is passed. */ -#ifndef SLJIT_ARGUMENT_CHECKS -/* Disabled by default */ -#define SLJIT_ARGUMENT_CHECKS 0 -#endif - -/* Debug checks (assertions, etc.). */ -#ifndef SLJIT_DEBUG -/* Enabled by default */ -#define SLJIT_DEBUG 1 -#endif - -/* Verbose operations. */ -#ifndef SLJIT_VERBOSE -/* Enabled by default */ -#define SLJIT_VERBOSE 1 -#endif - -/* - SLJIT_IS_FPU_AVAILABLE - The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE. - zero value - FPU is NOT present. - nonzero value - FPU is present. -*/ - -/* For further configurations, see the beginning of sljitConfigInternal.h */ - -#endif diff --git a/pcre2/src/sljit/sljitConfigInternal.h b/pcre2/src/sljit/sljitConfigInternal.h deleted file mode 100644 index 16e3547c9..000000000 --- a/pcre2/src/sljit/sljitConfigInternal.h +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SLJIT_CONFIG_INTERNAL_H_ -#define _SLJIT_CONFIG_INTERNAL_H_ - -/* - SLJIT defines the following architecture dependent types and macros: - - Types: - sljit_sb, sljit_ub : signed and unsigned 8 bit byte - sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type - sljit_si, sljit_ui : signed and unsigned 32 bit integer type - sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer - sljit_p : unsgined pointer value (usually the same as sljit_uw, but - some 64 bit ABIs may use 32 bit pointers) - sljit_s : single precision floating point value - sljit_d : double precision floating point value - - Macros for feature detection (boolean): - SLJIT_32BIT_ARCHITECTURE : 32 bit architecture - SLJIT_64BIT_ARCHITECTURE : 64 bit architecture - SLJIT_LITTLE_ENDIAN : little endian architecture - SLJIT_BIG_ENDIAN : big endian architecture - SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) - SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information - - Constants: - SLJIT_NUMBER_OF_REGISTERS : number of available registers - SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers - SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers - SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers - SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index - SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing - a double precision floating point array by index - SLJIT_SINGLE_SHIFT : the shift required to apply when accessing - a single precision floating point array by index - SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) - SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address - - Other macros: - SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT - SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) -*/ - -/*****************/ -/* Sanity check. */ -/*****************/ - -#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ - || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ - || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ - || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) -#error "An architecture must be selected" -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ - + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ - + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ - + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 -#error "Multiple architectures are selected" -#endif - -/********************************************************/ -/* Automatic CPU detection (requires compiler support). */ -/********************************************************/ - -#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) - -#ifndef _WIN32 - -#if defined(__i386__) || defined(__i386) -#define SLJIT_CONFIG_X86_32 1 -#elif defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif defined(__arm__) || defined(__ARM__) -#ifdef __thumb2__ -#define SLJIT_CONFIG_ARM_THUMB2 1 -#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) -#define SLJIT_CONFIG_ARM_V7 1 -#else -#define SLJIT_CONFIG_ARM_V5 1 -#endif -#elif defined (__aarch64__) -#define SLJIT_CONFIG_ARM_64 1 -#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__)) -#define SLJIT_CONFIG_PPC_64 1 -#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) -#define SLJIT_CONFIG_PPC_32 1 -#elif defined(__mips__) && !defined(_LP64) -#define SLJIT_CONFIG_MIPS_32 1 -#elif defined(__mips64) -#define SLJIT_CONFIG_MIPS_64 1 -#elif defined(__sparc__) || defined(__sparc) -#define SLJIT_CONFIG_SPARC_32 1 -#elif defined(__tilegx__) -#define SLJIT_CONFIG_TILEGX 1 -#else -/* Unsupported architecture */ -#define SLJIT_CONFIG_UNSUPPORTED 1 -#endif - -#else /* !_WIN32 */ - -#if defined(_M_X64) || defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif defined(_ARM_) -#define SLJIT_CONFIG_ARM_V5 1 -#else -#define SLJIT_CONFIG_X86_32 1 -#endif - -#endif /* !WIN32 */ -#endif /* SLJIT_CONFIG_AUTO */ - -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -#undef SLJIT_EXECUTABLE_ALLOCATOR -#endif - -/******************************/ -/* CPU family type detection. */ -/******************************/ - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -#define SLJIT_CONFIG_ARM_32 1 -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#define SLJIT_CONFIG_X86 1 -#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) -#define SLJIT_CONFIG_ARM 1 -#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_CONFIG_PPC 1 -#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -#define SLJIT_CONFIG_MIPS 1 -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) || (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64) -#define SLJIT_CONFIG_SPARC 1 -#endif - -/**********************************/ -/* External function definitions. */ -/**********************************/ - -#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) - -/* These libraries are needed for the macros below. */ -#include -#include - -#endif /* SLJIT_STD_MACROS_DEFINED */ - -/* General macros: - Note: SLJIT is designed to be independent from them as possible. - - In release mode (SLJIT_DEBUG is not defined) only the following - external functions are needed: -*/ - -#ifndef SLJIT_MALLOC -#define SLJIT_MALLOC(size, allocator_data) malloc(size) -#endif - -#ifndef SLJIT_FREE -#define SLJIT_FREE(ptr, allocator_data) free(ptr) -#endif - -#ifndef SLJIT_MEMMOVE -#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) -#endif - -#ifndef SLJIT_ZEROMEM -#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) -#endif - -/***************************/ -/* Compiler helper macros. */ -/***************************/ - -#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) - -#if defined(__GNUC__) && (__GNUC__ >= 3) -#define SLJIT_LIKELY(x) __builtin_expect((x), 1) -#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0) -#else -#define SLJIT_LIKELY(x) (x) -#define SLJIT_UNLIKELY(x) (x) -#endif - -#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ - -#ifndef SLJIT_INLINE -/* Inline functions. Some old compilers do not support them. */ -#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510 -#define SLJIT_INLINE -#else -#define SLJIT_INLINE __inline -#endif -#endif /* !SLJIT_INLINE */ - -#ifndef SLJIT_NOINLINE -/* Not inline functions. */ -#if defined(__GNUC__) -#define SLJIT_NOINLINE __attribute__ ((noinline)) -#else -#define SLJIT_NOINLINE -#endif -#endif /* !SLJIT_INLINE */ - -#ifndef SLJIT_CONST -/* Const variables. */ -#define SLJIT_CONST const -#endif - -#ifndef SLJIT_UNUSED_ARG -/* Unused arguments. */ -#define SLJIT_UNUSED_ARG(arg) (void)arg -#endif - -/*********************************/ -/* Type of public API functions. */ -/*********************************/ - -#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) -/* Static ABI functions. For all-in-one programs. */ - -#if defined(__GNUC__) -/* Disable unused warnings in gcc. */ -#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused)) -#else -#define SLJIT_API_FUNC_ATTRIBUTE static -#endif - -#else -#define SLJIT_API_FUNC_ATTRIBUTE -#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ - -/****************************/ -/* Instruction cache flush. */ -/****************************/ - -#ifndef SLJIT_CACHE_FLUSH - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - -/* Not required to implement on archs with unified caches. */ -#define SLJIT_CACHE_FLUSH(from, to) - -#elif defined __APPLE__ - -/* Supported by all macs since Mac OS 10.5. - However, it does not work on non-jailbroken iOS devices, - although the compilation is successful. */ - -#define SLJIT_CACHE_FLUSH(from, to) \ - sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) - -#elif defined __ANDROID__ - -/* Android lacks __clear_cache; instead, cacheflush should be used. */ - -#define SLJIT_CACHE_FLUSH(from, to) \ - cacheflush((long)(from), (long)(to), 0) - -#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) - -/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ -#define SLJIT_CACHE_FLUSH(from, to) \ - ppc_cache_flush((from), (to)) - -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - -/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ -#define SLJIT_CACHE_FLUSH(from, to) \ - sparc_cache_flush((from), (to)) - -#else - -/* Calls __ARM_NR_cacheflush on ARM-Linux. */ -#define SLJIT_CACHE_FLUSH(from, to) \ - __clear_cache((char*)(from), (char*)(to)) - -#endif - -#endif /* !SLJIT_CACHE_FLUSH */ - -/******************************************************/ -/* Byte/half/int/word/single/double type definitions. */ -/******************************************************/ - -/* 8 bit byte type. */ -typedef unsigned char sljit_ub; -typedef signed char sljit_sb; - -/* 16 bit half-word type. */ -typedef unsigned short int sljit_uh; -typedef signed short int sljit_sh; - -/* 32 bit integer type. */ -typedef unsigned int sljit_ui; -typedef signed int sljit_si; - -/* Machine word type. Enough for storing a pointer. - 32 bit for 32 bit machines. - 64 bit for 64 bit machines. */ -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -/* Just to have something. */ -#define SLJIT_WORD_SHIFT 0 -typedef unsigned long int sljit_uw; -typedef long int sljit_sw; -#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) -#define SLJIT_32BIT_ARCHITECTURE 1 -#define SLJIT_WORD_SHIFT 2 -typedef unsigned int sljit_uw; -typedef int sljit_sw; -#else -#define SLJIT_64BIT_ARCHITECTURE 1 -#define SLJIT_WORD_SHIFT 3 -#ifdef _WIN32 -typedef unsigned __int64 sljit_uw; -typedef __int64 sljit_sw; -#else -typedef unsigned long int sljit_uw; -typedef long int sljit_sw; -#endif -#endif - -typedef sljit_uw sljit_p; - -/* Floating point types. */ -typedef float sljit_s; -typedef double sljit_d; - -/* Shift for pointer sized data. */ -#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT - -/* Shift for double precision sized data. */ -#define SLJIT_DOUBLE_SHIFT 3 -#define SLJIT_SINGLE_SHIFT 2 - -#ifndef SLJIT_W - -/* Defining long constants. */ -#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) -#define SLJIT_W(w) (w##ll) -#else -#define SLJIT_W(w) (w) -#endif - -#endif /* !SLJIT_W */ - -/*************************/ -/* Endianness detection. */ -/*************************/ - -#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) - -/* These macros are mostly useful for the applications. */ -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - -#ifdef __LITTLE_ENDIAN__ -#define SLJIT_LITTLE_ENDIAN 1 -#else -#define SLJIT_BIG_ENDIAN 1 -#endif - -#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - -#ifdef __MIPSEL__ -#define SLJIT_LITTLE_ENDIAN 1 -#else -#define SLJIT_BIG_ENDIAN 1 -#endif - -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - -#define SLJIT_BIG_ENDIAN 1 - -#else -#define SLJIT_LITTLE_ENDIAN 1 -#endif - -#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */ - -/* Sanity check. */ -#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#error "Exactly one endianness must be selected" -#endif - -#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#error "Exactly one endianness must be selected" -#endif - -#ifndef SLJIT_UNALIGNED - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_UNALIGNED 1 -#endif - -#endif /* !SLJIT_UNALIGNED */ - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -/* Auto detect SSE2 support using CPUID. - On 64 bit x86 cpus, sse2 must be present. */ -#define SLJIT_DETECT_SSE2 1 -#endif - -/*****************************************************************************************/ -/* Calling convention of functions generated by SLJIT or called from the generated code. */ -/*****************************************************************************************/ - -#ifndef SLJIT_CALL - -#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) - -/* Force cdecl. */ -#define SLJIT_CALL - -#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - -#if defined(__GNUC__) && !defined(__APPLE__) - -#define SLJIT_CALL __attribute__ ((fastcall)) -#define SLJIT_X86_32_FASTCALL 1 - -#elif defined(_MSC_VER) - -#define SLJIT_CALL __fastcall -#define SLJIT_X86_32_FASTCALL 1 - -#elif defined(__BORLANDC__) - -#define SLJIT_CALL __msfastcall -#define SLJIT_X86_32_FASTCALL 1 - -#else /* Unknown compiler. */ - -/* The cdecl attribute is the default. */ -#define SLJIT_CALL - -#endif - -#else /* Non x86-32 architectures. */ - -#define SLJIT_CALL - -#endif /* SLJIT_CONFIG_X86_32 */ - -#endif /* !SLJIT_CALL */ - -#ifndef SLJIT_INDIRECT_CALL -#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \ - || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) -/* It seems certain ppc compilers use an indirect addressing for functions - which makes things complicated. */ -#define SLJIT_INDIRECT_CALL 1 -#endif -#endif /* SLJIT_INDIRECT_CALL */ - -/* The offset which needs to be substracted from the return address to -determine the next executed instruction after return. */ -#ifndef SLJIT_RETURN_ADDRESS_OFFSET -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#define SLJIT_RETURN_ADDRESS_OFFSET 8 -#else -#define SLJIT_RETURN_ADDRESS_OFFSET 0 -#endif -#endif /* SLJIT_RETURN_ADDRESS_OFFSET */ - -/***************************************************/ -/* Functions of the built-in executable allocator. */ -/***************************************************/ - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) -SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); -#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) -#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) -#endif - -/**********************************************/ -/* Registers and locals offset determination. */ -/**********************************************/ - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - -#define SLJIT_NUMBER_OF_REGISTERS 10 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) -#define SLJIT_LOCALS_OFFSET_BASE ((2 + 4) * sizeof(sljit_sw)) -#else -/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */ -#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1 + 4) * sizeof(sljit_sw)) -#endif /* SLJIT_X86_32_FASTCALL */ - -#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - -#ifndef _WIN64 -#define SLJIT_NUMBER_OF_REGISTERS 12 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6 -#define SLJIT_LOCALS_OFFSET_BASE (sizeof(sljit_sw)) -#else -#define SLJIT_NUMBER_OF_REGISTERS 12 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 -#define SLJIT_LOCALS_OFFSET_BASE ((4 + 2) * sizeof(sljit_sw)) -#endif /* _WIN64 */ - -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - -#define SLJIT_NUMBER_OF_REGISTERS 11 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - -#define SLJIT_NUMBER_OF_REGISTERS 11 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) - -#define SLJIT_NUMBER_OF_REGISTERS 25 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 -#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw)) - -#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) - -#define SLJIT_NUMBER_OF_REGISTERS 22 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17 -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX) -#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw)) -#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -/* Add +1 for double alignment. */ -#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw)) -#else -#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw)) -#endif /* SLJIT_CONFIG_PPC_64 || _AIX */ - -#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - -#define SLJIT_NUMBER_OF_REGISTERS 17 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw)) -#else -#define SLJIT_LOCALS_OFFSET_BASE 0 -#endif - -#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) - -#define SLJIT_NUMBER_OF_REGISTERS 18 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14 -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -/* Add +1 for double alignment. */ -#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw)) -#endif - -#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) - -#define SLJIT_NUMBER_OF_REGISTERS 10 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) - -#define SLJIT_NUMBER_OF_REGISTERS 0 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#endif - -#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE) - -#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \ - (SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS) - -#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6 -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64) -#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1 -#else -#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 -#endif - -#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ - (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) - -/*************************************/ -/* Debug and verbose related macros. */ -/*************************************/ - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -#include -#endif - -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) - -#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP) - -/* SLJIT_HALT_PROCESS must halt the process. */ -#ifndef SLJIT_HALT_PROCESS -#include - -#define SLJIT_HALT_PROCESS() \ - abort(); -#endif /* !SLJIT_HALT_PROCESS */ - -#include - -#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */ - -/* Feel free to redefine these two macros. */ -#ifndef SLJIT_ASSERT - -#define SLJIT_ASSERT(x) \ - do { \ - if (SLJIT_UNLIKELY(!(x))) { \ - printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ - SLJIT_HALT_PROCESS(); \ - } \ - } while (0) - -#endif /* !SLJIT_ASSERT */ - -#ifndef SLJIT_ASSERT_STOP - -#define SLJIT_ASSERT_STOP() \ - do { \ - printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ - SLJIT_HALT_PROCESS(); \ - } while (0) - -#endif /* !SLJIT_ASSERT_STOP */ - -#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ - -/* Forcing empty, but valid statements. */ -#undef SLJIT_ASSERT -#undef SLJIT_ASSERT_STOP - -#define SLJIT_ASSERT(x) \ - do { } while (0) -#define SLJIT_ASSERT_STOP() \ - do { } while (0) - -#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ - -#ifndef SLJIT_COMPILE_ASSERT - -/* Should be improved eventually. */ -#define SLJIT_COMPILE_ASSERT(x, description) \ - SLJIT_ASSERT(x) - -#endif /* !SLJIT_COMPILE_ASSERT */ - -#endif diff --git a/pcre2/src/sljit/sljitExecAllocator.c b/pcre2/src/sljit/sljitExecAllocator.c deleted file mode 100644 index f24ed3379..000000000 --- a/pcre2/src/sljit/sljitExecAllocator.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - This file contains a simple executable memory allocator - - It is assumed, that executable code blocks are usually medium (or sometimes - large) memory blocks, and the allocator is not too frequently called (less - optimized than other allocators). Thus, using it as a generic allocator is - not suggested. - - How does it work: - Memory is allocated in continuous memory areas called chunks by alloc_chunk() - Chunk format: - [ block ][ block ] ... [ block ][ block terminator ] - - All blocks and the block terminator is started with block_header. The block - header contains the size of the previous and the next block. These sizes - can also contain special values. - Block size: - 0 - The block is a free_block, with a different size member. - 1 - The block is a block terminator. - n - The block is used at the moment, and the value contains its size. - Previous block size: - 0 - This is the first block of the memory chunk. - n - The size of the previous block. - - Using these size values we can go forward or backward on the block chain. - The unused blocks are stored in a chain list pointed by free_blocks. This - list is useful if we need to find a suitable memory area when the allocator - is called. - - When a block is freed, the new free block is connected to its adjacent free - blocks if possible. - - [ free block ][ used block ][ free block ] - and "used block" is freed, the three blocks are connected together: - [ one big free block ] -*/ - -/* --------------------------------------------------------------------- */ -/* System (OS) functions */ -/* --------------------------------------------------------------------- */ - -/* 64 KByte. */ -#define CHUNK_SIZE 0x10000 - -/* - alloc_chunk / free_chunk : - * allocate executable system memory chunks - * the size is always divisible by CHUNK_SIZE - allocator_grab_lock / allocator_release_lock : - * make the allocator thread safe - * can be empty if the OS (or the application) does not support threading - * only the allocator requires this lock, sljit is fully thread safe - as it only uses local variables -*/ - -#ifdef _WIN32 - -static SLJIT_INLINE void* alloc_chunk(sljit_uw size) -{ - return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); -} - -static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) -{ - SLJIT_UNUSED_ARG(size); - VirtualFree(chunk, 0, MEM_RELEASE); -} - -#else - -static SLJIT_INLINE void* alloc_chunk(sljit_uw size) -{ - void* retval; - -#ifdef MAP_ANON - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); -#else - if (dev_zero < 0) { - if (open_dev_zero()) - return NULL; - } - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); -#endif - - return (retval != MAP_FAILED) ? retval : NULL; -} - -static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) -{ - munmap(chunk, size); -} - -#endif - -/* --------------------------------------------------------------------- */ -/* Common functions */ -/* --------------------------------------------------------------------- */ - -#define CHUNK_MASK (~(CHUNK_SIZE - 1)) - -struct block_header { - sljit_uw size; - sljit_uw prev_size; -}; - -struct free_block { - struct block_header header; - struct free_block *next; - struct free_block *prev; - sljit_uw size; -}; - -#define AS_BLOCK_HEADER(base, offset) \ - ((struct block_header*)(((sljit_ub*)base) + offset)) -#define AS_FREE_BLOCK(base, offset) \ - ((struct free_block*)(((sljit_ub*)base) + offset)) -#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) -#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) - -static struct free_block* free_blocks; -static sljit_uw allocated_size; -static sljit_uw total_size; - -static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) -{ - free_block->header.size = 0; - free_block->size = size; - - free_block->next = free_blocks; - free_block->prev = 0; - if (free_blocks) - free_blocks->prev = free_block; - free_blocks = free_block; -} - -static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) -{ - if (free_block->next) - free_block->next->prev = free_block->prev; - - if (free_block->prev) - free_block->prev->next = free_block->next; - else { - SLJIT_ASSERT(free_blocks == free_block); - free_blocks = free_block->next; - } -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) -{ - struct block_header *header; - struct block_header *next_header; - struct free_block *free_block; - sljit_uw chunk_size; - - allocator_grab_lock(); - if (size < sizeof(struct free_block)) - size = sizeof(struct free_block); - size = ALIGN_SIZE(size); - - free_block = free_blocks; - while (free_block) { - if (free_block->size >= size) { - chunk_size = free_block->size; - if (chunk_size > size + 64) { - /* We just cut a block from the end of the free block. */ - chunk_size -= size; - free_block->size = chunk_size; - header = AS_BLOCK_HEADER(free_block, chunk_size); - header->prev_size = chunk_size; - AS_BLOCK_HEADER(header, size)->prev_size = size; - } - else { - sljit_remove_free_block(free_block); - header = (struct block_header*)free_block; - size = chunk_size; - } - allocated_size += size; - header->size = size; - allocator_release_lock(); - return MEM_START(header); - } - free_block = free_block->next; - } - - chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; - header = (struct block_header*)alloc_chunk(chunk_size); - if (!header) { - allocator_release_lock(); - return NULL; - } - - chunk_size -= sizeof(struct block_header); - total_size += chunk_size; - - header->prev_size = 0; - if (chunk_size > size + 64) { - /* Cut the allocated space into a free and a used block. */ - allocated_size += size; - header->size = size; - chunk_size -= size; - - free_block = AS_FREE_BLOCK(header, size); - free_block->header.prev_size = size; - sljit_insert_free_block(free_block, chunk_size); - next_header = AS_BLOCK_HEADER(free_block, chunk_size); - } - else { - /* All space belongs to this allocation. */ - allocated_size += chunk_size; - header->size = chunk_size; - next_header = AS_BLOCK_HEADER(header, chunk_size); - } - next_header->size = 1; - next_header->prev_size = chunk_size; - allocator_release_lock(); - return MEM_START(header); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) -{ - struct block_header *header; - struct free_block* free_block; - - allocator_grab_lock(); - header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); - allocated_size -= header->size; - - /* Connecting free blocks together if possible. */ - - /* If header->prev_size == 0, free_block will equal to header. - In this case, free_block->header.size will be > 0. */ - free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size); - if (SLJIT_UNLIKELY(!free_block->header.size)) { - free_block->size += header->size; - header = AS_BLOCK_HEADER(free_block, free_block->size); - header->prev_size = free_block->size; - } - else { - free_block = (struct free_block*)header; - sljit_insert_free_block(free_block, header->size); - } - - header = AS_BLOCK_HEADER(free_block, free_block->size); - if (SLJIT_UNLIKELY(!header->size)) { - free_block->size += ((struct free_block*)header)->size; - sljit_remove_free_block((struct free_block*)header); - header = AS_BLOCK_HEADER(free_block, free_block->size); - header->prev_size = free_block->size; - } - - /* The whole chunk is free. */ - if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { - /* If this block is freed, we still have (allocated_size / 2) free space. */ - if (total_size - free_block->size > (allocated_size * 3 / 2)) { - total_size -= free_block->size; - sljit_remove_free_block(free_block); - free_chunk(free_block, free_block->size + sizeof(struct block_header)); - } - } - - allocator_release_lock(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) -{ - struct free_block* free_block; - struct free_block* next_free_block; - - allocator_grab_lock(); - - free_block = free_blocks; - while (free_block) { - next_free_block = free_block->next; - if (!free_block->header.prev_size && - AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { - total_size -= free_block->size; - sljit_remove_free_block(free_block); - free_chunk(free_block, free_block->size + sizeof(struct block_header)); - } - free_block = next_free_block; - } - - SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); - allocator_release_lock(); -} diff --git a/pcre2/src/sljit/sljitLir.c b/pcre2/src/sljit/sljitLir.c deleted file mode 100644 index 0f1b1c9cc..000000000 --- a/pcre2/src/sljit/sljitLir.c +++ /dev/null @@ -1,2029 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "sljitLir.h" - -#define CHECK_ERROR() \ - do { \ - if (SLJIT_UNLIKELY(compiler->error)) \ - return compiler->error; \ - } while (0) - -#define CHECK_ERROR_PTR() \ - do { \ - if (SLJIT_UNLIKELY(compiler->error)) \ - return NULL; \ - } while (0) - -#define FAIL_IF(expr) \ - do { \ - if (SLJIT_UNLIKELY(expr)) \ - return compiler->error; \ - } while (0) - -#define PTR_FAIL_IF(expr) \ - do { \ - if (SLJIT_UNLIKELY(expr)) \ - return NULL; \ - } while (0) - -#define FAIL_IF_NULL(ptr) \ - do { \ - if (SLJIT_UNLIKELY(!(ptr))) { \ - compiler->error = SLJIT_ERR_ALLOC_FAILED; \ - return SLJIT_ERR_ALLOC_FAILED; \ - } \ - } while (0) - -#define PTR_FAIL_IF_NULL(ptr) \ - do { \ - if (SLJIT_UNLIKELY(!(ptr))) { \ - compiler->error = SLJIT_ERR_ALLOC_FAILED; \ - return NULL; \ - } \ - } while (0) - -#define PTR_FAIL_WITH_EXEC_IF(ptr) \ - do { \ - if (SLJIT_UNLIKELY(!(ptr))) { \ - compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \ - return NULL; \ - } \ - } while (0) - -#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) - -#define GET_OPCODE(op) \ - ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) - -#define GET_FLAGS(op) \ - ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) - -#define GET_ALL_FLAGS(op) \ - ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) - -#define TYPE_CAST_NEEDED(op) \ - (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) - -#define BUF_SIZE 4096 - -#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) -#define ABUF_SIZE 2048 -#else -#define ABUF_SIZE 4096 -#endif - -/* Parameter parsing. */ -#define REG_MASK 0x3f -#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) -#define OFFS_REG_MASK (REG_MASK << 8) -#define TO_OFFS_REG(reg) ((reg) << 8) -/* When reg cannot be unused. */ -#define FAST_IS_REG(reg) ((reg) <= REG_MASK) -/* When reg can be unused. */ -#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK) - -/* Jump flags. */ -#define JUMP_LABEL 0x1 -#define JUMP_ADDR 0x2 -/* SLJIT_REWRITABLE_JUMP is 0x1000. */ - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -# define PATCH_MB 0x4 -# define PATCH_MW 0x8 -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -# define PATCH_MD 0x10 -#endif -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -# define IS_BL 0x4 -# define PATCH_B 0x8 -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -# define CPOOL_SIZE 512 -#endif - -#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -# define IS_COND 0x04 -# define IS_BL 0x08 - /* conditional + imm8 */ -# define PATCH_TYPE1 0x10 - /* conditional + imm20 */ -# define PATCH_TYPE2 0x20 - /* IT + imm24 */ -# define PATCH_TYPE3 0x30 - /* imm11 */ -# define PATCH_TYPE4 0x40 - /* imm24 */ -# define PATCH_TYPE5 0x50 - /* BL + imm24 */ -# define PATCH_BL 0x60 - /* 0xf00 cc code for branches */ -#endif - -#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) -# define IS_COND 0x004 -# define IS_CBZ 0x008 -# define IS_BL 0x010 -# define PATCH_B 0x020 -# define PATCH_COND 0x040 -# define PATCH_ABS48 0x080 -# define PATCH_ABS64 0x100 -#endif - -#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) -# define IS_COND 0x004 -# define IS_CALL 0x008 -# define PATCH_B 0x010 -# define PATCH_ABS_B 0x020 -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -# define PATCH_ABS32 0x040 -# define PATCH_ABS48 0x080 -#endif -# define REMOVE_COND 0x100 -#endif - -#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) -# define IS_MOVABLE 0x004 -# define IS_JAL 0x008 -# define IS_CALL 0x010 -# define IS_BIT26_COND 0x020 -# define IS_BIT16_COND 0x040 - -# define IS_COND (IS_BIT26_COND | IS_BIT16_COND) - -# define PATCH_B 0x080 -# define PATCH_J 0x100 - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -# define PATCH_ABS32 0x200 -# define PATCH_ABS48 0x400 -#endif - - /* instruction types */ -# define MOVABLE_INS 0 - /* 1 - 31 last destination register */ - /* no destination (i.e: store) */ -# define UNMOVABLE_INS 32 - /* FPU status register */ -# define FCSR_FCC 33 -#endif - -#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) -# define IS_JAL 0x04 -# define IS_COND 0x08 - -# define PATCH_B 0x10 -# define PATCH_J 0x20 -#endif - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -# define IS_MOVABLE 0x04 -# define IS_COND 0x08 -# define IS_CALL 0x10 - -# define PATCH_B 0x20 -# define PATCH_CALL 0x40 - - /* instruction types */ -# define MOVABLE_INS 0 - /* 1 - 31 last destination register */ - /* no destination (i.e: store) */ -# define UNMOVABLE_INS 32 - -# define DST_INS_MASK 0xff - - /* ICC_SET is the same as SET_FLAGS. */ -# define ICC_IS_SET (1 << 23) -# define FCC_IS_SET (1 << 24) -#endif - -/* Stack management. */ - -#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \ - (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \ - (saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \ - extra) * sizeof(sljit_sw)) - -#define ADJUST_LOCAL_OFFSET(p, i) \ - if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ - (i) += SLJIT_LOCALS_OFFSET; - -#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */ - -/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */ -#include "sljitUtils.c" - -#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) -#include "sljitExecAllocator.c" -#endif - -/* Argument checking features. */ - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - -/* Returns with error when an invalid argument is passed. */ - -#define CHECK_ARGUMENT(x) \ - do { \ - if (SLJIT_UNLIKELY(!(x))) \ - return 1; \ - } while (0) - -#define CHECK_RETURN_TYPE sljit_si -#define CHECK_RETURN_OK return 0 - -#define CHECK(x) \ - do { \ - if (SLJIT_UNLIKELY(x)) { \ - compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ - return SLJIT_ERR_BAD_ARGUMENT; \ - } \ - } while (0) - -#define CHECK_PTR(x) \ - do { \ - if (SLJIT_UNLIKELY(x)) { \ - compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ - return NULL; \ - } \ - } while (0) - -#define CHECK_REG_INDEX(x) \ - do { \ - if (SLJIT_UNLIKELY(x)) { \ - return -2; \ - } \ - } while (0) - -#elif (defined SLJIT_DEBUG && SLJIT_DEBUG) - -/* Assertion failure occures if an invalid argument is passed. */ -#undef SLJIT_ARGUMENT_CHECKS -#define SLJIT_ARGUMENT_CHECKS 1 - -#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x) -#define CHECK_RETURN_TYPE void -#define CHECK_RETURN_OK return -#define CHECK(x) x -#define CHECK_PTR(x) x -#define CHECK_REG_INDEX(x) x - -#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - -/* Arguments are not checked. */ -#define CHECK_RETURN_TYPE void -#define CHECK_RETURN_OK return -#define CHECK(x) x -#define CHECK_PTR(x) x -#define CHECK_REG_INDEX(x) x - -#else - -/* Arguments are not checked. */ -#define CHECK(x) -#define CHECK_PTR(x) -#define CHECK_REG_INDEX(x) - -#endif /* SLJIT_ARGUMENT_CHECKS */ - -/* --------------------------------------------------------------------- */ -/* Public functions */ -/* --------------------------------------------------------------------- */ - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -#define SLJIT_NEEDS_COMPILER_INIT 1 -static sljit_si compiler_initialized = 0; -/* A thread safe initialization. */ -static void init_compiler(void); -#endif - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) -{ - struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data); - if (!compiler) - return NULL; - SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); - - SLJIT_COMPILE_ASSERT( - sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1 - && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 - && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 - && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) - && sizeof(sljit_p) <= sizeof(sljit_sw) - && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) - && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), - invalid_integer_types); - SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, - int_op_and_single_op_must_be_the_same); - SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, - rewritable_jump_and_single_op_must_not_be_the_same); - - /* Only the non-zero members must be set. */ - compiler->error = SLJIT_SUCCESS; - - compiler->allocator_data = allocator_data; - compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); - compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data); - - if (!compiler->buf || !compiler->abuf) { - if (compiler->buf) - SLJIT_FREE(compiler->buf, allocator_data); - if (compiler->abuf) - SLJIT_FREE(compiler->abuf, allocator_data); - SLJIT_FREE(compiler, allocator_data); - return NULL; - } - - compiler->buf->next = NULL; - compiler->buf->used_size = 0; - compiler->abuf->next = NULL; - compiler->abuf->used_size = 0; - - compiler->scratches = -1; - compiler->saveds = -1; - compiler->fscratches = -1; - compiler->fsaveds = -1; - compiler->local_size = -1; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - compiler->args = -1; -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) - + CPOOL_SIZE * sizeof(sljit_ub), allocator_data); - if (!compiler->cpool) { - SLJIT_FREE(compiler->buf, allocator_data); - SLJIT_FREE(compiler->abuf, allocator_data); - SLJIT_FREE(compiler, allocator_data); - return NULL; - } - compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); - compiler->cpool_diff = 0xffffffff; -#endif - -#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - compiler->delay_slot = UNMOVABLE_INS; -#endif - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - compiler->delay_slot = UNMOVABLE_INS; -#endif - -#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) - if (!compiler_initialized) { - init_compiler(); - compiler_initialized = 1; - } -#endif - - return compiler; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - struct sljit_memory_fragment *curr; - void *allocator_data = compiler->allocator_data; - SLJIT_UNUSED_ARG(allocator_data); - - buf = compiler->buf; - while (buf) { - curr = buf; - buf = buf->next; - SLJIT_FREE(curr, allocator_data); - } - - buf = compiler->abuf; - while (buf) { - curr = buf; - buf = buf->next; - SLJIT_FREE(curr, allocator_data); - } - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - SLJIT_FREE(compiler->cpool, allocator_data); -#endif - SLJIT_FREE(compiler, allocator_data); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) -{ - if (compiler->error == SLJIT_SUCCESS) - compiler->error = SLJIT_ERR_ALLOC_FAILED; -} - -#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) -{ - /* Remove thumb mode flag. */ - SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); -} -#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) -{ - /* Resolve indirection. */ - code = (void*)(*(sljit_uw*)code); - SLJIT_FREE_EXEC(code); -} -#else -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) -{ - SLJIT_FREE_EXEC(code); -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) -{ - if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) { - jump->flags &= ~JUMP_ADDR; - jump->flags |= JUMP_LABEL; - jump->u.label = label; - } -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) -{ - if (SLJIT_LIKELY(!!jump)) { - jump->flags &= ~JUMP_LABEL; - jump->flags |= JUMP_ADDR; - jump->u.target = target; - } -} - -/* --------------------------------------------------------------------- */ -/* Private functions */ -/* --------------------------------------------------------------------- */ - -static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) -{ - sljit_ub *ret; - struct sljit_memory_fragment *new_frag; - - SLJIT_ASSERT(size <= 256); - if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { - ret = compiler->buf->memory + compiler->buf->used_size; - compiler->buf->used_size += size; - return ret; - } - new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data); - PTR_FAIL_IF_NULL(new_frag); - new_frag->next = compiler->buf; - compiler->buf = new_frag; - new_frag->used_size = size; - return new_frag->memory; -} - -static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) -{ - sljit_ub *ret; - struct sljit_memory_fragment *new_frag; - - SLJIT_ASSERT(size <= 256); - if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { - ret = compiler->abuf->memory + compiler->abuf->used_size; - compiler->abuf->used_size += size; - return ret; - } - new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data); - PTR_FAIL_IF_NULL(new_frag); - new_frag->next = compiler->abuf; - compiler->abuf = new_frag; - new_frag->used_size = size; - return new_frag->memory; -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) -{ - CHECK_ERROR_PTR(); - -#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) - if (size <= 0 || size > 128) - return NULL; - size = (size + 7) & ~7; -#else - if (size <= 0 || size > 64) - return NULL; - size = (size + 3) & ~3; -#endif - return ensure_abuf(compiler, size); -} - -static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf = compiler->buf; - struct sljit_memory_fragment *prev = NULL; - struct sljit_memory_fragment *tmp; - - do { - tmp = buf->next; - buf->next = prev; - prev = buf; - buf = tmp; - } while (buf != NULL); - - compiler->buf = prev; -} - -static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(local_size); - - compiler->options = options; - compiler->scratches = scratches; - compiler->saveds = saveds; - compiler->fscratches = fscratches; - compiler->fsaveds = fsaveds; -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->logical_local_size = local_size; -#endif -} - -static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(local_size); - - compiler->options = options; - compiler->scratches = scratches; - compiler->saveds = saveds; - compiler->fscratches = fscratches; - compiler->fsaveds = fsaveds; -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->logical_local_size = local_size; -#endif -} - -static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) -{ - label->next = NULL; - label->size = compiler->size; - if (compiler->last_label) - compiler->last_label->next = label; - else - compiler->labels = label; - compiler->last_label = label; -} - -static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags) -{ - jump->next = NULL; - jump->flags = flags; - if (compiler->last_jump) - compiler->last_jump->next = jump; - else - compiler->jumps = jump; - compiler->last_jump = jump; -} - -static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) -{ - const_->next = NULL; - const_->addr = compiler->size; - if (compiler->last_const) - compiler->last_const->next = const_; - else - compiler->consts = const_; - compiler->last_const = const_; -} - -#define ADDRESSING_DEPENDS_ON(exp, reg) \ - (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) -#define FUNCTION_CHECK_OP() \ - CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ - switch (GET_OPCODE(op)) { \ - case SLJIT_NOT: \ - case SLJIT_CLZ: \ - case SLJIT_AND: \ - case SLJIT_OR: \ - case SLJIT_XOR: \ - case SLJIT_SHL: \ - case SLJIT_LSHR: \ - case SLJIT_ASHR: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \ - break; \ - case SLJIT_NEG: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ - break; \ - case SLJIT_MUL: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ - break; \ - case SLJIT_ADD: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \ - break; \ - case SLJIT_SUB: \ - break; \ - case SLJIT_ADDC: \ - case SLJIT_SUBC: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \ - break; \ - case SLJIT_BREAKPOINT: \ - case SLJIT_NOP: \ - case SLJIT_LUMUL: \ - case SLJIT_LSMUL: \ - case SLJIT_MOV: \ - case SLJIT_MOV_UI: \ - case SLJIT_MOV_P: \ - case SLJIT_MOVU: \ - case SLJIT_MOVU_UI: \ - case SLJIT_MOVU_P: \ - /* Nothing allowed */ \ - CHECK_ARGUMENT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ - break; \ - default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ - break; \ - } - -#define FUNCTION_CHECK_FOP() \ - CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ - switch (GET_OPCODE(op)) { \ - case SLJIT_DCMP: \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ - CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ - break; \ - default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ - CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ - break; \ - } - -#define FUNCTION_CHECK_IS_REG(r) \ - (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ - ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) - -#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \ - ((r) == SLJIT_UNUSED || \ - ((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ - ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -#define CHECK_NOT_VIRTUAL_REGISTER(p) \ - CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6); -#else -#define CHECK_NOT_VIRTUAL_REGISTER(p) -#endif - -#define FUNCTION_CHECK_SRC(p, i) \ - CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ - if (FUNCTION_CHECK_IS_REG(p)) \ - CHECK_ARGUMENT((i) == 0); \ - else if ((p) == SLJIT_IMM) \ - ; \ - else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ - CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ - else { \ - CHECK_ARGUMENT((p) & SLJIT_MEM); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ - CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ - if ((p) & OFFS_REG_MASK) { \ - CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ - CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ - CHECK_ARGUMENT(!((i) & ~0x3)); \ - } \ - CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ - } - -#define FUNCTION_CHECK_DST(p, i) \ - CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ - if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \ - CHECK_ARGUMENT((i) == 0); \ - else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ - CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ - else { \ - CHECK_ARGUMENT((p) & SLJIT_MEM); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ - CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ - if ((p) & OFFS_REG_MASK) { \ - CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ - CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ - CHECK_ARGUMENT(!((i) & ~0x3)); \ - } \ - CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ - } - -#define FUNCTION_FCHECK(p, i) \ - CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \ - if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \ - ((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \ - CHECK_ARGUMENT(i == 0); \ - else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ - CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ - else { \ - CHECK_ARGUMENT((p) & SLJIT_MEM); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ - CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ - if ((p) & OFFS_REG_MASK) { \ - CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ - CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ - CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \ - } \ - CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ - } - -#define FUNCTION_CHECK_OP1() \ - if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ - CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP); \ - CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP); \ - if ((src & SLJIT_MEM) && (src & REG_MASK)) \ - CHECK_ARGUMENT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \ - } - -#endif /* SLJIT_ARGUMENT_CHECKS */ - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - -SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) -{ - compiler->verbose = verbose; -} - -#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) -#ifdef _WIN64 -# define SLJIT_PRINT_D "I64" -#else -# define SLJIT_PRINT_D "l" -#endif -#else -# define SLJIT_PRINT_D "" -#endif - -#define sljit_verbose_reg(compiler, r) \ - do { \ - if ((r) < (SLJIT_R0 + compiler->scratches)) \ - fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \ - else \ - fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \ - } while (0) - -#define sljit_verbose_param(compiler, p, i) \ - if ((p) & SLJIT_IMM) \ - fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ - else if ((p) & SLJIT_MEM) { \ - if ((p) & REG_MASK) { \ - fputc('[', compiler->verbose); \ - sljit_verbose_reg(compiler, (p) & REG_MASK); \ - if ((p) & OFFS_REG_MASK) { \ - fprintf(compiler->verbose, " + "); \ - sljit_verbose_reg(compiler, OFFS_REG(p)); \ - if (i) \ - fprintf(compiler->verbose, " * %d", 1 << (i)); \ - } \ - else if (i) \ - fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \ - fputc(']', compiler->verbose); \ - } \ - else \ - fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ - } else if (p) \ - sljit_verbose_reg(compiler, p); \ - else \ - fprintf(compiler->verbose, "unused"); - -#define sljit_verbose_fparam(compiler, p, i) \ - if ((p) & SLJIT_MEM) { \ - if ((p) & REG_MASK) { \ - fputc('[', compiler->verbose); \ - sljit_verbose_reg(compiler, (p) & REG_MASK); \ - if ((p) & OFFS_REG_MASK) { \ - fprintf(compiler->verbose, " + "); \ - sljit_verbose_reg(compiler, OFFS_REG(p)); \ - if (i) \ - fprintf(compiler->verbose, "%d", 1 << (i)); \ - } \ - else if (i) \ - fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \ - fputc(']', compiler->verbose); \ - } \ - else \ - fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ - } \ - else { \ - if ((p) < (SLJIT_FR0 + compiler->fscratches)) \ - fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \ - else \ - fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \ - } - -static SLJIT_CONST char* op0_names[] = { - (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul", - (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi" -}; - -static SLJIT_CONST char* op1_names[] = { - (char*)"mov", (char*)"mov_ub", (char*)"mov_sb", (char*)"mov_uh", - (char*)"mov_sh", (char*)"mov_ui", (char*)"mov_si", (char*)"mov_p", - (char*)"movu", (char*)"movu_ub", (char*)"movu_sb", (char*)"movu_uh", - (char*)"movu_sh", (char*)"movu_ui", (char*)"movu_si", (char*)"movu_p", - (char*)"not", (char*)"neg", (char*)"clz", -}; - -static SLJIT_CONST char* op2_names[] = { - (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", - (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", - (char*)"shl", (char*)"lshr", (char*)"ashr", -}; - -static SLJIT_CONST char* fop1_names[] = { - (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", - (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", - (char*)"abs", -}; - -static SLJIT_CONST char* fop2_names[] = { - (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" -}; - -#define JUMP_PREFIX(type) \ - ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_INT_OP) ? "i_" : "") \ - : ((type & 0xff) <= SLJIT_D_ORDERED ? ((type & SLJIT_SINGLE_OP) ? "s_" : "d_") : "")) - -static char* jump_names[] = { - (char*)"equal", (char*)"not_equal", - (char*)"less", (char*)"greater_equal", - (char*)"greater", (char*)"less_equal", - (char*)"sig_less", (char*)"sig_greater_equal", - (char*)"sig_greater", (char*)"sig_less_equal", - (char*)"overflow", (char*)"not_overflow", - (char*)"mul_overflow", (char*)"mul_not_overflow", - (char*)"equal", (char*)"not_equal", - (char*)"less", (char*)"greater_equal", - (char*)"greater", (char*)"less_equal", - (char*)"unordered", (char*)"ordered", - (char*)"jump", (char*)"fast_call", - (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" -}; - -#endif /* SLJIT_VERBOSE */ - -/* --------------------------------------------------------------------- */ -/* Arch dependent */ -/* --------------------------------------------------------------------- */ - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - struct sljit_jump *jump; -#endif - - SLJIT_UNUSED_ARG(compiler); - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(compiler->size > 0); - jump = compiler->jumps; - while (jump) { - /* All jumps have target. */ - CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR)); - jump = jump->next; - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - SLJIT_UNUSED_ARG(compiler); - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); - CHECK_ARGUMENT(args >= 0 && args <= 3); - CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(args <= saveds); - CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", - args, scratches, saveds, fscratches, fsaveds, local_size); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); - CHECK_ARGUMENT(args >= 0 && args <= 3); - CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(args <= saveds); - CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", - args, scratches, saveds, fscratches, fsaveds, local_size); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(compiler->scratches >= 0); - if (op != SLJIT_UNUSED) { - CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P); - FUNCTION_CHECK_SRC(src, srcw); - } - else - CHECK_ARGUMENT(src == 0 && srcw == 0); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (op == SLJIT_UNUSED) - fprintf(compiler->verbose, " return\n"); - else { - fprintf(compiler->verbose, " return.%s ", op1_names[op - SLJIT_OP1_BASE]); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fast_enter "); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_SRC(src, srcw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fast_return "); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL) - || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI)); - CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ); - FUNCTION_CHECK_OP(); - FUNCTION_CHECK_SRC(src, srcw); - FUNCTION_CHECK_DST(dst, dstw); - FUNCTION_CHECK_OP1(); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR); - FUNCTION_CHECK_OP(); - FUNCTION_CHECK_SRC(src1, src1w); - FUNCTION_CHECK_SRC(src2, src2w); - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src1, src1w); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src2, src2w); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si reg) -{ - SLJIT_UNUSED_ARG(reg); -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_si reg) -{ - SLJIT_UNUSED_ARG(reg); -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - int i; -#endif - - SLJIT_UNUSED_ARG(compiler); - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(instruction); -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - CHECK_ARGUMENT(size > 0 && size < 16); -#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0) - || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); -#else - CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); -#endif - -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " op_custom"); - for (i = 0; i < size; i++) - fprintf(compiler->verbose, " 0x%x", ((sljit_ub*)instruction)[i]); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DMOV && GET_OPCODE(op) <= SLJIT_DABS); - FUNCTION_CHECK_FOP(); - FUNCTION_FCHECK(src, srcw); - FUNCTION_FCHECK(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONVD_FROMS - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s.fromd" : "d.froms"); - else - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", - fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE]); - - sljit_verbose_fparam(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_DCMP); - FUNCTION_CHECK_FOP(); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop1_names[SLJIT_DCMP - SLJIT_FOP1_BASE], - (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : ""); - sljit_verbose_fparam(compiler, src1, src1w); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src2, src2w); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_CONVI_FROMD); - FUNCTION_CHECK_FOP(); - FUNCTION_FCHECK(src, srcw); - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? "i" : "w", - (op & SLJIT_SINGLE_OP) ? "s" : "d"); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVD_FROMW && GET_OPCODE(op) <= SLJIT_CONVD_FROMI); - FUNCTION_CHECK_FOP(); - FUNCTION_CHECK_SRC(src, srcw); - FUNCTION_FCHECK(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s" : "d", - (GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? "i" : "w"); - sljit_verbose_fparam(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DADD && GET_OPCODE(op) <= SLJIT_DDIV); - FUNCTION_CHECK_FOP(); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); - FUNCTION_FCHECK(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE]); - sljit_verbose_fparam(compiler, dst, dstw); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src1, src1w); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src2, src2w); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, "label:\n"); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3); - CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_INT_OP)); - CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " jump%s.%s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - JUMP_PREFIX(type), jump_names[type & 0xff]); -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL); - FUNCTION_CHECK_SRC(src1, src1w); - FUNCTION_CHECK_SRC(src2, src2w); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " cmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_INT_OP) ? "i_" : "", jump_names[type & 0xff]); - sljit_verbose_param(compiler, src1, src1w); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src2, src2w); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_D_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fcmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_SINGLE_OP) ? "s_" : "d_", jump_names[type & 0xff]); - sljit_verbose_fparam(compiler, src1, src1w); - fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src2, src2w); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - CHECK_RETURN_OK; - } - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); - CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches); - FUNCTION_CHECK_SRC(src, srcw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI - || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); - CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); - CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); - if (GET_OPCODE(op) < SLJIT_ADD) { - CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0); - } else { - CHECK_ARGUMENT(src == dst && srcw == dstw); - } - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " flags.%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", - GET_OPCODE(op) >= SLJIT_OP2_BASE ? op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE] : op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); - sljit_verbose_param(compiler, dst, dstw); - if (src != SLJIT_UNUSED) { - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); - } - fprintf(compiler->verbose, ", %s%s\n", JUMP_PREFIX(type), jump_names[type & 0xff]); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) -{ - SLJIT_UNUSED_ARG(offset); - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " local_base "); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); - } -#endif - CHECK_RETURN_OK; -} - -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - SLJIT_UNUSED_ARG(init_value); - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_DST(dst, dstw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " const "); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); - } -#endif - CHECK_RETURN_OK; -} - -#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ - -#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ - SLJIT_COMPILE_ASSERT(!(SLJIT_CONVW_FROMD & 0x1) && !(SLJIT_CONVD_FROMW & 0x1), \ - invalid_float_opcodes); \ - if (GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_DCMP) { \ - if (GET_OPCODE(op) == SLJIT_DCMP) { \ - CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \ - ADJUST_LOCAL_OFFSET(dst, dstw); \ - ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \ - } \ - if ((GET_OPCODE(op) | 0x1) == SLJIT_CONVI_FROMD) { \ - CHECK(check_sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw)); \ - ADJUST_LOCAL_OFFSET(dst, dstw); \ - ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \ - } \ - CHECK(check_sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw)); \ - ADJUST_LOCAL_OFFSET(dst, dstw); \ - ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \ - } \ - CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ - ADJUST_LOCAL_OFFSET(dst, dstw); \ - ADJUST_LOCAL_OFFSET(src, srcw); - -static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - /* Return if don't need to do anything. */ - if (op == SLJIT_UNUSED) - return SLJIT_SUCCESS; - -#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) - /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) - return SLJIT_SUCCESS; -#else - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) - return SLJIT_SUCCESS; -#endif - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - compiler->skip_checks = 1; -#endif - return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); -} - -/* CPU description section */ - -#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) -#define SLJIT_CPUINFO_PART1 " 32bit (" -#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) -#define SLJIT_CPUINFO_PART1 " 64bit (" -#else -#error "Internal error: CPU type info missing" -#endif - -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define SLJIT_CPUINFO_PART2 "little endian + " -#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) -#define SLJIT_CPUINFO_PART2 "big endian + " -#else -#error "Internal error: CPU type info missing" -#endif - -#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) -#define SLJIT_CPUINFO_PART3 "unaligned)" -#else -#define SLJIT_CPUINFO_PART3 "aligned)" -#endif - -#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -# include "sljitNativeX86_common.c" -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -# include "sljitNativeARM_32.c" -#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -# include "sljitNativeARM_32.c" -#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -# include "sljitNativeARM_T2_32.c" -#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) -# include "sljitNativeARM_64.c" -#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) -# include "sljitNativePPC_common.c" -#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) -# include "sljitNativeMIPS_common.c" -#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) -# include "sljitNativeSPARC_common.c" -#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) -# include "sljitNativeTILEGX_64.c" -#endif - -#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* Default compare for most architectures. */ - sljit_si flags, tmp_src, condition; - sljit_sw tmp_srcw; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); - - condition = type & 0xff; -#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) - if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) { - if ((src1 & SLJIT_IMM) && !src1w) { - src1 = src2; - src1w = src2w; - src2 = SLJIT_IMM; - src2w = 0; - } - if ((src2 & SLJIT_IMM) && !src2w) - return emit_cmp_to0(compiler, type, src1, src1w); - } -#endif - - if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { - /* Immediate is prefered as second argument by most architectures. */ - switch (condition) { - case SLJIT_LESS: - condition = SLJIT_GREATER; - break; - case SLJIT_GREATER_EQUAL: - condition = SLJIT_LESS_EQUAL; - break; - case SLJIT_GREATER: - condition = SLJIT_LESS; - break; - case SLJIT_LESS_EQUAL: - condition = SLJIT_GREATER_EQUAL; - break; - case SLJIT_SIG_LESS: - condition = SLJIT_SIG_GREATER; - break; - case SLJIT_SIG_GREATER_EQUAL: - condition = SLJIT_SIG_LESS_EQUAL; - break; - case SLJIT_SIG_GREATER: - condition = SLJIT_SIG_LESS; - break; - case SLJIT_SIG_LESS_EQUAL: - condition = SLJIT_SIG_GREATER_EQUAL; - break; - } - type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); - tmp_src = src1; - src1 = src2; - src2 = tmp_src; - tmp_srcw = src1w; - src1w = src2w; - src2w = tmp_srcw; - } - - if (condition <= SLJIT_NOT_ZERO) - flags = SLJIT_SET_E; - else if (condition <= SLJIT_LESS_EQUAL) - flags = SLJIT_SET_U; - else - flags = SLJIT_SET_S; - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), - SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si flags, condition; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); - - condition = type & 0xff; - flags = (condition <= SLJIT_D_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; - if (type & SLJIT_SINGLE_OP) - flags |= SLJIT_SINGLE_OP; - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - sljit_emit_fop1(compiler, SLJIT_DCMP | flags, src1, src1w, src2, src2w); - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); -} - -#endif - -#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) -{ - CHECK_ERROR(); - CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); - - ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - if (offset != 0) - return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset); - return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0); -} - -#endif - -#else /* SLJIT_CONFIG_UNSUPPORTED */ - -/* Empty function bodies for those machines, which are not (yet) supported. */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "unsupported"; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) -{ - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(size); - SLJIT_ASSERT_STOP(); - return NULL; -} - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(verbose); - SLJIT_ASSERT_STOP(); -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) -{ - SLJIT_UNUSED_ARG(code); - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - SLJIT_ASSERT_STOP(); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(instruction); - SLJIT_UNUSED_ARG(size); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ - SLJIT_ASSERT_STOP(); - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(label); - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(target); - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNUSED_ARG(type); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(offset); - SLJIT_ASSERT_STOP(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(initval); - SLJIT_ASSERT_STOP(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_addr); - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_constant); - SLJIT_ASSERT_STOP(); -} - -#endif diff --git a/pcre2/src/sljit/sljitLir.h b/pcre2/src/sljit/sljitLir.h deleted file mode 100644 index 2e2e9ac09..000000000 --- a/pcre2/src/sljit/sljitLir.h +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SLJIT_LIR_H_ -#define _SLJIT_LIR_H_ - -/* - ------------------------------------------------------------------------ - Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC) - ------------------------------------------------------------------------ - - Short description - Advantages: - - The execution can be continued from any LIR instruction. In other - words, it is possible to jump to any label from anywhere, even from - a code fragment, which is compiled later, if both compiled code - shares the same context. See sljit_emit_enter for more details - - Supports self modifying code: target of (conditional) jump and call - instructions and some constant values can be dynamically modified - during runtime - - although it is not suggested to do it frequently - - can be used for inline caching: save an important value once - in the instruction stream - - since this feature limits the optimization possibilities, a - special flag must be passed at compile time when these - instructions are emitted - - A fixed stack space can be allocated for local variables - - The compiler is thread-safe - - The compiler is highly configurable through preprocessor macros. - You can disable unneeded features (multithreading in single - threaded applications), and you can use your own system functions - (including memory allocators). See sljitConfig.h - Disadvantages: - - No automatic register allocation, and temporary results are - not stored on the stack. (hence the name comes) - In practice: - - This approach is very effective for interpreters - - One of the saved registers typically points to a stack interface - - It can jump to any exception handler anytime (even if it belongs - to another function) - - Hot paths can be modified during runtime reflecting the changes - of the fastest execution path of the dynamic language - - SLJIT supports complex memory addressing modes - - mainly position and context independent code (except some cases) - - For valgrind users: - - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" -*/ - -#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG) -#include "sljitConfig.h" -#endif - -/* The following header file defines useful macros for fine tuning -sljit based code generators. They are listed in the beginning -of sljitConfigInternal.h */ - -#include "sljitConfigInternal.h" - -/* --------------------------------------------------------------------- */ -/* Error codes */ -/* --------------------------------------------------------------------- */ - -/* Indicates no error. */ -#define SLJIT_SUCCESS 0 -/* After the call of sljit_generate_code(), the error code of the compiler - is set to this value to avoid future sljit calls (in debug mode at least). - The complier should be freed after sljit_generate_code(). */ -#define SLJIT_ERR_COMPILED 1 -/* Cannot allocate non executable memory. */ -#define SLJIT_ERR_ALLOC_FAILED 2 -/* Cannot allocate executable memory. - Only for sljit_generate_code() */ -#define SLJIT_ERR_EX_ALLOC_FAILED 3 -/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */ -#define SLJIT_ERR_UNSUPPORTED 4 -/* An ivalid argument is passed to any SLJIT function. */ -#define SLJIT_ERR_BAD_ARGUMENT 5 - -/* --------------------------------------------------------------------- */ -/* Registers */ -/* --------------------------------------------------------------------- */ - -/* - Scratch (R) registers: registers whose may not preserve their values - across function calls. - - Saved (S) registers: registers whose preserve their values across - function calls. - - The scratch and saved register sets are overlap. The last scratch register - is the first saved register, the one before the last is the second saved - register, and so on. - - If an architecture provides two scratch and three saved registers, - its scratch and saved register sets are the following: - - R0 | [S4] | R0 and S4 represent the same physical register - R1 | [S3] | R1 and S3 represent the same physical register - [R2] | S2 | R2 and S2 represent the same physical register - [R3] | S1 | R3 and S1 represent the same physical register - [R4] | S0 | R4 and S0 represent the same physical register - - Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and - SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture. - - Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10 - and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers - are virtual on x86-32. See below. - - The purpose of this definition is convenience. Although a register - is either scratch register or saved register, SLJIT allows accessing - them from the other set. For example, four registers can be used as - scratch registers and the fifth one as saved register on the architecture - above. Of course the last two scratch registers (R2 and R3) from this - four will be saved on the stack, because they are defined as saved - registers in the application binary interface. Still R2 and R3 can be - used for referencing to these registers instead of S2 and S1, which - makes easier to write platform independent code. Scratch registers - can be saved registers in a similar way, but these extra saved - registers will not be preserved across function calls! Hence the - application must save them on those platforms, where the number of - saved registers is too low. This can be done by copy them onto - the stack and restore them after a function call. - - Note: To emphasize that registers assigned to R2-R4 are saved - registers, they are enclosed by square brackets. S3-S4 - are marked in a similar way. - - Note: sljit_emit_enter and sljit_set_context defines whether a register - is S or R register. E.g: when 3 scratches and 1 saved is mapped - by sljit_emit_enter, the allowed register set will be: R0-R2 and - S0. Although S2 is mapped to the same position as R2, it does not - available in the current configuration. Furthermore the R3 (S1) - register does not available as well. -*/ - -/* When SLJIT_UNUSED is specified as destination, the result is discarded. */ -#define SLJIT_UNUSED 0 - -/* Scratch registers. */ -#define SLJIT_R0 1 -#define SLJIT_R1 2 -#define SLJIT_R2 3 -/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they - are allocated on the stack). These registers are called virtual - and cannot be used for memory addressing (cannot be part of - any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such - limitation on other CPUs. See sljit_get_register_index(). */ -#define SLJIT_R3 4 -#define SLJIT_R4 5 -#define SLJIT_R5 6 -#define SLJIT_R6 7 -#define SLJIT_R7 8 -#define SLJIT_R8 9 -#define SLJIT_R9 10 -/* All R registers provided by the architecture can be accessed by SLJIT_R(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */ -#define SLJIT_R(i) (1 + (i)) - -/* Saved registers. */ -#define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS) -#define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1) -#define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2) -/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they - are allocated on the stack). These registers are called virtual - and cannot be used for memory addressing (cannot be part of - any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such - limitation on other CPUs. See sljit_get_register_index(). */ -#define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3) -#define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4) -#define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5) -#define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6) -#define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7) -#define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8) -#define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9) -/* All S registers provided by the architecture can be accessed by SLJIT_S(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */ -#define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i)) - -/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */ -#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1) - -/* The SLJIT_SP provides direct access to the linear stack space allocated by - sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP). - The immediate offset is extended by the relative stack offset automatically. - The sljit_get_local_base can be used to obtain the absolute offset. */ -#define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1) - -/* Return with machine word. */ - -#define SLJIT_RETURN_REG SLJIT_R0 - -/* x86 prefers specific registers for special purposes. In case of shift - by register it supports only SLJIT_R2 for shift argument - (which is the src2 argument of sljit_emit_op2). If another register is - used, sljit must exchange data between registers which cause a minor - slowdown. Other architectures has no such limitation. */ - -#define SLJIT_PREF_SHIFT_REG SLJIT_R2 - -/* --------------------------------------------------------------------- */ -/* Floating point registers */ -/* --------------------------------------------------------------------- */ - -/* Each floating point register can store a double or single precision - value. The FR and FS register sets are overlap in the same way as R - and S register sets. See above. */ - -/* Note: SLJIT_UNUSED as destination is not valid for floating point - operations, since they cannot be used for setting flags. */ - -/* Floating point scratch registers. */ -#define SLJIT_FR0 1 -#define SLJIT_FR1 2 -#define SLJIT_FR2 3 -#define SLJIT_FR3 4 -#define SLJIT_FR4 5 -#define SLJIT_FR5 6 -/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */ -#define SLJIT_FR(i) (1 + (i)) - -/* Floating point saved registers. */ -#define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS) -#define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1) -#define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2) -#define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3) -#define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4) -#define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5) -/* All S registers provided by the architecture can be accessed by SLJIT_FS(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ -#define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) - -/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */ -#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1) - -/* --------------------------------------------------------------------- */ -/* Main structures and functions */ -/* --------------------------------------------------------------------- */ - -/* - The following structures are private, and can be changed in the - future. Keeping them here allows code inlining. -*/ - -struct sljit_memory_fragment { - struct sljit_memory_fragment *next; - sljit_uw used_size; - /* Must be aligned to sljit_sw. */ - sljit_ub memory[1]; -}; - -struct sljit_label { - struct sljit_label *next; - sljit_uw addr; - /* The maximum size difference. */ - sljit_uw size; -}; - -struct sljit_jump { - struct sljit_jump *next; - sljit_uw addr; - sljit_sw flags; - union { - sljit_uw target; - struct sljit_label* label; - } u; -}; - -struct sljit_const { - struct sljit_const *next; - sljit_uw addr; -}; - -struct sljit_compiler { - sljit_si error; - sljit_si options; - - struct sljit_label *labels; - struct sljit_jump *jumps; - struct sljit_const *consts; - struct sljit_label *last_label; - struct sljit_jump *last_jump; - struct sljit_const *last_const; - - void *allocator_data; - struct sljit_memory_fragment *buf; - struct sljit_memory_fragment *abuf; - - /* Used scratch registers. */ - sljit_si scratches; - /* Used saved registers. */ - sljit_si saveds; - /* Used float scratch registers. */ - sljit_si fscratches; - /* Used float saved registers. */ - sljit_si fsaveds; - /* Local stack size. */ - sljit_si local_size; - /* Code size. */ - sljit_uw size; - /* For statistical purposes. */ - sljit_uw executable_size; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si args; -#endif - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si mode32; -#endif - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - sljit_si flags_saved; -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - /* Constant pool handling. */ - sljit_uw *cpool; - sljit_ub *cpool_unique; - sljit_uw cpool_diff; - sljit_uw cpool_fill; - /* Other members. */ - /* Contains pointer, "ldr pc, [...]" pairs. */ - sljit_uw patches; -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - /* Temporary fields. */ - sljit_uw shift_imm; - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) - sljit_sw imm; - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - sljit_si delay_slot; - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - sljit_si delay_slot; - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - FILE* verbose; -#endif - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_DEBUG && SLJIT_DEBUG) - /* Local size passed to the functions. */ - sljit_si logical_local_size; -#endif - -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - sljit_si skip_checks; -#endif -}; - -/* --------------------------------------------------------------------- */ -/* Main functions */ -/* --------------------------------------------------------------------- */ - -/* Creates an sljit compiler. The allocator_data is required by some - custom memory managers. This pointer is passed to SLJIT_MALLOC - and SLJIT_FREE macros. Most allocators (including the default - one) ignores this value, and it is recommended to pass NULL - as a dummy value for allocator_data. - - Returns NULL if failed. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data); - -/* Frees everything except the compiled machine code. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); - -/* Returns the current error code. If an error is occurred, future sljit - calls which uses the same compiler argument returns early with the same - error code. Thus there is no need for checking the error after every - call, it is enough to do it before the code is compiled. Removing - these checks increases the performance of the compiling process. */ -static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } - -/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except - if an error was detected before. After the error code is set - the compiler behaves as if the allocation failure happened - during an sljit function call. This can greatly simplify error - checking, since only the compiler status needs to be checked - after the compilation. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler); - -/* - Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, - and <= 128 bytes on 64 bit architectures. The memory area is owned by the - compiler, and freed by sljit_free_compiler. The returned pointer is - sizeof(sljit_sw) aligned. Excellent for allocating small blocks during - the compiling, and no need to worry about freeing them. The size is - enough to contain at most 16 pointers. If the size is outside of the range, - the function will return with NULL. However, this return value does not - indicate that there is no more memory (does not set the current error code - of the compiler to out-of-memory status). -*/ -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size); - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -/* Passing NULL disables verbose. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); -#endif - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); - -/* - After the machine code generation is finished we can retrieve the allocated - executable memory size, although this area may not be fully filled with - instructions depending on some optimizations. This function is useful only - for statistical purposes. - - Before a successful code generation, this function returns with 0. -*/ -static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } - -/* Instruction generation. Returns with any error code. If there is no - error, they return with SLJIT_SUCCESS. */ - -/* - The executable code is a function call from the viewpoint of the C - language. The function calls must obey to the ABI (Application - Binary Interface) of the platform, which specify the purpose of - all machine registers and stack handling among other things. The - sljit_emit_enter function emits the necessary instructions for - setting up a new context for the executable code and moves function - arguments to the saved registers. Furthermore the options argument - can be used to pass configuration options to the compiler. The - available options are listed before sljit_emit_enter. - - The number of sljit_sw arguments passed to the generated function - are specified in the "args" parameter. The number of arguments must - be less than or equal to 3. The first argument goes to SLJIT_S0, - the second goes to SLJIT_S1 and so on. The register set used by - the function must be declared as well. The number of scratch and - saved registers used by the function must be passed to sljit_emit_enter. - Only R registers between R0 and "scratches" argument can be used - later. E.g. if "scratches" is set to 2, the register set will be - limited to R0 and R1. The S registers and the floating point - registers ("fscratches" and "fsaveds") are specified in a similar - way. The sljit_emit_enter is also capable of allocating a stack - space for local variables. The "local_size" argument contains the - size in bytes of this local area and its staring address is stored - in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and - SLJIT_SP + local_size (exclusive) can be modified freely until - the function returns. The stack space is not initialized. - - Note: the following conditions must met: - 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS - 0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS - scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS - 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS - 0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS - fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS - - Note: every call of sljit_emit_enter and sljit_set_context - overwrites the previous context. -*/ - -/* The absolute address returned by sljit_get_local_base with -offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */ -#define SLJIT_DOUBLE_ALIGNMENT 0x00000001 - -/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ -#define SLJIT_MAX_LOCAL_SIZE 65536 - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); - -/* The machine code has a context (which contains the local stack space size, - number of used registers, etc.) which initialized by sljit_emit_enter. Several - functions (like sljit_emit_return) requres this context to be able to generate - the appropriate code. However, some code fragments (like inline cache) may have - no normal entry point so their context is unknown for the compiler. Their context - can be provided to the compiler by the sljit_set_context function. - - Note: every call of sljit_emit_enter and sljit_set_context overwrites - the previous context. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); - -/* Return from machine code. The op argument can be SLJIT_UNUSED which means the - function does not return with anything or any opcode between SLJIT_MOV and - SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op - is SLJIT_UNUSED, otherwise see below the description about source and - destination arguments. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, - sljit_si src, sljit_sw srcw); - -/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and - even the stack frame is passed to the callee. The return address is preserved in - dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function - is sljit_p), and sljit_emit_fast_return can use this as a return value later. */ - -/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine - instructions are needed. Excellent for small uility functions, where saving registers - and setting up a new stack frame would cost too much performance. However, it is still - possible to return to the address of the caller (or anywhere else). */ - -/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */ - -/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, - since many architectures do clever branch prediction on call / return instruction pairs. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw); - -/* - Source and destination values for arithmetical instructions - imm - a simple immediate value (cannot be used as a destination) - reg - any of the registers (immediate argument must be 0) - [imm] - absolute immediate memory address - [reg+imm] - indirect memory address - [reg+(reg<addr; } -static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } -static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; } - -/* Only the address is required to rewrite the code. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant); - -/* --------------------------------------------------------------------- */ -/* Miscellaneous utility functions */ -/* --------------------------------------------------------------------- */ - -#define SLJIT_MAJOR_VERSION 0 -#define SLJIT_MINOR_VERSION 93 - -/* Get the human readable name of the platform. Can be useful on platforms - like ARM, where ARM and Thumb2 functions can be mixed, and - it is useful to know the type of the code generator. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); - -/* Portable helper function to get an offset of a member. */ -#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) - -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) -/* This global lock is useful to compile common functions. */ -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void); -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void); -#endif - -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) - -/* The sljit_stack is a utiliy feature of sljit, which allocates a - writable memory region between base (inclusive) and limit (exclusive). - Both base and limit is a pointer, and base is always <= than limit. - This feature uses the "address space reserve" feature - of modern operating systems. Basically we don't need to allocate a - huge memory block in one step for the worst case, we can start with - a smaller chunk and extend it later. Since the address space is - reserved, the data never copied to other regions, thus it is safe - to store pointers here. */ - -/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more). - Note: stack growing should not happen in small steps: 4k, 16k or even - bigger growth is better. - Note: this structure may not be supported by all operating systems. - Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK - is not defined. */ - -struct sljit_stack { - /* User data, anything can be stored here. - Starting with the same value as base. */ - sljit_uw top; - /* These members are read only. */ - sljit_uw base; - sljit_uw limit; - sljit_uw max_limit; -}; - -/* Returns NULL if unsuccessful. - Note: limit and max_limit contains the size for stack allocation. - Note: the top field is initialized to base. - Note: see sljit_create_compiler for the explanation of allocator_data. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data); -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data); - -/* Can be used to increase (allocate) or decrease (free) the memory area. - Returns with a non-zero value if unsuccessful. If new_limit is greater than - max_limit, it will fail. It is very easy to implement a stack data structure, - since the growth ratio can be added to the current limit, and sljit_stack_resize - will do all the necessary checks. The fields of the stack are not changed if - sljit_stack_resize fails. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_uw new_limit); - -#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */ - -#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) - -/* Get the entry address of a given function. */ -#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name) - -#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ - -/* All JIT related code should be placed in the same context (library, binary, etc.). */ - -#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name) - -/* For powerpc64, the function pointers point to a context descriptor. */ -struct sljit_function_context { - sljit_sw addr; - sljit_sw r2; - sljit_sw r11; -}; - -/* Fill the context arguments using the addr and the function. - If func_ptr is NULL, it will not be set to the address of context - If addr is NULL, the function address also comes from the func pointer. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func); - -#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ - -/* --------------------------------------------------------------------- */ -/* CPU specific functions */ -/* --------------------------------------------------------------------- */ - -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index ( >=0 ) of any SLJIT_R, - SLJIT_S and SLJIT_SP registers. - - Note: it returns with -1 for virtual registers (only on x86-32). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); - -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index of any SLJIT_FLOAT register. - - Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); - -/* Any instruction can be inserted into the instruction stream by - sljit_emit_op_custom. It has a similar purpose as inline assembly. - The size parameter must match to the instruction size of the target - architecture: - - x86: 0 < size <= 15. The instruction argument can be byte aligned. - Thumb2: if size == 2, the instruction argument must be 2 byte aligned. - if size == 4, the instruction argument must be 4 byte aligned. - Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size); - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - -/* Returns with non-zero if sse2 is available. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void); - -/* Returns with non-zero if cmov instruction is available. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); - -/* Emit a conditional mov instruction on x86 CPUs. This instruction - moves src to destination, if the condition is satisfied. Unlike - other arithmetic instructions, destination must be a register. - Before such instructions are emitted, cmov support should be - checked by sljit_x86_is_cmov_available function. - type must be between SLJIT_EQUAL and SLJIT_S_ORDERED - dst_reg must be a valid register and it can be combined - with SLJIT_INT_OP to perform 32 bit arithmetic - Flags: I - (never set any flags) - */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw); - -#endif - -#endif /* _SLJIT_LIR_H_ */ diff --git a/pcre2/src/sljit/sljitNativeARM_32.c b/pcre2/src/sljit/sljitNativeARM_32.c deleted file mode 100644 index 5cd4c71a2..000000000 --- a/pcre2/src/sljit/sljitNativeARM_32.c +++ /dev/null @@ -1,2566 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - return "ARMv7" SLJIT_CPUINFO; -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - return "ARMv5" SLJIT_CPUINFO; -#else -#error "Internal error: Unknown ARM architecture" -#endif -} - -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5) - -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) - -/* In ARM instruction words. - Cache lines are usually 32 byte aligned. */ -#define CONST_POOL_ALIGNMENT 8 -#define CONST_POOL_EMPTY 0xffffffff - -#define ALIGN_INSTRUCTION(ptr) \ - (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) -#define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) - -/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { - 0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15 -}; - -#define RM(rm) (reg_map[rm]) -#define RD(rd) (reg_map[rd] << 12) -#define RN(rn) (reg_map[rn] << 16) - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -/* The instruction includes the AL condition. - INST_NAME - CONDITIONAL remove this flag. */ -#define COND_MASK 0xf0000000 -#define CONDITIONAL 0xe0000000 -#define PUSH_POOL 0xff000000 - -/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */ -#define ADC_DP 0x5 -#define ADD_DP 0x4 -#define AND_DP 0x0 -#define B 0xea000000 -#define BIC_DP 0xe -#define BL 0xeb000000 -#define BLX 0xe12fff30 -#define BX 0xe12fff10 -#define CLZ 0xe16f0f10 -#define CMP_DP 0xa -#define BKPT 0xe1200070 -#define EOR_DP 0x1 -#define MOV_DP 0xd -#define MUL 0xe0000090 -#define MVN_DP 0xf -#define NOP 0xe1a00000 -#define ORR_DP 0xc -#define PUSH 0xe92d0000 -#define POP 0xe8bd0000 -#define RSB_DP 0x3 -#define RSC_DP 0x7 -#define SBC_DP 0x6 -#define SMULL 0xe0c00090 -#define SUB_DP 0x2 -#define UMULL 0xe0800090 -#define VABS_F32 0xeeb00ac0 -#define VADD_F32 0xee300a00 -#define VCMP_F32 0xeeb40a40 -#define VCVT_F32_S32 0xeeb80ac0 -#define VCVT_F64_F32 0xeeb70ac0 -#define VCVT_S32_F32 0xeebd0ac0 -#define VDIV_F32 0xee800a00 -#define VMOV_F32 0xeeb00a40 -#define VMOV 0xee000a10 -#define VMRS 0xeef1fa10 -#define VMUL_F32 0xee200a00 -#define VNEG_F32 0xeeb10a40 -#define VSTR_F32 0xed000a00 -#define VSUB_F32 0xee300a40 - -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -/* Arm v7 specific instructions. */ -#define MOVW 0xe3000000 -#define MOVT 0xe3400000 -#define SXTB 0xe6af0070 -#define SXTH 0xe6bf0070 -#define UXTB 0xe6ef0070 -#define UXTH 0xe6ff0070 -#endif - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - -static sljit_si push_cpool(struct sljit_compiler *compiler) -{ - /* Pushing the constant pool into the instruction stream. */ - sljit_uw* inst; - sljit_uw* cpool_ptr; - sljit_uw* cpool_end; - sljit_si i; - - /* The label could point the address after the constant pool. */ - if (compiler->last_label && compiler->last_label->size == compiler->size) - compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; - - SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!inst); - compiler->size++; - *inst = 0xff000000 | compiler->cpool_fill; - - for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!inst); - compiler->size++; - *inst = 0; - } - - cpool_ptr = compiler->cpool; - cpool_end = cpool_ptr + compiler->cpool_fill; - while (cpool_ptr < cpool_end) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!inst); - compiler->size++; - *inst = *cpool_ptr++; - } - compiler->cpool_diff = CONST_POOL_EMPTY; - compiler->cpool_fill = 0; - return SLJIT_SUCCESS; -} - -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) -{ - sljit_uw* ptr; - - if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) - FAIL_IF(push_cpool(compiler)); - - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!ptr); - compiler->size++; - *ptr = inst; - return SLJIT_SUCCESS; -} - -static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) -{ - sljit_uw* ptr; - sljit_uw cpool_index = CPOOL_SIZE; - sljit_uw* cpool_ptr; - sljit_uw* cpool_end; - sljit_ub* cpool_unique_ptr; - - if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) - FAIL_IF(push_cpool(compiler)); - else if (compiler->cpool_fill > 0) { - cpool_ptr = compiler->cpool; - cpool_end = cpool_ptr + compiler->cpool_fill; - cpool_unique_ptr = compiler->cpool_unique; - do { - if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) { - cpool_index = cpool_ptr - compiler->cpool; - break; - } - cpool_ptr++; - cpool_unique_ptr++; - } while (cpool_ptr < cpool_end); - } - - if (cpool_index == CPOOL_SIZE) { - /* Must allocate a new entry in the literal pool. */ - if (compiler->cpool_fill < CPOOL_SIZE) { - cpool_index = compiler->cpool_fill; - compiler->cpool_fill++; - } - else { - FAIL_IF(push_cpool(compiler)); - cpool_index = 0; - compiler->cpool_fill = 1; - } - } - - SLJIT_ASSERT((inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!ptr); - compiler->size++; - *ptr = inst | cpool_index; - - compiler->cpool[cpool_index] = literal; - compiler->cpool_unique[cpool_index] = 0; - if (compiler->cpool_diff == CONST_POOL_EMPTY) - compiler->cpool_diff = compiler->size; - return SLJIT_SUCCESS; -} - -static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) -{ - sljit_uw* ptr; - if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) - FAIL_IF(push_cpool(compiler)); - - SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!ptr); - compiler->size++; - *ptr = inst | compiler->cpool_fill; - - compiler->cpool[compiler->cpool_fill] = literal; - compiler->cpool_unique[compiler->cpool_fill] = 1; - compiler->cpool_fill++; - if (compiler->cpool_diff == CONST_POOL_EMPTY) - compiler->cpool_diff = compiler->size; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) -{ - /* Place for at least two instruction (doesn't matter whether the first has a literal). */ - if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) - return push_cpool(compiler); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler) -{ - /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ - SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); - return push_inst(compiler, BLX | RM(TMP_REG1)); -} - -static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size) -{ - sljit_uw diff; - sljit_uw ind; - sljit_uw counter = 0; - sljit_uw* clear_const_pool = const_pool; - sljit_uw* clear_const_pool_end = const_pool + cpool_size; - - SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT); - /* Set unused flag for all literals in the constant pool. - I.e.: unused literals can belong to branches, which can be encoded as B or BL. - We can "compress" the constant pool by discarding these literals. */ - while (clear_const_pool < clear_const_pool_end) - *clear_const_pool++ = (sljit_uw)(-1); - - while (last_pc_patch < code_ptr) { - /* Data transfer instruction with Rn == r15. */ - if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { - diff = const_pool - last_pc_patch; - ind = (*last_pc_patch) & 0xfff; - - /* Must be a load instruction with immediate offset. */ - SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); - if ((sljit_si)const_pool[ind] < 0) { - const_pool[ind] = counter; - ind = counter; - counter++; - } - else - ind = const_pool[ind]; - - SLJIT_ASSERT(diff >= 1); - if (diff >= 2 || ind > 0) { - diff = (diff + ind - 2) << 2; - SLJIT_ASSERT(diff <= 0xfff); - *last_pc_patch = (*last_pc_patch & ~0xfff) | diff; - } - else - *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004; - } - last_pc_patch++; - } - return counter; -} - -/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ -struct future_patch { - struct future_patch* next; - sljit_si index; - sljit_si value; -}; - -static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) -{ - sljit_si value; - struct future_patch *curr_patch, *prev_patch; - - SLJIT_UNUSED_ARG(compiler); - - /* Using the values generated by patch_pc_relative_loads. */ - if (!*first_patch) - value = (sljit_si)cpool_start_address[cpool_current_index]; - else { - curr_patch = *first_patch; - prev_patch = 0; - while (1) { - if (!curr_patch) { - value = (sljit_si)cpool_start_address[cpool_current_index]; - break; - } - if ((sljit_uw)curr_patch->index == cpool_current_index) { - value = curr_patch->value; - if (prev_patch) - prev_patch->next = curr_patch->next; - else - *first_patch = curr_patch->next; - SLJIT_FREE(curr_patch, compiler->allocator_data); - break; - } - prev_patch = curr_patch; - curr_patch = curr_patch->next; - } - } - - if (value >= 0) { - if ((sljit_uw)value > cpool_current_index) { - curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data); - if (!curr_patch) { - while (*first_patch) { - curr_patch = *first_patch; - *first_patch = (*first_patch)->next; - SLJIT_FREE(curr_patch, compiler->allocator_data); - } - return SLJIT_ERR_ALLOC_FAILED; - } - curr_patch->next = *first_patch; - curr_patch->index = value; - curr_patch->value = cpool_start_address[value]; - *first_patch = curr_patch; - } - cpool_start_address[value] = *buf_ptr; - } - return SLJIT_SUCCESS; -} - -#else - -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) -{ - sljit_uw* ptr; - - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); - FAIL_IF(!ptr); - compiler->size++; - *ptr = inst; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) -{ - FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); - return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); -} - -#endif - -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) -{ - sljit_sw diff; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return 0; - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (jump->flags & IS_BL) - code_ptr--; - - if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); - } - - /* Branch to Thumb code has not been optimized yet. */ - if (diff & 0x3) - return 0; - - if (jump->flags & IS_BL) { - if (diff <= 0x01ffffff && diff >= -0x02000000) { - *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK); - jump->flags |= PATCH_B; - return 1; - } - } - else { - if (diff <= 0x01ffffff && diff >= -0x02000000) { - *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); - jump->flags |= PATCH_B; - } - } -#else - if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr); - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr); - } - - /* Branch to Thumb code has not been optimized yet. */ - if (diff & 0x3) - return 0; - - if (diff <= 0x01ffffff && diff >= -0x02000000) { - code_ptr -= 2; - *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK); - jump->flags |= PATCH_B; - return 1; - } -#endif - return 0; -} - -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) -{ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw*)addr; - sljit_uw *inst = (sljit_uw*)ptr[0]; - sljit_uw mov_pc = ptr[1]; - sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); - sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); - - if (diff <= 0x7fffff && diff >= -0x800000) { - /* Turn to branch. */ - if (!bl) { - inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 1); - } - } else { - inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); - inst[1] = NOP; - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 2); - } - } - } else { - /* Get the position of the constant. */ - if (mov_pc & (1 << 23)) - ptr = inst + ((mov_pc & 0xfff) >> 2) + 2; - else - ptr = inst + 1; - - if (*inst != mov_pc) { - inst[0] = mov_pc; - if (!bl) { - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 1); - } - } else { - inst[1] = BLX | RM(TMP_REG1); - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 2); - } - } - } - *ptr = new_addr; - } -#else - sljit_uw *inst = (sljit_uw*)addr; - SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); - inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); - inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 2); - } -#endif -} - -static sljit_uw get_imm(sljit_uw imm); - -static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush) -{ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw*)addr; - sljit_uw *inst = (sljit_uw*)ptr[0]; - sljit_uw ldr_literal = ptr[1]; - sljit_uw src2; - - src2 = get_imm(new_constant); - if (src2) { - *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 1); - } - return; - } - - src2 = get_imm(~new_constant); - if (src2) { - *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 1); - } - return; - } - - if (ldr_literal & (1 << 23)) - ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2; - else - ptr = inst + 1; - - if (*inst != ldr_literal) { - *inst = ldr_literal; - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 1); - } - } - *ptr = new_constant; -#else - sljit_uw *inst = (sljit_uw*)addr; - SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); - inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); - inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); - if (flush) { - SLJIT_CACHE_FLUSH(inst, inst + 2); - } -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_uw *code; - sljit_uw *code_ptr; - sljit_uw *buf_ptr; - sljit_uw *buf_end; - sljit_uw size; - sljit_uw word_count; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw cpool_size; - sljit_uw cpool_skip_alignment; - sljit_uw cpool_current_index; - sljit_uw *cpool_start_address; - sljit_uw *last_pc_patch; - struct future_patch *first_patch; -#endif - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - /* Second code generation pass. */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - size = compiler->size + (compiler->patches << 1); - if (compiler->cpool_fill > 0) - size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; -#else - size = compiler->size; -#endif - code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - cpool_size = 0; - cpool_skip_alignment = 0; - cpool_current_index = 0; - cpool_start_address = NULL; - first_patch = NULL; - last_pc_patch = code; -#endif - - code_ptr = code; - word_count = 0; - - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - - if (label && label->size == 0) { - label->addr = (sljit_uw)code; - label->size = 0; - label = label->next; - } - - do { - buf_ptr = (sljit_uw*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 2); - do { - word_count++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (cpool_size > 0) { - if (cpool_skip_alignment > 0) { - buf_ptr++; - cpool_skip_alignment--; - } - else { - if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { - SLJIT_FREE_EXEC(code); - compiler->error = SLJIT_ERR_ALLOC_FAILED; - return NULL; - } - buf_ptr++; - if (++cpool_current_index >= cpool_size) { - SLJIT_ASSERT(!first_patch); - cpool_size = 0; - if (label && label->size == word_count) { - /* Points after the current instruction. */ - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - } - } - } - else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { -#endif - *code_ptr = *buf_ptr++; - /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (detect_jump_type(jump, code_ptr, code)) - code_ptr--; - jump->addr = (sljit_uw)code_ptr; -#else - jump->addr = (sljit_uw)(code_ptr - 2); - if (detect_jump_type(jump, code_ptr, code)) - code_ptr -= 2; -#endif - jump = jump->next; - } - if (label && label->size == word_count) { - /* code_ptr can be affected above. */ - label->addr = (sljit_uw)(code_ptr + 1); - label->size = (code_ptr + 1) - code; - label = label->next; - } - if (const_ && const_->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - const_->addr = (sljit_uw)code_ptr; -#else - const_->addr = (sljit_uw)(code_ptr - 1); -#endif - const_ = const_->next; - } - code_ptr++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - } - else { - /* Fortunately, no need to shift. */ - cpool_size = *buf_ptr++ & ~PUSH_POOL; - SLJIT_ASSERT(cpool_size > 0); - cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1); - cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); - if (cpool_current_index > 0) { - /* Unconditional branch. */ - *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); - code_ptr = cpool_start_address + cpool_current_index; - } - cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; - cpool_current_index = 0; - last_pc_patch = code_ptr; - } -#endif - } while (buf_ptr < buf_end); - buf = buf->next; - } while (buf); - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - SLJIT_ASSERT(cpool_size == 0); - if (compiler->cpool_fill > 0) { - cpool_start_address = ALIGN_INSTRUCTION(code_ptr); - cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); - if (cpool_current_index > 0) - code_ptr = cpool_start_address + cpool_current_index; - - buf_ptr = compiler->cpool; - buf_end = buf_ptr + compiler->cpool_fill; - cpool_current_index = 0; - while (buf_ptr < buf_end) { - if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { - SLJIT_FREE_EXEC(code); - compiler->error = SLJIT_ERR_ALLOC_FAILED; - return NULL; - } - buf_ptr++; - cpool_current_index++; - } - SLJIT_ASSERT(!first_patch); - } -#endif - - jump = compiler->jumps; - while (jump) { - buf_ptr = (sljit_uw*)jump->addr; - - if (jump->flags & PATCH_B) { - if (!(jump->flags & JUMP_ADDR)) { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; - } - else { - SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; - } - } - else if (jump->flags & SLJIT_REWRITABLE_JUMP) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - jump->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_uw)buf_ptr; - code_ptr[1] = *buf_ptr; - inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); - code_ptr += 2; -#else - inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif - } - else { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (jump->flags & IS_BL) - buf_ptr--; - if (*buf_ptr & (1 << 23)) - buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; - else - buf_ptr += 1; - *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; -#else - inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif - } - jump = jump->next; - } - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - const_ = compiler->consts; - while (const_) { - buf_ptr = (sljit_uw*)const_->addr; - const_->addr = (sljit_uw)code_ptr; - - code_ptr[0] = (sljit_uw)buf_ptr; - code_ptr[1] = *buf_ptr; - if (*buf_ptr & (1 << 23)) - buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; - else - buf_ptr += 1; - /* Set the value again (can be a simple constant). */ - inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0); - code_ptr += 2; - - const_ = const_->next; - } -#endif - - SLJIT_ASSERT(code_ptr - code <= (sljit_si)size); - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); - SLJIT_CACHE_FLUSH(code, code_ptr); - return code; -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -/* emit_op inp_flags. - WRITE_BACK must be the first, since it is a flag. */ -#define WRITE_BACK 0x01 -#define ALLOW_IMM 0x02 -#define ALLOW_INV_IMM 0x04 -#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) -#define ARG_TEST 0x08 - -/* Creates an index in data_transfer_insts array. */ -#define WORD_DATA 0x00 -#define BYTE_DATA 0x10 -#define HALF_DATA 0x20 -#define SIGNED_DATA 0x40 -#define LOAD_DATA 0x80 - -/* Condition: AL. */ -#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ - (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si size, i, tmp; - sljit_uw push; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - /* Push saved registers, temporary registers - stmdb sp!, {..., lr} */ - push = PUSH | (1 << 14); - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) - push |= 1 << reg_map[i]; - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) - push |= 1 << reg_map[i]; - - FAIL_IF(push_inst(compiler, push)); - - /* Stack must be aligned to 8 bytes: */ - size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - local_size = ((size + local_size + 7) & ~7) - size; - compiler->local_size = local_size; - if (local_size > 0) - FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); - - if (args >= 1) - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S0, SLJIT_UNUSED, RM(SLJIT_R0)))); - if (args >= 2) - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S1, SLJIT_UNUSED, RM(SLJIT_R1)))); - if (args >= 3) - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S2, SLJIT_UNUSED, RM(SLJIT_R2)))); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si size; - - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - compiler->local_size = ((size + local_size + 7) & ~7) - size; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si i, tmp; - sljit_uw pop; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - if (compiler->local_size > 0) - FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size)); - - /* Push saved registers, temporary registers - ldmia sp!, {..., pc} */ - pop = POP | (1 << 15); - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) - pop |= 1 << reg_map[i]; - - for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) - pop |= 1 << reg_map[i]; - - return push_inst(compiler, pop); -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -/* s/l - store/load (1 bit) - u/s - signed/unsigned (1 bit) - w/b/h/N - word/byte/half/NOT allowed (2 bit) - It contans 16 items, but not all are different. */ - -static sljit_sw data_transfer_insts[16] = { -/* s u w */ 0xe5000000 /* str */, -/* s u b */ 0xe5400000 /* strb */, -/* s u h */ 0xe10000b0 /* strh */, -/* s u N */ 0x00000000 /* not allowed */, -/* s s w */ 0xe5000000 /* str */, -/* s s b */ 0xe5400000 /* strb */, -/* s s h */ 0xe10000b0 /* strh */, -/* s s N */ 0x00000000 /* not allowed */, - -/* l u w */ 0xe5100000 /* ldr */, -/* l u b */ 0xe5500000 /* ldrb */, -/* l u h */ 0xe11000b0 /* ldrh */, -/* l u N */ 0x00000000 /* not allowed */, -/* l s w */ 0xe5100000 /* ldr */, -/* l s b */ 0xe11000d0 /* ldrsb */, -/* l s h */ 0xe11000f0 /* ldrsh */, -/* l s N */ 0x00000000 /* not allowed */, -}; - -#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \ - (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2)) -/* Normal ldr/str instruction. - Type2: ldrsb, ldrh, ldrsh */ -#define IS_TYPE1_TRANSFER(type) \ - (data_transfer_insts[(type) >> 4] & 0x04000000) -#define TYPE2_TRANSFER_IMM(imm) \ - (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) - -/* flags: */ - /* Arguments are swapped. */ -#define ARGS_SWAPPED 0x01 - /* Inverted immediate. */ -#define INV_IMM 0x02 - /* Source and destination is register. */ -#define REG_DEST 0x04 -#define REG_SOURCE 0x08 - /* One instruction is enough. */ -#define FAST_DEST 0x10 - /* Multiple instructions are required. */ -#define SLOW_DEST 0x20 -/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */ -#define SET_FLAGS (1 << 20) -/* dst: reg - src1: reg - src2: reg or imm (if allowed) - SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */ -#define SRC2_IMM (1 << 25) - -#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2))) - -#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2)) - -#define EMIT_SHIFT_INS_AND_RETURN(opcode) \ - SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \ - if (compiler->shift_imm != 0x20) { \ - SLJIT_ASSERT(src1 == TMP_REG1); \ - SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ - if (compiler->shift_imm != 0) \ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \ - } \ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) -{ - sljit_sw mul_inst; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (dst != src2) { - if (src2 & SRC2_IMM) { - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_UB) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); -#else - return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { - SLJIT_ASSERT(src2 & SRC2_IMM); - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); -#else - return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { - SLJIT_ASSERT(src2 & SRC2_IMM); - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - if (src2 & SRC2_IMM) { - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - } - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(!(flags & INV_IMM)); - SLJIT_ASSERT(!(src2 & SRC2_IMM)); - FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); - if (flags & SET_FLAGS) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); - return SLJIT_SUCCESS; - - case SLJIT_ADD: - SLJIT_ASSERT(!(flags & INV_IMM)); - EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP); - - case SLJIT_ADDC: - SLJIT_ASSERT(!(flags & INV_IMM)); - EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP); - - case SLJIT_SUB: - SLJIT_ASSERT(!(flags & INV_IMM)); - if (!(flags & ARGS_SWAPPED)) - EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP); - EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP); - - case SLJIT_SUBC: - SLJIT_ASSERT(!(flags & INV_IMM)); - if (!(flags & ARGS_SWAPPED)) - EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP); - EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP); - - case SLJIT_MUL: - SLJIT_ASSERT(!(flags & INV_IMM)); - SLJIT_ASSERT(!(src2 & SRC2_IMM)); - if (SLJIT_UNLIKELY(op & SLJIT_SET_O)) - mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12); - else - mul_inst = MUL | (reg_map[dst] << 16); - - if (dst != src2) - FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2])); - else if (dst != src1) - FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1])); - else { - /* Rm and Rd must not be the same register. */ - SLJIT_ASSERT(dst != TMP_REG1); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2]))); - FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1])); - } - - if (!(op & SLJIT_SET_O)) - return SLJIT_SUCCESS; - - /* We need to use TMP_REG3. */ - compiler->cache_arg = 0; - compiler->cache_argw = 0; - /* cmp TMP_REG2, dst asr #31. */ - return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0)); - - case SLJIT_AND: - if (!(flags & INV_IMM)) - EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP); - EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP); - - case SLJIT_OR: - SLJIT_ASSERT(!(flags & INV_IMM)); - EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP); - - case SLJIT_XOR: - SLJIT_ASSERT(!(flags & INV_IMM)); - EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP); - - case SLJIT_SHL: - EMIT_SHIFT_INS_AND_RETURN(0); - - case SLJIT_LSHR: - EMIT_SHIFT_INS_AND_RETURN(1); - - case SLJIT_ASHR: - EMIT_SHIFT_INS_AND_RETURN(2); - } - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -#undef EMIT_DATA_PROCESS_INS_AND_RETURN -#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN -#undef EMIT_SHIFT_INS_AND_RETURN - -/* Tests whether the immediate can be stored in the 12 bit imm field. - Returns with 0 if not possible. */ -static sljit_uw get_imm(sljit_uw imm) -{ - sljit_si rol; - - if (imm <= 0xff) - return SRC2_IMM | imm; - - if (!(imm & 0xff000000)) { - imm <<= 8; - rol = 8; - } - else { - imm = (imm << 24) | (imm >> 8); - rol = 0; - } - - if (!(imm & 0xff000000)) { - imm <<= 8; - rol += 4; - } - - if (!(imm & 0xf0000000)) { - imm <<= 4; - rol += 2; - } - - if (!(imm & 0xc0000000)) { - imm <<= 2; - rol += 1; - } - - if (!(imm & 0x00ffffff)) - return SRC2_IMM | (imm >> 24) | (rol << 8); - else - return 0; -} - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) -{ - sljit_uw mask; - sljit_uw imm1; - sljit_uw imm2; - sljit_si rol; - - /* Step1: Search a zero byte (8 continous zero bit). */ - mask = 0xff000000; - rol = 8; - while(1) { - if (!(imm & mask)) { - /* Rol imm by rol. */ - imm = (imm << rol) | (imm >> (32 - rol)); - /* Calculate arm rol. */ - rol = 4 + (rol >> 1); - break; - } - rol += 2; - mask >>= 2; - if (mask & 0x3) { - /* rol by 8. */ - imm = (imm << 8) | (imm >> 24); - mask = 0xff00; - rol = 24; - while (1) { - if (!(imm & mask)) { - /* Rol imm by rol. */ - imm = (imm << rol) | (imm >> (32 - rol)); - /* Calculate arm rol. */ - rol = (rol >> 1) - 8; - break; - } - rol += 2; - mask >>= 2; - if (mask & 0x3) - return 0; - } - break; - } - } - - /* The low 8 bit must be zero. */ - SLJIT_ASSERT(!(imm & 0xff)); - - if (!(imm & 0xff000000)) { - imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); - imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); - } - else if (imm & 0xc0000000) { - imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); - imm <<= 8; - rol += 4; - - if (!(imm & 0xff000000)) { - imm <<= 8; - rol += 4; - } - - if (!(imm & 0xf0000000)) { - imm <<= 4; - rol += 2; - } - - if (!(imm & 0xc0000000)) { - imm <<= 2; - rol += 1; - } - - if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); - else - return 0; - } - else { - if (!(imm & 0xf0000000)) { - imm <<= 4; - rol += 2; - } - - if (!(imm & 0xc0000000)) { - imm <<= 2; - rol += 1; - } - - imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); - imm <<= 8; - rol += 4; - - if (!(imm & 0xf0000000)) { - imm <<= 4; - rol += 2; - } - - if (!(imm & 0xc0000000)) { - imm <<= 2; - rol += 1; - } - - if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); - else - return 0; - } - - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1))); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2))); - return 1; -} -#endif - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm) -{ - sljit_uw tmp; - -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - if (!(imm & ~0xffff)) - return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); -#endif - - /* Create imm by 1 inst. */ - tmp = get_imm(imm); - if (tmp) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); - - tmp = get_imm(~imm); - if (tmp) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp)); - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - /* Create imm by 2 inst. */ - FAIL_IF(generate_int(compiler, reg, imm, 1)); - FAIL_IF(generate_int(compiler, reg, ~imm, 0)); - - /* Load integer. */ - return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm); -#else - return emit_imm(compiler, reg, imm); -#endif -} - -/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) -{ - if (value >= 0) { - value = get_imm(value); - if (value) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value)); - } - else { - value = get_imm(-value); - if (value) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value)); - } - return SLJIT_ERR_UNSUPPORTED; -} - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_uw imm; - - if (arg & SLJIT_IMM) { - imm = get_imm(argw); - if (imm) { - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm))); - return -1; - } - imm = get_imm(~argw); - if (imm) { - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm))); - return -1; - } - return 0; - } - - SLJIT_ASSERT(arg & SLJIT_MEM); - - /* Fast loads/stores. */ - if (!(arg & REG_MASK)) - return 0; - - if (arg & OFFS_REG_MASK) { - if ((argw & 0x3) != 0 && !IS_TYPE1_TRANSFER(inp_flags)) - return 0; - - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, - RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)))); - return -1; - } - - if (IS_TYPE1_TRANSFER(inp_flags)) { - if (argw >= 0 && argw <= 0xfff) { - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw))); - return -1; - } - if (argw < 0 && argw >= -0xfff) { - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw))); - return -1; - } - } - else { - if (argw >= 0 && argw <= 0xff) { - if (inp_flags & ARG_TEST) - return 1; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)))); - return -1; - } - if (argw < 0 && argw >= -0xff) { - if (inp_flags & ARG_TEST) - return 1; - argw = -argw; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)))); - return -1; - } - } - - return 0; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - /* Immediate caching is not supported as it would be an operation on constant arguments. */ - if (arg & SLJIT_IMM) - return 0; - - /* Always a simple operation. */ - if (arg & OFFS_REG_MASK) - return 0; - - if (!(arg & REG_MASK)) { - /* Immediate access. */ - if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) - return 1; - return 0; - } - - if (argw <= 0xfffff && argw >= -0xfffff) - return 0; - - if (argw == next_argw && (next_arg & SLJIT_MEM)) - return 1; - - if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) - return 1; - - return 0; -} - -#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \ - if (max_delta & 0xf00) \ - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \ - else \ - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm)))); - -#define TEST_WRITE_BACK() \ - if (inp_flags & WRITE_BACK) { \ - tmp_r = arg & REG_MASK; \ - if (reg == tmp_r) { \ - /* This can only happen for stores */ \ - /* since ldr reg, [reg, ...]! has no meaning */ \ - SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \ - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg)))); \ - reg = TMP_REG3; \ - } \ - } - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si tmp_r; - sljit_sw max_delta; - sljit_sw sign; - sljit_uw imm; - - if (arg & SLJIT_IMM) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - return load_immediate(compiler, reg, argw); - } - - SLJIT_ASSERT(arg & SLJIT_MEM); - - tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; - max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff; - - if ((arg & REG_MASK) == SLJIT_UNUSED) { - /* Write back is not used. */ - imm = (sljit_uw)(argw - compiler->cache_argw); - if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { - if (imm <= (sljit_uw)max_delta) { - sign = 1; - argw = argw - compiler->cache_argw; - } - else { - sign = 0; - argw = compiler->cache_argw - argw; - } - - GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw); - return SLJIT_SUCCESS; - } - - /* With write back, we can create some sophisticated loads, but - it is hard to decide whether we should convert downward (0s) or upward (1s). */ - imm = (sljit_uw)(argw - next_argw); - if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } - - FAIL_IF(load_immediate(compiler, tmp_r, argw)); - GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0); - return SLJIT_SUCCESS; - } - - if (arg & OFFS_REG_MASK) { - SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); - if (inp_flags & WRITE_BACK) - tmp_r = arg & REG_MASK; - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)))); - return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0))); - } - - imm = (sljit_uw)(argw - compiler->cache_argw); - if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) { - SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); - GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm); - return SLJIT_SUCCESS; - } - if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) { - SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); - imm = (sljit_uw)-(sljit_sw)imm; - GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm); - return SLJIT_SUCCESS; - } - - imm = get_imm(argw & ~max_delta); - if (imm) { - TEST_WRITE_BACK(); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm))); - GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); - return SLJIT_SUCCESS; - } - - imm = get_imm(-argw & ~max_delta); - if (imm) { - argw = -argw; - TEST_WRITE_BACK(); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm))); - GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); - return SLJIT_SUCCESS; - } - - if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { - TEST_WRITE_BACK(); - return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); - } - - if (argw == next_argw && (next_arg & SLJIT_MEM)) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - - TEST_WRITE_BACK(); - return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); - } - - imm = (sljit_uw)(argw - next_argw); - if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK]))); - - compiler->cache_arg = arg; - compiler->cache_argw = argw; - - GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0); - return SLJIT_SUCCESS; - } - - if ((arg & REG_MASK) == tmp_r) { - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } - - FAIL_IF(load_immediate(compiler, tmp_r, argw)); - return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg - arg2 goes to TMP_REG2, imm or src reg - TMP_REG3 can be used for caching - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - - /* We prefers register and simple consts. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - /* Destination check. */ - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } - else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } - else { - SLJIT_ASSERT(dst & SLJIT_MEM); - if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { - flags |= FAST_DEST; - dst_r = TMP_REG2; - } - else { - flags |= SLOW_DEST; - dst_r = 0; - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) - src1_r = src1; - else if (FAST_IS_REG(src2)) { - flags |= ARGS_SWAPPED; - src1_r = src2; - src2 = src1; - src2w = src1w; - } - else do { /* do { } while(0) is used because of breaks. */ - src1_r = 0; - if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { - /* The second check will generate a hit. */ - src2_r = get_imm(src1w); - if (src2_r) { - flags |= ARGS_SWAPPED; - src1 = src2; - src1w = src2w; - break; - } - if (inp_flags & ALLOW_INV_IMM) { - src2_r = get_imm(~src1w); - if (src2_r) { - flags |= ARGS_SWAPPED | INV_IMM; - src1 = src2; - src1w = src2w; - break; - } - } - if (GET_OPCODE(op) == SLJIT_ADD) { - src2_r = get_imm(-src1w); - if (src2_r) { - /* Note: ARGS_SWAPPED is intentionally not applied! */ - src1 = src2; - src1w = src2w; - op = SLJIT_SUB | GET_ALL_FLAGS(op); - break; - } - } - } - - if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1_r = TMP_REG1; - } - } while (0); - - /* Source 2. */ - if (src2_r == 0) { - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - dst_r = src2_r; - } - else do { /* do { } while(0) is used because of breaks. */ - if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) { - src2_r = get_imm(src2w); - if (src2_r) - break; - if (inp_flags & ALLOW_INV_IMM) { - src2_r = get_imm(~src2w); - if (src2_r) { - flags |= INV_IMM; - break; - } - } - if (GET_OPCODE(op) == SLJIT_ADD) { - src2_r = get_imm(-src2w); - if (src2_r) { - op = SLJIT_SUB | GET_ALL_FLAGS(op); - flags &= ~ARGS_SWAPPED; - break; - } - } - if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { - src2_r = get_imm(-src2w); - if (src2_r) { - op = SLJIT_ADD | GET_ALL_FLAGS(op); - flags &= ~ARGS_SWAPPED; - break; - } - } - } - - /* src2_r is 0. */ - if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { - FAIL_IF(compiler->error); - src2_r = sugg_src2_r; - } - } while (0); - } - - /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero. - If they are zero, they must not be registers. */ - if (src1_r == 0 && src2_r == 0 && dst_r == 0) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); - flags |= ARGS_SWAPPED; - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); - } - src1_r = TMP_REG1; - src2_r = TMP_REG2; - } - else if (src1_r == 0 && src2_r == 0) { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - src1_r = TMP_REG1; - } - else if (src1_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); - src1_r = TMP_REG1; - } - else if (src2_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); - src2_r = sugg_src2_r; - } - - if (dst_r == 0) - dst_r = TMP_REG2; - - if (src1_r == 0) { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); - src1_r = TMP_REG1; - } - - if (src2_r == 0) { - FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); - src2_r = sugg_src2_r; - } - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (flags & (FAST_DEST | SLOW_DEST)) { - if (flags & FAST_DEST) - FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); - else - FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); - } - return SLJIT_SUCCESS; -} - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) -extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator); -extern int __aeabi_idivmod(int numerator, int denominator); -#else -#error "Software divmod functions are needed" -#endif - -#ifdef __cplusplus -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - FAIL_IF(push_inst(compiler, BKPT)); - break; - case SLJIT_NOP: - FAIL_IF(push_inst(compiler, NOP)); - break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) - | (reg_map[SLJIT_R1] << 16) - | (reg_map[SLJIT_R0] << 12) - | (reg_map[SLJIT_R0] << 8) - | reg_map[SLJIT_R1]); -#else - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1)))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) - | (reg_map[SLJIT_R1] << 16) - | (reg_map[SLJIT_R0] << 12) - | (reg_map[SLJIT_R0] << 8) - | reg_map[TMP_REG1]); -#endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); - SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping); - - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { - FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */)); - FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */)); - } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); - -#if defined(__GNUC__) - FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); -#else -#error "Software divmod functions are needed" -#endif - - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { - FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */)); - FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */)); - } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); - return SLJIT_SUCCESS; - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); - - case SLJIT_CLZ: - return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - case SLJIT_ADDC: - case SLJIT_SUB: - case SLJIT_SUBC: - case SLJIT_OR: - case SLJIT_XOR: - return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_MUL: - return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_AND: - return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: - if (src2 & SLJIT_IMM) { - compiler->shift_imm = src2w & 0x1f; - return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); - } - else { - compiler->shift_imm = 0x20; - return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); - } - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg << 1; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - return push_inst(compiler, *(sljit_uw*)instruction); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - -/* 0 - no fpu - 1 - vfp */ -static sljit_si arm_fpu_type = -1; - -static void init_compiler(void) -{ - if (arm_fpu_type != -1) - return; - - /* TODO: Only the OS can help to determine the correct fpu type. */ - arm_fpu_type = 1; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#else - if (arm_fpu_type == -1) - init_compiler(); - return arm_fpu_type; -#endif -} - -#else - -#define arm_fpu_type 1 - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ - /* Always available. */ - return 1; -} - -#endif - -#define FPU_LOAD (1 << 20) -#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ - ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs)) -#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ - ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) - -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_sw tmp; - sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)))); - arg = SLJIT_MEM | TMP_REG1; - argw = 0; - } - - /* Fast loads and stores. */ - if ((arg & REG_MASK)) { - if (!(argw & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2)); - if (!(-argw & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2)); - } - - if (compiler->cache_arg == arg) { - tmp = argw - compiler->cache_argw; - if (!(tmp & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2)); - if (!(-tmp & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); - } - } - - if (arg & REG_MASK) { - if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0)); - } - imm = get_imm(argw & ~0x3fc); - if (imm) { - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm))); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2)); - } - imm = get_imm(-argw & ~0x3fc); - if (imm) { - argw = -argw; - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm))); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2)); - } - } - - compiler->cache_arg = arg; - compiler->cache_argw = argw; - if (arg & REG_MASK) { - FAIL_IF(load_immediate(compiler, TMP_REG1, argw)); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1]))); - } - else - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); - src = TMP_FREG1; - } - - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_SINGLE_OP, TMP_FREG1, src, 0))); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (TMP_FREG1 << 16)); - - /* Store the integer value from a VFP register. */ - return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16))); - else if (src & SLJIT_MEM) { - /* Load the integer value into a VFP register. */ - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16))); - } - - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_SINGLE_OP, dst_r, TMP_FREG1, 0))); - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); - src1 = TMP_FREG1; - } - - if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); - src2 = TMP_FREG2; - } - - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, src1, src2, 0))); - return push_inst(compiler, VMRS); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; - - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw)); - src = dst_r; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - op ^= SLJIT_SINGLE_OP; - break; - } - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); - src2 = TMP_FREG2; - } - - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); - src1 = TMP_FREG1; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); - break; - - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); - break; - - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); - break; - - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); - break; - } - - if (dst_r == TMP_FREG1) - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); - - return SLJIT_SUCCESS; -} - -#undef FPU_LOAD -#undef EMIT_FPU_DATA_TRANSFER -#undef EMIT_FPU_OPERATION - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); - - /* Memory. */ - if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) - return compiler->error; - /* TMP_REG3 is used for caching. */ - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3)))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src)))); - else if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) - FAIL_IF(compiler->error); - else { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0)); - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2)))); - } - } - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); - return push_inst(compiler, BLX | RM(TMP_REG3)); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -static sljit_uw get_cc(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: - return 0x00000000; - - case SLJIT_NOT_EQUAL: - case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: - return 0x10000000; - - case SLJIT_LESS: - case SLJIT_D_LESS: - return 0x30000000; - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - return 0x20000000; - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - return 0x80000000; - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - return 0x90000000; - - case SLJIT_SIG_LESS: - return 0xb0000000; - - case SLJIT_SIG_GREATER_EQUAL: - return 0xa0000000; - - case SLJIT_SIG_GREATER: - return 0xc0000000; - - case SLJIT_SIG_LESS_EQUAL: - return 0xd0000000; - - case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: - return 0x60000000; - - case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: - return 0x70000000; - - default: - SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); - return 0xe0000000; - } -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - /* In ARM, we don't need to touch the arguments. */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type >= SLJIT_FAST_CALL) - PTR_FAIL_IF(prepare_blx(compiler)); - PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, - type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0)); - - if (jump->flags & SLJIT_REWRITABLE_JUMP) { - jump->addr = compiler->size; - compiler->patches++; - } - - if (type >= SLJIT_FAST_CALL) { - jump->flags |= IS_BL; - PTR_FAIL_IF(emit_blx(compiler)); - } - - if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) - jump->addr = compiler->size; -#else - if (type >= SLJIT_FAST_CALL) - jump->flags |= IS_BL; - PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); - PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type))); - jump->addr = compiler->size; -#endif - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - /* In ARM, we don't need to touch the arguments. */ - if (!(src & SLJIT_IMM)) { - if (FAST_IS_REG(src)) - return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); - - SLJIT_ASSERT(src & SLJIT_MEM); - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); - return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); - } - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); - jump->u.target = srcw; - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type >= SLJIT_FAST_CALL) - FAIL_IF(prepare_blx(compiler)); - FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); - if (type >= SLJIT_FAST_CALL) - FAIL_IF(emit_blx(compiler)); -#else - FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); - FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); -#endif - jump->addr = compiler->size; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si dst_r, flags = GET_ALL_FLAGS(op); - sljit_uw cc, ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - op = GET_OPCODE(op); - cc = get_cc(type & 0xff); - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; - - if (op < SLJIT_ADD) { - FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0))); - FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc)); - return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; - } - - ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); - if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { - FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc)); - /* The condition must always be set, even if the ORR/EOR is not executed above. */ - return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; - } - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } else if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; - } - - FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc)); - FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000))); - if (dst_r == TMP_REG2) - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); - - return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si reg; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - - reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); - compiler->patches++; -#else - PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); -#endif - set_const(const_, compiler); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - inline_set_jump_addr(addr, new_addr, 1); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - inline_set_const(addr, new_constant, 1); -} diff --git a/pcre2/src/sljit/sljitNativeARM_64.c b/pcre2/src/sljit/sljitNativeARM_64.c deleted file mode 100644 index 044a675ee..000000000 --- a/pcre2/src/sljit/sljitNativeARM_64.c +++ /dev/null @@ -1,2050 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "ARM-64" SLJIT_CPUINFO; -} - -/* Length of an instruction word */ -typedef sljit_ui sljit_ins; - -#define TMP_ZERO (0) - -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5) -#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6) - -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { - 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31 -}; - -#define W_OP (1 << 31) -#define RD(rd) (reg_map[rd]) -#define RT(rt) (reg_map[rt]) -#define RN(rn) (reg_map[rn] << 5) -#define RT2(rt2) (reg_map[rt2] << 10) -#define RM(rm) (reg_map[rm] << 16) -#define VD(vd) (vd) -#define VT(vt) (vt) -#define VN(vn) ((vn) << 5) -#define VM(vm) ((vm) << 16) - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -#define ADC 0x9a000000 -#define ADD 0x8b000000 -#define ADDI 0x91000000 -#define AND 0x8a000000 -#define ANDI 0x92000000 -#define ASRV 0x9ac02800 -#define B 0x14000000 -#define B_CC 0x54000000 -#define BL 0x94000000 -#define BLR 0xd63f0000 -#define BR 0xd61f0000 -#define BRK 0xd4200000 -#define CBZ 0xb4000000 -#define CLZ 0xdac01000 -#define CSINC 0x9a800400 -#define EOR 0xca000000 -#define EORI 0xd2000000 -#define FABS 0x1e60c000 -#define FADD 0x1e602800 -#define FCMP 0x1e602000 -#define FCVT 0x1e224000 -#define FCVTZS 0x9e780000 -#define FDIV 0x1e601800 -#define FMOV 0x1e604000 -#define FMUL 0x1e600800 -#define FNEG 0x1e614000 -#define FSUB 0x1e603800 -#define LDRI 0xf9400000 -#define LDP 0xa9400000 -#define LDP_PST 0xa8c00000 -#define LSLV 0x9ac02000 -#define LSRV 0x9ac02400 -#define MADD 0x9b000000 -#define MOVK 0xf2800000 -#define MOVN 0x92800000 -#define MOVZ 0xd2800000 -#define NOP 0xd503201f -#define ORN 0xaa200000 -#define ORR 0xaa000000 -#define ORRI 0xb2000000 -#define RET 0xd65f0000 -#define SBC 0xda000000 -#define SBFM 0x93000000 -#define SCVTF 0x9e620000 -#define SDIV 0x9ac00c00 -#define SMADDL 0x9b200000 -#define SMULH 0x9b403c00 -#define STP 0xa9000000 -#define STP_PRE 0xa9800000 -#define STRI 0xf9000000 -#define STR_FI 0x3d000000 -#define STR_FR 0x3c206800 -#define STUR_FI 0x3c000000 -#define SUB 0xcb000000 -#define SUBI 0xd1000000 -#define SUBS 0xeb000000 -#define UBFM 0xd3000000 -#define UDIV 0x9ac00800 -#define UMULH 0x9bc03c00 - -/* dest_reg is the absolute name of the register - Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) -{ - FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); - FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); - FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21))); - return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21)); -} - -static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) -{ - sljit_si dst = inst[0] & 0x1f; - SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); - inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); - inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); - inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21); - inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); -} - -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) { - jump->flags |= PATCH_ABS64; - return 0; - } - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4); - - if (jump->flags & IS_COND) { - diff += sizeof(sljit_ins); - if (diff <= 0xfffff && diff >= -0x100000) { - code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1; - jump->addr -= sizeof(sljit_ins); - jump->flags |= PATCH_COND; - return 5; - } - diff -= sizeof(sljit_ins); - } - - if (diff <= 0x7ffffff && diff >= -0x8000000) { - jump->flags |= PATCH_B; - return 4; - } - - if (target_addr <= 0xffffffffl) { - if (jump->flags & IS_COND) - code_ptr[-5] -= (2 << 5); - code_ptr[-2] = code_ptr[0]; - return 2; - } - if (target_addr <= 0xffffffffffffl) { - if (jump->flags & IS_COND) - code_ptr[-5] -= (1 << 5); - jump->flags |= PATCH_ABS48; - code_ptr[-1] = code_ptr[0]; - return 1; - } - - jump->flags |= PATCH_ABS64; - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - sljit_si dst; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - - do { - buf_ptr = (sljit_ins*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 2); - do { - *code_ptr = *buf_ptr++; - /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { - jump->addr = (sljit_uw)(code_ptr - 4); - code_ptr -= detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; - } - code_ptr ++; - word_count ++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; - if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - jump->addr) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000); - buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff); - if (jump->flags & IS_COND) - buf_ptr[-1] -= (4 << 5); - break; - } - if (jump->flags & PATCH_COND) { - addr = (sljit_sw)(addr - jump->addr) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000); - buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5); - break; - } - - SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl); - SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl); - - dst = buf_ptr[0] & 0x1f; - buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5); - buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21); - if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) - buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21); - if (jump->flags & PATCH_ABS64) - buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21); - } while (0); - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); - return code; -} - -/* --------------------------------------------------------------------- */ -/* Core code generator functions. */ -/* --------------------------------------------------------------------- */ - -#define COUNT_TRAILING_ZERO(value, result) \ - result = 0; \ - if (!(value & 0xffffffff)) { \ - result += 32; \ - value >>= 32; \ - } \ - if (!(value & 0xffff)) { \ - result += 16; \ - value >>= 16; \ - } \ - if (!(value & 0xff)) { \ - result += 8; \ - value >>= 8; \ - } \ - if (!(value & 0xf)) { \ - result += 4; \ - value >>= 4; \ - } \ - if (!(value & 0x3)) { \ - result += 2; \ - value >>= 2; \ - } \ - if (!(value & 0x1)) { \ - result += 1; \ - value >>= 1; \ - } - -#define LOGICAL_IMM_CHECK 0x100 - -static sljit_ins logical_imm(sljit_sw imm, sljit_si len) -{ - sljit_si negated, ones, right; - sljit_uw mask, uimm; - sljit_ins ins; - - if (len & LOGICAL_IMM_CHECK) { - len &= ~LOGICAL_IMM_CHECK; - if (len == 32 && (imm == 0 || imm == -1)) - return 0; - if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1)) - return 0; - } - - SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) - || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1)); - uimm = (sljit_uw)imm; - while (1) { - if (len <= 0) { - SLJIT_ASSERT_STOP(); - return 0; - } - mask = ((sljit_uw)1 << len) - 1; - if ((uimm & mask) != ((uimm >> len) & mask)) - break; - len >>= 1; - } - - len <<= 1; - - negated = 0; - if (uimm & 0x1) { - negated = 1; - uimm = ~uimm; - } - - if (len < 64) - uimm &= ((sljit_uw)1 << len) - 1; - - /* Unsigned right shift. */ - COUNT_TRAILING_ZERO(uimm, right); - - /* Signed shift. We also know that the highest bit is set. */ - imm = (sljit_sw)~uimm; - SLJIT_ASSERT(imm < 0); - - COUNT_TRAILING_ZERO(imm, ones); - - if (~imm) - return 0; - - if (len == 64) - ins = 1 << 22; - else - ins = (0x3f - ((len << 1) - 1)) << 10; - - if (negated) - return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16); - - return ins | ((ones - 1) << 10) | ((len - right) << 16); -} - -#undef COUNT_TRAILING_ZERO - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm) -{ - sljit_uw imm = (sljit_uw)simm; - sljit_si i, zeros, ones, first; - sljit_ins bitmask; - - if (imm <= 0xffff) - return push_inst(compiler, MOVZ | RD(dst) | (imm << 5)); - - if (simm >= -0x10000 && simm < 0) - return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)); - - if (imm <= 0xffffffffl) { - if ((imm & 0xffff0000l) == 0xffff0000) - return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5)); - if ((imm & 0xffff) == 0xffff) - return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); - bitmask = logical_imm(simm, 16); - if (bitmask != 0) - return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask); - } - else { - bitmask = logical_imm(simm, 32); - if (bitmask != 0) - return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask); - } - - if (imm <= 0xffffffffl) { - FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); - return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); - } - - if (simm >= -0x100000000l && simm < 0) { - FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5))); - return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); - } - - /* A large amount of number can be constructed from ORR and MOVx, - but computing them is costly. We don't */ - - zeros = 0; - ones = 0; - for (i = 4; i > 0; i--) { - if ((simm & 0xffff) == 0) - zeros++; - if ((simm & 0xffff) == 0xffff) - ones++; - simm >>= 16; - } - - simm = (sljit_sw)imm; - first = 1; - if (ones > zeros) { - simm = ~simm; - for (i = 0; i < 4; i++) { - if (!(simm & 0xffff)) { - simm >>= 16; - continue; - } - if (first) { - first = 0; - FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); - } - else - FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21))); - simm >>= 16; - } - return SLJIT_SUCCESS; - } - - for (i = 0; i < 4; i++) { - if (!(simm & 0xffff)) { - simm >>= 16; - continue; - } - if (first) { - first = 0; - FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); - } - else - FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); - simm >>= 16; - } - return SLJIT_SUCCESS; -} - -#define ARG1_IMM 0x0010000 -#define ARG2_IMM 0x0020000 -#define INT_OP 0x0040000 -#define SET_FLAGS 0x0080000 -#define UNUSED_RETURN 0x0100000 -#define SLOW_DEST 0x0200000 -#define SLOW_SRC1 0x0400000 -#define SLOW_SRC2 0x0800000 - -#define CHECK_FLAGS(flag_bits) \ - if (flags & SET_FLAGS) { \ - inv_bits |= flag_bits; \ - if (flags & UNUSED_RETURN) \ - dst = TMP_ZERO; \ - } - -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2) -{ - /* dst must be register, TMP_REG1 - arg1 must be register, TMP_REG1, imm - arg2 must be register, TMP_REG2, imm */ - sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; - sljit_ins inst_bits; - sljit_si op = (flags & 0xffff); - sljit_si reg; - sljit_sw imm, nimm; - - if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { - /* Both are immediates. */ - flags &= ~ARG1_IMM; - if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB) - arg1 = TMP_ZERO; - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); - arg1 = TMP_REG1; - } - } - - if (flags & (ARG1_IMM | ARG2_IMM)) { - reg = (flags & ARG2_IMM) ? arg1 : arg2; - imm = (flags & ARG2_IMM) ? arg2 : arg1; - - switch (op) { - case SLJIT_MUL: - case SLJIT_NEG: - case SLJIT_CLZ: - case SLJIT_ADDC: - case SLJIT_SUBC: - /* No form with immediate operand (except imm 0, which - is represented by a ZERO register). */ - break; - case SLJIT_MOV: - SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); - return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - SLJIT_ASSERT(flags & ARG2_IMM); - FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); - goto set_flags; - case SLJIT_SUB: - if (flags & ARG1_IMM) - break; - imm = -imm; - /* Fall through. */ - case SLJIT_ADD: - if (imm == 0) { - CHECK_FLAGS(1 << 29); - return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg)); - } - if (imm > 0 && imm <= 0xfff) { - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10)); - } - nimm = -imm; - if (nimm > 0 && nimm <= 0xfff) { - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10)); - } - if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) { - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)); - } - if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) { - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)); - } - if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) { - FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22))); - return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10)); - } - if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) { - FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22))); - return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10)); - } - break; - case SLJIT_AND: - inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); - if (!inst_bits) - break; - CHECK_FLAGS(3 << 29); - return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); - case SLJIT_OR: - case SLJIT_XOR: - inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); - if (!inst_bits) - break; - if (op == SLJIT_OR) - inst_bits |= ORRI; - else - inst_bits |= EORI; - FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg))); - goto set_flags; - case SLJIT_SHL: - if (flags & ARG1_IMM) - break; - if (flags & INT_OP) { - imm &= 0x1f; - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10))); - } - else { - imm &= 0x3f; - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10))); - } - goto set_flags; - case SLJIT_LSHR: - case SLJIT_ASHR: - if (flags & ARG1_IMM) - break; - if (op == SLJIT_ASHR) - inv_bits |= 1 << 30; - if (flags & INT_OP) { - imm &= 0x1f; - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10))); - } - else { - imm &= 0x3f; - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10))); - } - goto set_flags; - default: - SLJIT_ASSERT_STOP(); - break; - } - - if (flags & ARG2_IMM) { - if (arg2 == 0) - arg2 = TMP_ZERO; - else { - FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); - arg2 = TMP_REG2; - } - } - else { - if (arg1 == 0) - arg1 = TMP_ZERO; - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); - arg1 = TMP_REG1; - } - } - } - - /* Both arguments are registers. */ - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: - case SLJIT_MOVU: - case SLJIT_MOVU_P: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (dst == arg2) - return SLJIT_SUCCESS; - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; - return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; - return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_UI: - case SLJIT_MOVU_UI: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if ((flags & INT_OP) && dst == arg2) - return SLJIT_SUCCESS; - return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_SI: - case SLJIT_MOVU_SI: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if ((flags & INT_OP) && dst == arg2) - return SLJIT_SUCCESS; - return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG1); - FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); - goto set_flags; - case SLJIT_NEG: - SLJIT_ASSERT(arg1 == TMP_REG1); - if (flags & SET_FLAGS) - inv_bits |= 1 << 29; - return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_CLZ: - SLJIT_ASSERT(arg1 == TMP_REG1); - FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2))); - goto set_flags; - case SLJIT_ADD: - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); - case SLJIT_ADDC: - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); - case SLJIT_SUB: - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); - case SLJIT_SUBC: - CHECK_FLAGS(1 << 29); - return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); - case SLJIT_MUL: - if (!(flags & SET_FLAGS)) - return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)); - if (flags & INT_OP) { - FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10))); - FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10))); - return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); - } - FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2))); - FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO))); - return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); - case SLJIT_AND: - CHECK_FLAGS(3 << 29); - return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); - case SLJIT_OR: - FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); - goto set_flags; - case SLJIT_XOR: - FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); - goto set_flags; - case SLJIT_SHL: - FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); - goto set_flags; - case SLJIT_LSHR: - FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); - goto set_flags; - case SLJIT_ASHR: - FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); - goto set_flags; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - -set_flags: - if (flags & SET_FLAGS) - return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO)); - return SLJIT_SUCCESS; -} - -#define STORE 0x01 -#define SIGNED 0x02 - -#define UPDATE 0x04 -#define ARG_TEST 0x08 - -#define BYTE_SIZE 0x000 -#define HALF_SIZE 0x100 -#define INT_SIZE 0x200 -#define WORD_SIZE 0x300 - -#define MEM_SIZE_SHIFT(flags) ((flags) >> 8) - -static SLJIT_CONST sljit_ins sljit_mem_imm[4] = { -/* u l */ 0x39400000 /* ldrb [reg,imm] */, -/* u s */ 0x39000000 /* strb [reg,imm] */, -/* s l */ 0x39800000 /* ldrsb [reg,imm] */, -/* s s */ 0x39000000 /* strb [reg,imm] */, -}; - -static SLJIT_CONST sljit_ins sljit_mem_simm[4] = { -/* u l */ 0x38400000 /* ldurb [reg,imm] */, -/* u s */ 0x38000000 /* sturb [reg,imm] */, -/* s l */ 0x38800000 /* ldursb [reg,imm] */, -/* s s */ 0x38000000 /* sturb [reg,imm] */, -}; - -static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = { -/* u l */ 0x38400c00 /* ldrb [reg,imm]! */, -/* u s */ 0x38000c00 /* strb [reg,imm]! */, -/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, -/* s s */ 0x38000c00 /* strb [reg,imm]! */, -}; - -static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { -/* u l */ 0x38606800 /* ldrb [reg,reg] */, -/* u s */ 0x38206800 /* strb [reg,reg] */, -/* s l */ 0x38a06800 /* ldrsb [reg,reg] */, -/* s s */ 0x38206800 /* strb [reg,reg] */, -}; - -/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) -{ - if (value >= 0) { - if (value <= 0xfff) - return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10)); - if (value <= 0xffffff && !(value & 0xfff)) - return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); - } - else { - value = -value; - if (value <= 0xfff) - return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10)); - if (value <= 0xffffff && !(value & 0xfff)) - return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); - } - return SLJIT_ERR_UNSUPPORTED; -} - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_ui shift = MEM_SIZE_SHIFT(flags); - - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (SLJIT_UNLIKELY(flags & UPDATE)) { - if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) { - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - arg &= REG_MASK; - argw &= 0x1ff; - FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3] - | (shift << 30) | RT(reg) | RN(arg) | (argw << 12))); - return -1; - } - return 0; - } - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - if (argw && argw != shift) - return 0; - - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) - | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0))); - return -1; - } - - arg &= REG_MASK; - if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) { - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) - | RT(reg) | RN(arg) | (argw << (10 - shift)))); - return -1; - } - - if (argw > 255 || argw < -256) - return 0; - - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) - | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12))); - return -1; -} - -/* see getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_sw diff; - if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) - return 0; - - if (!(arg & REG_MASK)) { - diff = argw - next_argw; - if (diff <= 0xfff && diff >= -0xfff) - return 1; - return 0; - } - - if (argw == next_argw) - return 1; - - diff = argw - next_argw; - if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) - return 1; - - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_ui shift = MEM_SIZE_SHIFT(flags); - sljit_si tmp_r, other_r; - sljit_sw diff; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - tmp_r = (flags & STORE) ? TMP_REG3 : reg; - - if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) { - /* Update only applies if a base register exists. */ - other_r = OFFS_REG(arg); - if (!other_r) { - other_r = arg & REG_MASK; - if (other_r != reg && argw >= 0 && argw <= 0xffffff) { - if ((argw & 0xfff) != 0) - FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); - if (argw >> 12) - FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); - } - else if (other_r != reg && argw < 0 && argw >= -0xffffff) { - argw = -argw; - if ((argw & 0xfff) != 0) - FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); - if (argw >> 12) - FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); - } - - if (compiler->cache_arg == SLJIT_MEM) { - if (argw == compiler->cache_argw) { - other_r = TMP_REG3; - argw = 0; - } - else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - other_r = TMP_REG3; - argw = 0; - } - } - - if (argw) { - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - other_r = TMP_REG3; - argw = 0; - } - } - - /* No caching here. */ - arg &= REG_MASK; - argw &= 0x3; - if (!argw || argw == shift) { - FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0))); - return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)); - } - if (arg != reg) { - FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10))); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); - } - FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10))); - FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR))); - return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR)); - } - - if (arg & OFFS_REG_MASK) { - other_r = OFFS_REG(arg); - arg &= REG_MASK; - FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10))); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r)); - } - - if (compiler->cache_arg == arg) { - diff = argw - compiler->cache_argw; - if (diff <= 255 && diff >= -256) - return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) - | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); - } - } - - if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) { - FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10))); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) - | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift))); - } - - diff = argw - next_argw; - next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0; - arg &= REG_MASK; - - if (arg && compiler->cache_arg == SLJIT_MEM) { - if (compiler->cache_argw == argw) - return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); - } - } - - compiler->cache_argw = argw; - if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_arg = SLJIT_MEM | arg; - arg = 0; - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - compiler->cache_arg = SLJIT_MEM; - - if (next_arg) { - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg))); - compiler->cache_arg = SLJIT_MEM | arg; - arg = 0; - } - } - - if (arg) - return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); - return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si i, tmp, offs, prev, saved_regs_size; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); - local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; - local_size = (local_size + 15) & ~0xf; - compiler->local_size = local_size; - - if (local_size <= (63 * sizeof(sljit_sw))) { - FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) - | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); - FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); - offs = (local_size - saved_regs_size) << (15 - 3); - } else { - offs = 0 << 15; - if (saved_regs_size & 0x8) { - offs = 1 << 15; - saved_regs_size += sizeof(sljit_sw); - } - local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; - if (saved_regs_size > 0) - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); - } - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - prev = -1; - for (i = SLJIT_S0; i >= tmp; i--) { - if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; - continue; - } - FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); - offs += 2 << 15; - prev = -1; - } - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; - continue; - } - FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); - offs += 2 << 15; - prev = -1; - } - - SLJIT_ASSERT(prev == -1); - - if (compiler->local_size > (63 * sizeof(sljit_sw))) { - /* The local_size is already adjusted by the saved registers. */ - if (local_size > 0xfff) { - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); - local_size &= 0xfff; - } - if (local_size) - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); - FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) - | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); - FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); - } - - if (args >= 1) - FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0))); - if (args >= 2) - FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1))); - if (args >= 3) - FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2))); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET; - local_size = (local_size + 15) & ~0xf; - compiler->local_size = local_size; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si local_size; - sljit_si i, tmp, offs, prev, saved_regs_size; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - local_size = compiler->local_size; - - saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); - if (local_size <= (63 * sizeof(sljit_sw))) - offs = (local_size - saved_regs_size) << (15 - 3); - else { - FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) - | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); - offs = 0 << 15; - if (saved_regs_size & 0x8) { - offs = 1 << 15; - saved_regs_size += sizeof(sljit_sw); - } - local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; - if (local_size > 0xfff) { - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); - local_size &= 0xfff; - } - if (local_size) - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); - } - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - prev = -1; - for (i = SLJIT_S0; i >= tmp; i--) { - if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; - continue; - } - FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); - offs += 2 << 15; - prev = -1; - } - - for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; - continue; - } - FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); - offs += 2 << 15; - prev = -1; - } - - SLJIT_ASSERT(prev == -1); - - if (compiler->local_size <= (63 * sizeof(sljit_sw))) { - FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) - | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); - } else if (saved_regs_size > 0) { - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); - } - - FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - return push_inst(compiler, BRK); - case SLJIT_NOP: - return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); - FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); - FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); - FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); - return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: - return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r, flags, mem_flags; - sljit_si op_flags = GET_ALL_FLAGS(op); - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - - op = GET_OPCODE(op); - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: - flags = WORD_SIZE; - break; - case SLJIT_MOV_UB: - flags = BYTE_SIZE; - if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; - break; - case SLJIT_MOV_SB: - flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; - break; - case SLJIT_MOV_UH: - flags = HALF_SIZE; - if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; - break; - case SLJIT_MOV_SH: - flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; - break; - case SLJIT_MOV_UI: - flags = INT_SIZE; - if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; - break; - case SLJIT_MOV_SI: - flags = INT_SIZE | SIGNED; - if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; - break; - case SLJIT_MOVU: - case SLJIT_MOVU_P: - flags = WORD_SIZE | UPDATE; - break; - case SLJIT_MOVU_UB: - flags = BYTE_SIZE | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; - break; - case SLJIT_MOVU_SB: - flags = BYTE_SIZE | SIGNED | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; - break; - case SLJIT_MOVU_UH: - flags = HALF_SIZE | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; - break; - case SLJIT_MOVU_SH: - flags = HALF_SIZE | SIGNED | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; - break; - case SLJIT_MOVU_UI: - flags = INT_SIZE | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; - break; - case SLJIT_MOVU_SI: - flags = INT_SIZE | SIGNED | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; - break; - default: - SLJIT_ASSERT_STOP(); - flags = 0; - break; - } - - if (src & SLJIT_IMM) - FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); - else if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) - FAIL_IF(compiler->error); - else - FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); - } else { - if (dst_r != TMP_REG1) - return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); - dst_r = src; - } - - if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) - return compiler->error; - else - return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; - } - - flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; - mem_flags = WORD_SIZE; - if (op_flags & SLJIT_INT_OP) { - flags |= INT_OP; - mem_flags = INT_SIZE; - } - - if (dst == SLJIT_UNUSED) - flags |= UNUSED_RETURN; - - if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw)) - FAIL_IF(compiler->error); - else - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw)); - src = TMP_REG2; - } - - if (src & SLJIT_IMM) { - flags |= ARG2_IMM; - if (op_flags & SLJIT_INT_OP) - srcw = (sljit_si)srcw; - } else - srcw = src; - - emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); - - if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw)) - return compiler->error; - else - return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, flags, mem_flags; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - flags = GET_FLAGS(op) ? SET_FLAGS : 0; - mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { - flags |= INT_OP; - mem_flags = INT_SIZE; - } - - if (dst == SLJIT_UNUSED) - flags |= UNUSED_RETURN; - - if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw)) - flags |= SLOW_DEST; - - if (src1 & SLJIT_MEM) { - if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - } - if (src2 & SLJIT_MEM) { - if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); - - if (src1 & SLJIT_MEM) - src1 = TMP_REG1; - if (src2 & SLJIT_MEM) - src2 = TMP_REG2; - - if (src1 & SLJIT_IMM) - flags |= ARG1_IMM; - else - src1w = src1; - if (src2 & SLJIT_IMM) - flags |= ARG2_IMM; - else - src2w = src2; - - emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw); - return compiler->error; - } - return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - return push_inst(compiler, *(sljit_ins*)instruction); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#else - /* Available by default. */ - return 1; -#endif -} - -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_ui shift = MEM_SIZE_SHIFT(flags); - sljit_ins ins_bits = (shift << 30); - sljit_si other_r; - sljit_sw diff; - - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (!(flags & STORE)) - ins_bits |= 1 << 22; - - if (arg & OFFS_REG_MASK) { - argw &= 3; - if (!argw || argw == shift) - return push_inst(compiler, STR_FR | ins_bits | VT(reg) - | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)); - other_r = OFFS_REG(arg); - arg &= REG_MASK; - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10))); - arg = TMP_REG1; - argw = 0; - } - - arg &= REG_MASK; - if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0) - return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift))); - - if (arg && argw <= 255 && argw >= -256) - return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12)); - - /* Slow cases */ - if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) { - diff = argw - compiler->cache_argw; - if (!arg && diff <= 255 && diff >= -256) - return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - } - } - - if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) { - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - } - - if (arg & REG_MASK) - return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3)); - return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; - - if (GET_OPCODE(op) == SLJIT_CONVI_FROMD) - inv_bits |= (1 << 31); - - if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); - src = TMP_FREG1; - } - - FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src))); - - if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) - return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; - - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - inv_bits |= (1 << 31); - - if (src & SLJIT_MEM) { - emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); - src = TMP_REG1; - } else if (src & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; -#endif - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - - FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; - - if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); - src1 = TMP_FREG1; - } - - if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); - src2 = TMP_FREG2; - } - - return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); - src = dst_r; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); - break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); - break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); - break; - } - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); - src1 = TMP_FREG1; - } - if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); - src2 = TMP_FREG2; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); - break; - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); - break; - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); - break; - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); - break; - } - - if (!(dst & SLJIT_MEM)) - return SLJIT_SUCCESS; - return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); -} - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); - - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); - else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw)); - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, TMP_LR, srcw)); - - return push_inst(compiler, RET | RN(TMP_LR)); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -static sljit_uw get_cc(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: - return 0x1; - - case SLJIT_NOT_EQUAL: - case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: - return 0x0; - - case SLJIT_LESS: - case SLJIT_D_LESS: - return 0x2; - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - return 0x3; - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - return 0x9; - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - return 0x8; - - case SLJIT_SIG_LESS: - return 0xa; - - case SLJIT_SIG_GREATER_EQUAL: - return 0xb; - - case SLJIT_SIG_GREATER: - return 0xd; - - case SLJIT_SIG_LESS_EQUAL: - return 0xc; - - case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: - return 0x7; - - case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: - return 0x6; - - default: - SLJIT_ASSERT_STOP(); - return 0xe; - } -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - if (type < SLJIT_JUMP) { - jump->flags |= IS_COND; - PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type))); - } - else if (type >= SLJIT_FAST_CALL) - jump->flags |= IS_BL; - - PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1))); - - return jump; -} - -static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type, - sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump; - sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0; - - SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); - ADJUST_LOCAL_OFFSET(src, srcw); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - jump->flags |= IS_CBZ | IS_COND; - - if (src & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw)); - src = TMP_REG1; - } - else if (src & SLJIT_IMM) { - PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - SLJIT_ASSERT(FAST_IS_REG(src)); - - if ((type & 0xff) == SLJIT_EQUAL) - inv_bits |= 1 << 24; - - PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src))); - PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1))); - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - /* In ARM, we don't need to touch the arguments. */ - if (!(src & SLJIT_IMM)) { - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw)); - src = TMP_REG1; - } - return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src)); - } - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); - jump->u.target = srcw; - - FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); - jump->addr = compiler->size; - return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si dst_r, flags, mem_flags; - sljit_ins cc; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - cc = get_cc(type & 0xff); - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - if (GET_OPCODE(op) < SLJIT_ADD) { - FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO))); - if (dst_r != TMP_REG1) - return SLJIT_SUCCESS; - return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw); - } - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - flags = GET_FLAGS(op) ? SET_FLAGS : 0; - mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { - flags |= INT_OP; - mem_flags = INT_SIZE; - } - - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } else if (src & SLJIT_IMM) - flags |= ARG1_IMM; - - FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO))); - emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2); - - if (dst_r != TMP_REG1) - return SLJIT_SUCCESS; - return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si dst_r; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins* inst = (sljit_ins*)addr; - modify_imm64_const(inst, new_addr); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins* inst = (sljit_ins*)addr; - modify_imm64_const(inst, new_constant); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} diff --git a/pcre2/src/sljit/sljitNativeARM_T2_32.c b/pcre2/src/sljit/sljitNativeARM_T2_32.c deleted file mode 100644 index f9803f5d4..000000000 --- a/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ /dev/null @@ -1,2090 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "ARM-Thumb2" SLJIT_CPUINFO; -} - -/* Length of an instruction word. */ -typedef sljit_ui sljit_ins; - -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5) - -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) - -/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { - 0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15 -}; - -#define COPY_BITS(src, from, to, bits) \ - ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to)) - -/* Thumb16 encodings. */ -#define RD3(rd) (reg_map[rd]) -#define RN3(rn) (reg_map[rn] << 3) -#define RM3(rm) (reg_map[rm] << 6) -#define RDN3(rdn) (reg_map[rdn] << 8) -#define IMM3(imm) (imm << 6) -#define IMM8(imm) (imm) - -/* Thumb16 helpers. */ -#define SET_REGS44(rd, rn) \ - ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4)) -#define IS_2_LO_REGS(reg1, reg2) \ - (reg_map[reg1] <= 7 && reg_map[reg2] <= 7) -#define IS_3_LO_REGS(reg1, reg2, reg3) \ - (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) - -/* Thumb32 encodings. */ -#define RD4(rd) (reg_map[rd] << 8) -#define RN4(rn) (reg_map[rn] << 16) -#define RM4(rm) (reg_map[rm]) -#define RT4(rt) (reg_map[rt] << 12) -#define DD4(dd) ((dd) << 12) -#define DN4(dn) ((dn) << 16) -#define DM4(dm) (dm) -#define IMM5(imm) \ - (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6)) -#define IMM12(imm) \ - (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)) - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -/* dot '.' changed to _ - I immediate form (possibly followed by number of immediate bits). */ -#define ADCI 0xf1400000 -#define ADCS 0x4140 -#define ADC_W 0xeb400000 -#define ADD 0x4400 -#define ADDS 0x1800 -#define ADDSI3 0x1c00 -#define ADDSI8 0x3000 -#define ADD_W 0xeb000000 -#define ADDWI 0xf2000000 -#define ADD_SP 0xb000 -#define ADD_W 0xeb000000 -#define ADD_WI 0xf1000000 -#define ANDI 0xf0000000 -#define ANDS 0x4000 -#define AND_W 0xea000000 -#define ASRS 0x4100 -#define ASRSI 0x1000 -#define ASR_W 0xfa40f000 -#define ASR_WI 0xea4f0020 -#define BICI 0xf0200000 -#define BKPT 0xbe00 -#define BLX 0x4780 -#define BX 0x4700 -#define CLZ 0xfab0f080 -#define CMPI 0x2800 -#define CMP_W 0xebb00f00 -#define EORI 0xf0800000 -#define EORS 0x4040 -#define EOR_W 0xea800000 -#define IT 0xbf00 -#define LSLS 0x4080 -#define LSLSI 0x0000 -#define LSL_W 0xfa00f000 -#define LSL_WI 0xea4f0000 -#define LSRS 0x40c0 -#define LSRSI 0x0800 -#define LSR_W 0xfa20f000 -#define LSR_WI 0xea4f0010 -#define MOV 0x4600 -#define MOVS 0x0000 -#define MOVSI 0x2000 -#define MOVT 0xf2c00000 -#define MOVW 0xf2400000 -#define MOV_W 0xea4f0000 -#define MOV_WI 0xf04f0000 -#define MUL 0xfb00f000 -#define MVNS 0x43c0 -#define MVN_W 0xea6f0000 -#define MVN_WI 0xf06f0000 -#define NOP 0xbf00 -#define ORNI 0xf0600000 -#define ORRI 0xf0400000 -#define ORRS 0x4300 -#define ORR_W 0xea400000 -#define POP 0xbc00 -#define POP_W 0xe8bd0000 -#define PUSH 0xb400 -#define PUSH_W 0xe92d0000 -#define RSB_WI 0xf1c00000 -#define RSBSI 0x4240 -#define SBCI 0xf1600000 -#define SBCS 0x4180 -#define SBC_W 0xeb600000 -#define SMULL 0xfb800000 -#define STR_SP 0x9000 -#define SUBS 0x1a00 -#define SUBSI3 0x1e00 -#define SUBSI8 0x3800 -#define SUB_W 0xeba00000 -#define SUBWI 0xf2a00000 -#define SUB_SP 0xb080 -#define SUB_WI 0xf1a00000 -#define SXTB 0xb240 -#define SXTB_W 0xfa4ff080 -#define SXTH 0xb200 -#define SXTH_W 0xfa0ff080 -#define TST 0x4200 -#define UMULL 0xfba00000 -#define UXTB 0xb2c0 -#define UXTB_W 0xfa5ff080 -#define UXTH 0xb280 -#define UXTH_W 0xfa1ff080 -#define VABS_F32 0xeeb00ac0 -#define VADD_F32 0xee300a00 -#define VCMP_F32 0xeeb40a40 -#define VCVT_F32_S32 0xeeb80ac0 -#define VCVT_F64_F32 0xeeb70ac0 -#define VCVT_S32_F32 0xeebd0ac0 -#define VDIV_F32 0xee800a00 -#define VMOV_F32 0xeeb00a40 -#define VMOV 0xee000a10 -#define VMRS 0xeef1fa10 -#define VMUL_F32 0xee200a00 -#define VNEG_F32 0xeeb10a40 -#define VSTR_F32 0xed000a00 -#define VSUB_F32 0xee300a40 - -static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) -{ - sljit_uh *ptr; - SLJIT_ASSERT(!(inst & 0xffff0000)); - - ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); - FAIL_IF(!ptr); - *ptr = inst; - compiler->size++; - return SLJIT_SUCCESS; -} - -static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) -{ - sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr++ = inst >> 16; - *ptr = inst; - compiler->size += 2; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) -{ - FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | - COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); - return push_inst32(compiler, MOVT | RD4(dst) | - COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); -} - -static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) -{ - sljit_si dst = inst[1] & 0x0f00; - SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); - inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); - inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); - inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1); - inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); -} - -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) -{ - sljit_sw diff; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return 0; - - if (jump->flags & JUMP_ADDR) { - /* Branch to ARM code is not optimized yet. */ - if (!(jump->u.target & 0x1)) - return 0; - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; - } - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1; - } - - if (jump->flags & IS_COND) { - SLJIT_ASSERT(!(jump->flags & IS_BL)); - if (diff <= 127 && diff >= -128) { - jump->flags |= PATCH_TYPE1; - return 5; - } - if (diff <= 524287 && diff >= -524288) { - jump->flags |= PATCH_TYPE2; - return 4; - } - /* +1 comes from the prefix IT instruction. */ - diff--; - if (diff <= 8388607 && diff >= -8388608) { - jump->flags |= PATCH_TYPE3; - return 3; - } - } - else if (jump->flags & IS_BL) { - if (diff <= 8388607 && diff >= -8388608) { - jump->flags |= PATCH_BL; - return 3; - } - } - else { - if (diff <= 1023 && diff >= -1024) { - jump->flags |= PATCH_TYPE4; - return 4; - } - if (diff <= 8388607 && diff >= -8388608) { - jump->flags |= PATCH_TYPE5; - return 3; - } - } - - return 0; -} - -static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) -{ - sljit_si type = (jump->flags >> 4) & 0xf; - sljit_sw diff; - sljit_uh *jump_inst; - sljit_si s, j1, j2; - - if (SLJIT_UNLIKELY(type == 0)) { - modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); - return; - } - - if (jump->flags & JUMP_ADDR) { - SLJIT_ASSERT(jump->u.target & 0x1); - diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; - } - else - diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; - jump_inst = (sljit_uh*)jump->addr; - - switch (type) { - case 1: - /* Encoding T1 of 'B' instruction */ - SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND)); - jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff); - return; - case 2: - /* Encoding T3 of 'B' instruction */ - SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND)); - jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1); - jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff); - return; - case 3: - SLJIT_ASSERT(jump->flags & IS_COND); - *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8; - diff--; - type = 5; - break; - case 4: - /* Encoding T2 of 'B' instruction */ - SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND)); - jump_inst[0] = 0xe000 | (diff & 0x7ff); - return; - } - - SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608); - - /* Really complex instruction form for branches. */ - s = (diff >> 23) & 0x1; - j1 = (~(diff >> 21) ^ s) & 0x1; - j2 = (~(diff >> 22) ^ s) & 0x1; - jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10); - jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff); - - /* The others have a common form. */ - if (type == 5) /* Encoding T4 of 'B' instruction */ - jump_inst[1] |= 0x9000; - else if (type == 6) /* Encoding T1 of 'BL' instruction */ - jump_inst[1] |= 0xd000; - else - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_uh *code; - sljit_uh *code_ptr; - sljit_uh *buf_ptr; - sljit_uh *buf_end; - sljit_uw half_count; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - half_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - - do { - buf_ptr = (sljit_uh*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 1); - do { - *code_ptr = *buf_ptr++; - /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= half_count); - SLJIT_ASSERT(!jump || jump->addr >= half_count); - SLJIT_ASSERT(!const_ || const_->addr >= half_count); - if (label && label->size == half_count) { - label->addr = ((sljit_uw)code_ptr) | 0x1; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == half_count) { - jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); - code_ptr -= detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - if (const_ && const_->addr == half_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; - } - code_ptr ++; - half_count ++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == half_count) { - label->addr = ((sljit_uw)code_ptr) | 0x1; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); - - jump = compiler->jumps; - while (jump) { - set_jump_instruction(jump); - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh); - SLJIT_CACHE_FLUSH(code, code_ptr); - /* Set thumb mode flag. */ - return (void*)((sljit_uw)code | 0x1); -} - -/* --------------------------------------------------------------------- */ -/* Core code generator functions. */ -/* --------------------------------------------------------------------- */ - -#define INVALID_IMM 0x80000000 -static sljit_uw get_imm(sljit_uw imm) -{ - /* Thumb immediate form. */ - sljit_si counter; - - if (imm <= 0xff) - return imm; - - if ((imm & 0xffff) == (imm >> 16)) { - /* Some special cases. */ - if (!(imm & 0xff00)) - return (1 << 12) | (imm & 0xff); - if (!(imm & 0xff)) - return (2 << 12) | ((imm >> 8) & 0xff); - if ((imm & 0xff00) == ((imm & 0xff) << 8)) - return (3 << 12) | (imm & 0xff); - } - - /* Assembly optimization: count leading zeroes? */ - counter = 8; - if (!(imm & 0xffff0000)) { - counter += 16; - imm <<= 16; - } - if (!(imm & 0xff000000)) { - counter += 8; - imm <<= 8; - } - if (!(imm & 0xf0000000)) { - counter += 4; - imm <<= 4; - } - if (!(imm & 0xc0000000)) { - counter += 2; - imm <<= 2; - } - if (!(imm & 0x80000000)) { - counter += 1; - imm <<= 1; - } - /* Since imm >= 128, this must be true. */ - SLJIT_ASSERT(counter <= 31); - - if (imm & 0x00ffffff) - return INVALID_IMM; /* Cannot be encoded. */ - - return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); -} - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) -{ - sljit_uw tmp; - - if (imm >= 0x10000) { - tmp = get_imm(imm); - if (tmp != INVALID_IMM) - return push_inst32(compiler, MOV_WI | RD4(dst) | tmp); - tmp = get_imm(~imm); - if (tmp != INVALID_IMM) - return push_inst32(compiler, MVN_WI | RD4(dst) | tmp); - } - - /* set low 16 bits, set hi 16 bits to 0. */ - FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | - COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); - - /* set hi 16 bit if needed. */ - if (imm >= 0x10000) - return push_inst32(compiler, MOVT | RD4(dst) | - COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); - return SLJIT_SUCCESS; -} - -#define ARG1_IMM 0x0010000 -#define ARG2_IMM 0x0020000 -#define KEEP_FLAGS 0x0040000 -/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */ -#define SET_FLAGS 0x0100000 -#define UNUSED_RETURN 0x0200000 -#define SLOW_DEST 0x0400000 -#define SLOW_SRC1 0x0800000 -#define SLOW_SRC2 0x1000000 - -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2) -{ - /* dst must be register, TMP_REG1 - arg1 must be register, TMP_REG1, imm - arg2 must be register, TMP_REG2, imm */ - sljit_si reg; - sljit_uw imm, nimm; - - if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { - /* Both are immediates. */ - flags &= ~ARG1_IMM; - FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); - arg1 = TMP_REG1; - } - - if (flags & (ARG1_IMM | ARG2_IMM)) { - reg = (flags & ARG2_IMM) ? arg1 : arg2; - imm = (flags & ARG2_IMM) ? arg2 : arg1; - - switch (flags & 0xffff) { - case SLJIT_CLZ: - case SLJIT_MUL: - /* No form with immediate operand. */ - break; - case SLJIT_MOV: - SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); - return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - if (!(flags & SET_FLAGS)) - return load_immediate(compiler, dst, ~imm); - /* Since the flags should be set, we just fallback to the register mode. - Although some clever things could be done here, "NOT IMM" does not worth the efforts. */ - break; - case SLJIT_ADD: - nimm = -imm; - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { - if (imm <= 0x7) - return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); - if (nimm <= 0x7) - return push_inst16(compiler, SUBSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); - if (reg == dst) { - if (imm <= 0xff) - return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst)); - if (nimm <= 0xff) - return push_inst16(compiler, SUBSI8 | IMM8(nimm) | RDN3(dst)); - } - } - if (!(flags & SET_FLAGS)) { - if (imm <= 0xfff) - return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm)); - if (nimm <= 0xfff) - return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm)); - } - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_ADDC: - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_SUB: - if (flags & ARG1_IMM) { - if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst)) - return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg)); - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - } - nimm = -imm; - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { - if (imm <= 0x7) - return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); - if (nimm <= 0x7) - return push_inst16(compiler, ADDSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); - if (reg == dst) { - if (imm <= 0xff) - return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst)); - if (nimm <= 0xff) - return push_inst16(compiler, ADDSI8 | IMM8(nimm) | RDN3(dst)); - } - if (imm <= 0xff && (flags & UNUSED_RETURN)) - return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg)); - } - if (!(flags & SET_FLAGS)) { - if (imm <= 0xfff) - return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm)); - if (nimm <= 0xfff) - return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm)); - } - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_SUBC: - if (flags & ARG1_IMM) - break; - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_AND: - nimm = get_imm(imm); - if (nimm != INVALID_IMM) - return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_OR: - nimm = get_imm(imm); - if (nimm != INVALID_IMM) - return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_XOR: - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); - break; - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: - if (flags & ARG1_IMM) - break; - imm &= 0x1f; - if (imm == 0) { - if (!(flags & SET_FLAGS)) - return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); - if (IS_2_LO_REGS(dst, reg)) - return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); - return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); - } - switch (flags & 0xffff) { - case SLJIT_SHL: - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) - return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6)); - return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); - case SLJIT_LSHR: - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) - return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6)); - return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); - default: /* SLJIT_ASHR */ - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) - return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6)); - return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); - } - default: - SLJIT_ASSERT_STOP(); - break; - } - - if (flags & ARG2_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); - arg2 = TMP_REG2; - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); - arg1 = TMP_REG1; - } - } - - /* Both arguments are registers. */ - switch (flags & 0xffff) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (dst == arg2) - return SLJIT_SUCCESS; - return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: - SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG1); - if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); - case SLJIT_CLZ: - SLJIT_ASSERT(arg1 == TMP_REG1); - FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2))); - if (flags & SET_FLAGS) { - if (reg_map[dst] <= 7) - return push_inst16(compiler, CMPI | RDN3(dst)); - return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst)); - } - return SLJIT_SUCCESS; - case SLJIT_ADD: - if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) - return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2)); - if (dst == arg1 && !(flags & SET_FLAGS)) - return push_inst16(compiler, ADD | SET_REGS44(dst, arg2)); - return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_ADDC: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_SUB: - if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) - return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2)); - return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_SUBC: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_MUL: - if (!(flags & SET_FLAGS)) - return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2)); - SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2); - FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2))); - /* cmp TMP_REG2, dst asr #31. */ - return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst)); - case SLJIT_AND: - if (!(flags & KEEP_FLAGS)) { - if (dst == arg1 && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2)); - if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2)) - return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2)); - } - return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_OR: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_XOR: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_SHL: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_LSHR: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - case SLJIT_ASHR: - if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -#define STORE 0x01 -#define SIGNED 0x02 - -#define WORD_SIZE 0x00 -#define BYTE_SIZE 0x04 -#define HALF_SIZE 0x08 - -#define UPDATE 0x10 -#define ARG_TEST 0x20 - -#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE))) -#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift))) - -/* - 1st letter: - w = word - b = byte - h = half - - 2nd letter: - s = signed - u = unsigned - - 3rd letter: - l = load - s = store -*/ - -static SLJIT_CONST sljit_ins sljit_mem16[12] = { -/* w u l */ 0x5800 /* ldr */, -/* w u s */ 0x5000 /* str */, -/* w s l */ 0x5800 /* ldr */, -/* w s s */ 0x5000 /* str */, - -/* b u l */ 0x5c00 /* ldrb */, -/* b u s */ 0x5400 /* strb */, -/* b s l */ 0x5600 /* ldrsb */, -/* b s s */ 0x5400 /* strb */, - -/* h u l */ 0x5a00 /* ldrh */, -/* h u s */ 0x5200 /* strh */, -/* h s l */ 0x5e00 /* ldrsh */, -/* h s s */ 0x5200 /* strh */, -}; - -static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { -/* w u l */ 0x6800 /* ldr imm5 */, -/* w u s */ 0x6000 /* str imm5 */, -/* w s l */ 0x6800 /* ldr imm5 */, -/* w s s */ 0x6000 /* str imm5 */, - -/* b u l */ 0x7800 /* ldrb imm5 */, -/* b u s */ 0x7000 /* strb imm5 */, -/* b s l */ 0x0000 /* not allowed */, -/* b s s */ 0x7000 /* strb imm5 */, - -/* h u l */ 0x8800 /* ldrh imm5 */, -/* h u s */ 0x8000 /* strh imm5 */, -/* h s l */ 0x0000 /* not allowed */, -/* h s s */ 0x8000 /* strh imm5 */, -}; - -#define MEM_IMM8 0xc00 -#define MEM_IMM12 0x800000 -static SLJIT_CONST sljit_ins sljit_mem32[12] = { -/* w u l */ 0xf8500000 /* ldr.w */, -/* w u s */ 0xf8400000 /* str.w */, -/* w s l */ 0xf8500000 /* ldr.w */, -/* w s s */ 0xf8400000 /* str.w */, - -/* b u l */ 0xf8100000 /* ldrb.w */, -/* b u s */ 0xf8000000 /* strb.w */, -/* b s l */ 0xf9100000 /* ldrsb.w */, -/* b s s */ 0xf8000000 /* strb.w */, - -/* h u l */ 0xf8300000 /* ldrh.w */, -/* h u s */ 0xf8200000 /* strsh.w */, -/* h s l */ 0xf9300000 /* ldrsh.w */, -/* h s s */ 0xf8200000 /* strsh.w */, -}; - -/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) -{ - if (value >= 0) { - if (value <= 0xfff) - return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value)); - value = get_imm(value); - if (value != INVALID_IMM) - return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value); - } - else { - value = -value; - if (value <= 0xfff) - return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value)); - value = get_imm(value); - if (value != INVALID_IMM) - return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value); - } - return SLJIT_ERR_UNSUPPORTED; -} - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_si other_r, shift; - - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (SLJIT_UNLIKELY(flags & UPDATE)) { - if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 0xff && argw >= -0xff) { - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - flags &= ~UPDATE; - arg &= 0xf; - if (argw >= 0) - argw |= 0x200; - else { - argw = -argw; - } - - SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff); - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw)); - return -1; - } - return 0; - } - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - argw &= 0x3; - other_r = OFFS_REG(arg); - arg &= 0xf; - - if (!argw && IS_3_LO_REGS(reg, arg, other_r)) - FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); - else - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); - return -1; - } - - if (!(arg & REG_MASK) || argw > 0xfff || argw < -0xff) - return 0; - - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - arg &= 0xf; - if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) { - shift = 3; - if (IS_WORD_SIZE(flags)) { - if (OFFSET_CHECK(0x1f, 2)) - shift = 2; - } - else if (flags & BYTE_SIZE) - { - if (OFFSET_CHECK(0x1f, 0)) - shift = 0; - } - else { - SLJIT_ASSERT(flags & HALF_SIZE); - if (OFFSET_CHECK(0x1f, 1)) - shift = 1; - } - - if (shift != 3) { - FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift)))); - return -1; - } - } - - /* SP based immediate. */ - if (SLJIT_UNLIKELY(arg == SLJIT_SP) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) { - FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2))); - return -1; - } - - if (argw >= 0) - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); - else - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw)); - return -1; -} - -/* see getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_sw diff; - if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) - return 0; - - if (!(arg & REG_MASK)) { - diff = argw - next_argw; - if (diff <= 0xfff && diff >= -0xfff) - return 1; - return 0; - } - - if (argw == next_argw) - return 1; - - diff = argw - next_argw; - if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) - return 1; - - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si tmp_r, other_r; - sljit_sw diff; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - tmp_r = (flags & STORE) ? TMP_REG3 : reg; - - if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) { - /* Update only applies if a base register exists. */ - /* There is no caching here. */ - other_r = OFFS_REG(arg); - arg &= 0xf; - flags &= ~UPDATE; - - if (!other_r) { - if (!(argw & ~0xfff)) { - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); - return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw)); - } - - if (compiler->cache_arg == SLJIT_MEM) { - if (argw == compiler->cache_argw) { - other_r = TMP_REG3; - argw = 0; - } - else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - other_r = TMP_REG3; - argw = 0; - } - } - - if (argw) { - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - other_r = TMP_REG3; - argw = 0; - } - } - - argw &= 0x3; - if (!argw && IS_3_LO_REGS(reg, arg, other_r)) { - FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); - return push_inst16(compiler, ADD | SET_REGS44(arg, other_r)); - } - FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); - return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(other_r) | (argw << 6)); - } - flags &= ~UPDATE; - - SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); - - if (compiler->cache_arg == arg) { - diff = argw - compiler->cache_argw; - if (!(diff & ~0xfff)) - return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | diff); - if (!((compiler->cache_argw - argw) & ~0xff)) - return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); - } - } - - next_arg = (arg & REG_MASK) && (arg == next_arg) && (argw != next_argw); - arg &= 0xf; - if (arg && compiler->cache_arg == SLJIT_MEM) { - if (compiler->cache_argw == argw) - return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); - } - } - - compiler->cache_argw = argw; - if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_arg = SLJIT_MEM | arg; - arg = 0; - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - compiler->cache_arg = SLJIT_MEM; - - diff = argw - next_argw; - if (next_arg && diff <= 0xfff && diff >= -0xfff) { - FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg))); - compiler->cache_arg = SLJIT_MEM | arg; - arg = 0; - } - } - - if (arg) - return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); - return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si size, i, tmp; - sljit_ins push; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - push = (1 << 4); - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) - push |= 1 << reg_map[i]; - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) - push |= 1 << reg_map[i]; - - FAIL_IF((push & 0xff00) - ? push_inst32(compiler, PUSH_W | (1 << 14) | push) - : push_inst16(compiler, PUSH | (1 << 8) | push)); - - /* Stack must be aligned to 8 bytes: (LR, R4) */ - size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); - local_size = ((size + local_size + 7) & ~7) - size; - compiler->local_size = local_size; - if (local_size > 0) { - if (local_size <= (127 << 2)) - FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2))); - else - FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size)); - } - - if (args >= 1) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0))); - if (args >= 2) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S1, SLJIT_R1))); - if (args >= 3) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2))); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si size; - - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); - compiler->local_size = ((size + local_size + 7) & ~7) - size; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si i, tmp; - sljit_ins pop; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - if (compiler->local_size > 0) { - if (compiler->local_size <= (127 << 2)) - FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2))); - else - FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size)); - } - - pop = (1 << 4); - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) - pop |= 1 << reg_map[i]; - - for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) - pop |= 1 << reg_map[i]; - - return (pop & 0xff00) - ? push_inst32(compiler, POP_W | (1 << 15) | pop) - : push_inst16(compiler, POP | (1 << 8) | pop); -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) -extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator); -extern int __aeabi_idivmod(int numerator, int denominator); -#else -#error "Software divmod functions are needed" -#endif - -#ifdef __cplusplus -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - sljit_sw saved_reg_list[3]; - sljit_sw saved_reg_count; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - return push_inst16(compiler, BKPT); - case SLJIT_NOP: - return push_inst16(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) - | (reg_map[SLJIT_R1] << 8) - | (reg_map[SLJIT_R0] << 12) - | (reg_map[SLJIT_R0] << 16) - | reg_map[SLJIT_R1]); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); - SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping); - - saved_reg_count = 0; - if (compiler->scratches >= 4) - saved_reg_list[saved_reg_count++] = 12; - if (compiler->scratches >= 3) - saved_reg_list[saved_reg_count++] = 2; - if (op >= SLJIT_UDIVI) - saved_reg_list[saved_reg_count++] = 1; - - if (saved_reg_count > 0) { - FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8) - | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */)); - if (saved_reg_count >= 2) { - SLJIT_ASSERT(saved_reg_list[1] < 8); - FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */)); - } - if (saved_reg_count >= 3) { - SLJIT_ASSERT(saved_reg_list[2] < 8); - FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */)); - } - } - -#if defined(__GNUC__) - FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); -#else -#error "Software divmod functions are needed" -#endif - - if (saved_reg_count > 0) { - if (saved_reg_count >= 3) { - SLJIT_ASSERT(saved_reg_list[2] < 8); - FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */)); - } - if (saved_reg_count >= 2) { - SLJIT_ASSERT(saved_reg_list[1] < 8); - FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */)); - } - return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8) - | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); - } - return SLJIT_SUCCESS; - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r, flags; - sljit_si op_flags = GET_ALL_FLAGS(op); - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - - op = GET_OPCODE(op); - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - flags = WORD_SIZE; - break; - case SLJIT_MOV_UB: - flags = BYTE_SIZE; - if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; - break; - case SLJIT_MOV_SB: - flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; - break; - case SLJIT_MOV_UH: - flags = HALF_SIZE; - if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; - break; - case SLJIT_MOV_SH: - flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; - break; - case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: - flags = WORD_SIZE | UPDATE; - break; - case SLJIT_MOVU_UB: - flags = BYTE_SIZE | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; - break; - case SLJIT_MOVU_SB: - flags = BYTE_SIZE | SIGNED | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; - break; - case SLJIT_MOVU_UH: - flags = HALF_SIZE | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; - break; - case SLJIT_MOVU_SH: - flags = HALF_SIZE | SIGNED | UPDATE; - if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; - break; - default: - SLJIT_ASSERT_STOP(); - flags = 0; - break; - } - - if (src & SLJIT_IMM) - FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); - else if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) - FAIL_IF(compiler->error); - else - FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); - } else { - if (dst_r != TMP_REG1) - return emit_op_imm(compiler, op, dst_r, TMP_REG1, src); - dst_r = src; - } - - if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) - return compiler->error; - else - return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; - } - - if (op == SLJIT_NEG) { -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw); - } - - flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); - if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw)) - FAIL_IF(compiler->error); - else - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); - src = TMP_REG2; - } - - if (src & SLJIT_IMM) - flags |= ARG2_IMM; - else - srcw = src; - - emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); - - if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) - return compiler->error; - else - return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, flags; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); - - if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) - flags |= SLOW_DEST; - - if (src1 & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - } - if (src2 & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); - - if (src1 & SLJIT_MEM) - src1 = TMP_REG1; - if (src2 & SLJIT_MEM) - src2 = TMP_REG2; - - if (src1 & SLJIT_IMM) - flags |= ARG1_IMM; - else - src1w = src1; - if (src2 & SLJIT_IMM) - flags |= ARG2_IMM; - else - src2w = src2; - - if (dst == SLJIT_UNUSED) - flags |= UNUSED_RETURN; - - emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw); - return compiler->error; - } - return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg << 1; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - if (size == 2) - return push_inst16(compiler, *(sljit_uh*)instruction); - return push_inst32(compiler, *(sljit_ins*)instruction); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#else - /* Available by default. */ - return 1; -#endif -} - -#define FPU_LOAD (1 << 20) - -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_sw tmp; - sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); - - SLJIT_ASSERT(arg & SLJIT_MEM); - - /* Fast loads and stores. */ - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6))); - arg = SLJIT_MEM | TMP_REG2; - argw = 0; - } - - if ((arg & REG_MASK) && (argw & 0x3) == 0) { - if (!(argw & ~0x3fc)) - return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2)); - if (!(-argw & ~0x3fc)) - return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2)); - } - - /* Slow cases */ - SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); - if (compiler->cache_arg == arg) { - tmp = argw - compiler->cache_argw; - if (!(tmp & ~0x3fc)) - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2)); - if (!(-tmp & ~0x3fc)) - return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); - } - } - - if (arg & REG_MASK) { - if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); - } - imm = get_imm(argw & ~0x3fc); - if (imm != INVALID_IMM) { - FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); - } - imm = get_imm(-argw & ~0x3fc); - if (imm != INVALID_IMM) { - argw = -argw; - FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); - } - } - - compiler->cache_arg = arg; - compiler->cache_argw = argw; - - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - if (arg & REG_MASK) - FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & REG_MASK)))); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); - src = TMP_FREG1; - } - - FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src))); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1)); - - /* Store the integer value from a VFP register. */ - return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); - else if (src & SLJIT_MEM) { - /* Load the integer value into a VFP register. */ - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); - } - - FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1))); - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); - src1 = TMP_FREG1; - } - - if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); - src2 = TMP_FREG2; - } - - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2))); - return push_inst32(compiler, VMRS); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; - - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); - src = dst_r; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - break; - case SLJIT_DABS: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - op ^= SLJIT_SINGLE_OP; - break; - } - - if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); - src1 = TMP_FREG1; - } - if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); - src2 = TMP_FREG2; - } - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); - break; - case SLJIT_DSUB: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); - break; - case SLJIT_DMUL: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); - break; - case SLJIT_DDIV: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); - break; - } - - if (!(dst & SLJIT_MEM)) - return SLJIT_SUCCESS; - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); -} - -#undef FPU_LOAD - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); - - /* Memory. */ - if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) - return compiler->error; - /* TMP_REG3 is used for caching. */ - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); - else if (src & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) - FAIL_IF(compiler->error); - else { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0)); - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2))); - } - } - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); - return push_inst16(compiler, BLX | RN3(TMP_REG3)); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -static sljit_uw get_cc(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: - return 0x0; - - case SLJIT_NOT_EQUAL: - case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: - return 0x1; - - case SLJIT_LESS: - case SLJIT_D_LESS: - return 0x3; - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - return 0x2; - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - return 0x8; - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - return 0x9; - - case SLJIT_SIG_LESS: - return 0xb; - - case SLJIT_SIG_GREATER_EQUAL: - return 0xa; - - case SLJIT_SIG_GREATER: - return 0xc; - - case SLJIT_SIG_LESS_EQUAL: - return 0xd; - - case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: - return 0x6; - - case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: - return 0x7; - - default: /* SLJIT_JUMP */ - SLJIT_ASSERT_STOP(); - return 0xe; - } -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - sljit_ins cc; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - /* In ARM, we don't need to touch the arguments. */ - PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); - if (type < SLJIT_JUMP) { - jump->flags |= IS_COND; - cc = get_cc(type); - jump->flags |= cc << 8; - PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - } - - jump->addr = compiler->size; - if (type <= SLJIT_JUMP) - PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1))); - else { - jump->flags |= IS_BL; - PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1))); - } - - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - /* In ARM, we don't need to touch the arguments. */ - if (!(src & SLJIT_IMM)) { - if (FAST_IS_REG(src)) - return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); - - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw)); - if (type >= SLJIT_FAST_CALL) - return push_inst16(compiler, BLX | RN3(TMP_REG1)); - } - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); - jump->u.target = srcw; - - FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); - jump->addr = compiler->size; - return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si dst_r, flags = GET_ALL_FLAGS(op); - sljit_ins cc, ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - op = GET_OPCODE(op); - cc = get_cc(type & 0xff); - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; - - if (op < SLJIT_ADD) { - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); - if (reg_map[dst_r] > 7) { - FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); - FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); - } else { - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); - } - if (dst_r != TMP_REG2) - return SLJIT_SUCCESS; - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); - } - - ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); - if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { - /* Does not change the other bits. */ - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); - if (flags & SLJIT_SET_E) { - /* The condition must always be set, even if the ORRI/EORI is not executed above. */ - if (reg_map[dst] <= 7) - return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); - return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); - } - return SLJIT_SUCCESS; - } - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); - src = TMP_REG2; - srcw = 0; - } else if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); - src = TMP_REG2; - srcw = 0; - } - - if (op == SLJIT_AND || src != dst_r) { - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); - } - else { - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); - } - - if (dst_r == TMP_REG2) - FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); - - if (flags & SLJIT_SET_E) { - /* The condition must always be set, even if the ORR/EORI is not executed above. */ - if (reg_map[dst_r] <= 7) - return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r)); - return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si dst_r; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_uh *inst = (sljit_uh*)addr; - modify_imm32_const(inst, new_addr); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_uh *inst = (sljit_uh*)addr; - modify_imm32_const(inst, new_constant); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} diff --git a/pcre2/src/sljit/sljitNativeMIPS_32.c b/pcre2/src/sljit/sljitNativeMIPS_32.c deleted file mode 100644 index b2b60d7a4..000000000 --- a/pcre2/src/sljit/sljitNativeMIPS_32.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* mips 32-bit arch dependent functions. */ - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) -{ - if (!(imm & ~0xffff)) - return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); - - if (imm < 0 && imm >= SIMM_MIN) - return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); - - FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); - return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; -} - -#define EMIT_LOGICAL(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ - } \ - else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ - } - -#define EMIT_SHIFT(op_imm, op_v) \ - if (flags & SRC2_IMM) { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ - } \ - else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \ - } - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) -{ - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); - return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); -#endif - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); - return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); -#endif - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); - return SLJIT_SUCCESS; - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); -#else - if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { - FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); - return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); - } - /* Nearly all instructions are unmovable in the following sequence. */ - FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); - /* Check zero. */ - FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst))); - /* Loop for searching the highest bit. */ - FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst))); - FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); - if (op & SLJIT_SET_E) - return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); -#endif - return SLJIT_SUCCESS; - - case SLJIT_ADD: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - else - FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - else { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - } - } - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); - } - else { - if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); - } - - /* a + b >= a | b (otherwise, the carry should be set to 1). */ - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - if (!(op & SLJIT_SET_O)) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); - - case SLJIT_ADDC: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - else { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - } - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); - } else { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); - } - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - - FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); - if (!(op & SLJIT_SET_C)) - return SLJIT_SUCCESS; - - /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - /* Set carry flag. */ - return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); - - case SLJIT_SUB: - if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - else - FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); - } - else { - if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); - if (op & SLJIT_SET_U) - FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); - if (op & SLJIT_SET_S) { - FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); - FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); - } - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) - FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); - } - - if (!(op & SLJIT_SET_O)) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); - - case SLJIT_SUBC: - if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); - } - else { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); - } - - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); - - FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); - return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; - - case SLJIT_MUL: - SLJIT_ASSERT(!(flags & SRC2_IMM)); - if (!(op & SLJIT_SET_O)) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); - return push_inst(compiler, MFLO | D(dst), DR(dst)); -#endif - } - FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); - FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); - return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); - - case SLJIT_AND: - EMIT_LOGICAL(ANDI, AND); - return SLJIT_SUCCESS; - - case SLJIT_OR: - EMIT_LOGICAL(ORI, OR); - return SLJIT_SUCCESS; - - case SLJIT_XOR: - EMIT_LOGICAL(XORI, XOR); - return SLJIT_SUCCESS; - - case SLJIT_SHL: - EMIT_SHIFT(SLL, SLLV); - return SLJIT_SUCCESS; - - case SLJIT_LSHR: - EMIT_SHIFT(SRL, SRLV); - return SLJIT_SUCCESS; - - case SLJIT_ASHR: - EMIT_SHIFT(SRA, SRAV); - return SLJIT_SUCCESS; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) -{ - FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); - return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} diff --git a/pcre2/src/sljit/sljitNativeMIPS_64.c b/pcre2/src/sljit/sljitNativeMIPS_64.c deleted file mode 100644 index 185fb5768..000000000 --- a/pcre2/src/sljit/sljitNativeMIPS_64.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* mips 64-bit arch dependent functions. */ - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) -{ - sljit_si shift = 32; - sljit_si shift2; - sljit_si inv = 0; - sljit_ins ins; - sljit_uw uimm; - - if (!(imm & ~0xffff)) - return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); - - if (imm < 0 && imm >= SIMM_MIN) - return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); - - if (imm <= 0x7fffffffl && imm >= -0x80000000l) { - FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); - return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; - } - - /* Zero extended number. */ - uimm = imm; - if (imm < 0) { - uimm = ~imm; - inv = 1; - } - - while (!(uimm & 0xff00000000000000l)) { - shift -= 8; - uimm <<= 8; - } - - if (!(uimm & 0xf000000000000000l)) { - shift -= 4; - uimm <<= 4; - } - - if (!(uimm & 0xc000000000000000l)) { - shift -= 2; - uimm <<= 2; - } - - if ((sljit_sw)uimm < 0) { - uimm >>= 1; - shift += 1; - } - SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32)); - - if (inv) - uimm = ~uimm; - - FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); - if (uimm & 0x0000ffff00000000l) - FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar)); - - imm &= (1l << shift) - 1; - if (!(imm & ~0xffff)) { - ins = (shift == 32) ? DSLL32 : DSLL; - if (shift < 32) - ins |= SH_IMM(shift); - FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar)); - return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); - } - - /* Double shifts needs to be performed. */ - uimm <<= 32; - shift2 = shift - 16; - - while (!(uimm & 0xf000000000000000l)) { - shift2 -= 4; - uimm <<= 4; - } - - if (!(uimm & 0xc000000000000000l)) { - shift2 -= 2; - uimm <<= 2; - } - - if (!(uimm & 0x8000000000000000l)) { - shift2--; - uimm <<= 1; - } - - SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16)); - - FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar)); - FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); - FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar)); - - imm &= (1l << shift2) - 1; - return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); -} - -#define SELECT_OP(a, b) \ - (!(op & SLJIT_INT_OP) ? a : b) - -#define EMIT_LOGICAL(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ - } \ - else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ - } - -#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ - if (flags & SRC2_IMM) { \ - if (src2 >= 32) { \ - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ - ins = op_dimm32; \ - src2 -= 32; \ - } \ - else \ - ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ - } \ - else { \ - ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ - } - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) -{ - sljit_ins ins; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { - FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); - return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { - FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); - return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UI: - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); - FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); - return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); - - case SLJIT_MOV_SI: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); - return SLJIT_SUCCESS; - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); -#else - if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { - FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); - return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); - } - /* Nearly all instructions are unmovable in the following sequence. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); - /* Check zero. */ - FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); - /* Loop for searching the highest bit. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); - FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); - if (op & SLJIT_SET_E) - return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); -#endif - return SLJIT_SUCCESS; - - case SLJIT_ADD: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - else - FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - else { - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - } - } - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); - } - else { - if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); - } - - /* a + b >= a | b (otherwise, the carry should be set to 1). */ - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - if (!(op & SLJIT_SET_O)) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); - - case SLJIT_ADDC: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - else { - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - } - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); - } else { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); - } - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); - if (!(op & SLJIT_SET_C)) - return SLJIT_SUCCESS; - - /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); - /* Set carry flag. */ - return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); - - case SLJIT_SUB: - if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - if (src2 >= 0) - FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - else - FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - } - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); - if (op & (SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); - } - else { - if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) - FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); - if (op & SLJIT_SET_U) - FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); - if (op & SLJIT_SET_S) { - FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); - FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); - } - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) - FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); - } - - if (!(op & SLJIT_SET_O)) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); - - case SLJIT_SUBC: - if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { - FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); - } - else { - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); - /* dst may be the same as src1 or src2. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); - } - - if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); - - FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); - return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; - - case SLJIT_MUL: - SLJIT_ASSERT(!(flags & SRC2_IMM)); - if (!(op & SLJIT_SET_O)) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op & SLJIT_INT_OP) - return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); - FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); - return push_inst(compiler, MFLO | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); - return push_inst(compiler, MFLO | D(dst), DR(dst)); -#endif - } - FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); - FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); - return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); - - case SLJIT_AND: - EMIT_LOGICAL(ANDI, AND); - return SLJIT_SUCCESS; - - case SLJIT_OR: - EMIT_LOGICAL(ORI, OR); - return SLJIT_SUCCESS; - - case SLJIT_XOR: - EMIT_LOGICAL(XORI, XOR); - return SLJIT_SUCCESS; - - case SLJIT_SHL: - EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV); - return SLJIT_SUCCESS; - - case SLJIT_LSHR: - EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV); - return SLJIT_SUCCESS; - - case SLJIT_ASHR: - EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV); - return SLJIT_SUCCESS; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) -{ - FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); - FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); - FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); - FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst))); - FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); - return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 6); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 6); -} diff --git a/pcre2/src/sljit/sljitNativeMIPS_common.c b/pcre2/src/sljit/sljitNativeMIPS_common.c deleted file mode 100644 index cf3535f81..000000000 --- a/pcre2/src/sljit/sljitNativeMIPS_common.c +++ /dev/null @@ -1,2138 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Latest MIPS architecture. */ -/* Automatically detect SLJIT_MIPS_R1 */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return "MIPS32-R1" SLJIT_CPUINFO; -#else - return "MIPS64-R1" SLJIT_CPUINFO; -#endif -#else /* SLJIT_MIPS_R1 */ - return "MIPS III" SLJIT_CPUINFO; -#endif -} - -/* Length of an instruction word - Both for mips-32 and mips-64 */ -typedef sljit_ui sljit_ins; - -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) - -/* For position independent code, t9 must contain the function address. */ -#define PIC_ADDR_REG TMP_REG2 - -/* Floating point status register. */ -#define FCSR_REG 31 -/* Return address register. */ -#define RETURN_ADDR_REG 31 - -/* Flags are kept in volatile registers. */ -#define EQUAL_FLAG 12 -/* And carry flag as well. */ -#define ULESS_FLAG 13 -#define UGREATER_FLAG 14 -#define LESS_FLAG 15 -#define GREATER_FLAG 31 -#define OVERFLOW_FLAG 1 - -#define TMP_FREG1 (0) -#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4 -}; - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -#define S(s) (reg_map[s] << 21) -#define T(t) (reg_map[t] << 16) -#define D(d) (reg_map[d] << 11) -/* Absolute registers. */ -#define SA(s) ((s) << 21) -#define TA(t) ((t) << 16) -#define DA(d) ((d) << 11) -#define FT(t) ((t) << 16) -#define FS(s) ((s) << 11) -#define FD(d) ((d) << 6) -#define IMM(imm) ((imm) & 0xffff) -#define SH_IMM(imm) ((imm) << 6) - -#define DR(dr) (reg_map[dr]) -#define HI(opcode) ((opcode) << 26) -#define LO(opcode) (opcode) -/* S = (16 << 21) D = (17 << 21) */ -#define FMT_S (16 << 21) - -#define ABS_S (HI(17) | FMT_S | LO(5)) -#define ADD_S (HI(17) | FMT_S | LO(0)) -#define ADDIU (HI(9)) -#define ADDU (HI(0) | LO(33)) -#define AND (HI(0) | LO(36)) -#define ANDI (HI(12)) -#define B (HI(4)) -#define BAL (HI(1) | (17 << 16)) -#define BC1F (HI(17) | (8 << 21)) -#define BC1T (HI(17) | (8 << 21) | (1 << 16)) -#define BEQ (HI(4)) -#define BGEZ (HI(1) | (1 << 16)) -#define BGTZ (HI(7)) -#define BLEZ (HI(6)) -#define BLTZ (HI(1) | (0 << 16)) -#define BNE (HI(5)) -#define BREAK (HI(0) | LO(13)) -#define CFC1 (HI(17) | (2 << 21)) -#define C_UN_S (HI(17) | FMT_S | LO(49)) -#define C_UEQ_S (HI(17) | FMT_S | LO(51)) -#define C_ULE_S (HI(17) | FMT_S | LO(55)) -#define C_ULT_S (HI(17) | FMT_S | LO(53)) -#define CVT_S_S (HI(17) | FMT_S | LO(32)) -#define DADDIU (HI(25)) -#define DADDU (HI(0) | LO(45)) -#define DDIV (HI(0) | LO(30)) -#define DDIVU (HI(0) | LO(31)) -#define DIV (HI(0) | LO(26)) -#define DIVU (HI(0) | LO(27)) -#define DIV_S (HI(17) | FMT_S | LO(3)) -#define DMULT (HI(0) | LO(28)) -#define DMULTU (HI(0) | LO(29)) -#define DSLL (HI(0) | LO(56)) -#define DSLL32 (HI(0) | LO(60)) -#define DSLLV (HI(0) | LO(20)) -#define DSRA (HI(0) | LO(59)) -#define DSRA32 (HI(0) | LO(63)) -#define DSRAV (HI(0) | LO(23)) -#define DSRL (HI(0) | LO(58)) -#define DSRL32 (HI(0) | LO(62)) -#define DSRLV (HI(0) | LO(22)) -#define DSUBU (HI(0) | LO(47)) -#define J (HI(2)) -#define JAL (HI(3)) -#define JALR (HI(0) | LO(9)) -#define JR (HI(0) | LO(8)) -#define LD (HI(55)) -#define LUI (HI(15)) -#define LW (HI(35)) -#define MFC1 (HI(17)) -#define MFHI (HI(0) | LO(16)) -#define MFLO (HI(0) | LO(18)) -#define MOV_S (HI(17) | FMT_S | LO(6)) -#define MTC1 (HI(17) | (4 << 21)) -#define MUL_S (HI(17) | FMT_S | LO(2)) -#define MULT (HI(0) | LO(24)) -#define MULTU (HI(0) | LO(25)) -#define NEG_S (HI(17) | FMT_S | LO(7)) -#define NOP (HI(0) | LO(0)) -#define NOR (HI(0) | LO(39)) -#define OR (HI(0) | LO(37)) -#define ORI (HI(13)) -#define SD (HI(63)) -#define SLT (HI(0) | LO(42)) -#define SLTI (HI(10)) -#define SLTIU (HI(11)) -#define SLTU (HI(0) | LO(43)) -#define SLL (HI(0) | LO(0)) -#define SLLV (HI(0) | LO(4)) -#define SRL (HI(0) | LO(2)) -#define SRLV (HI(0) | LO(6)) -#define SRA (HI(0) | LO(3)) -#define SRAV (HI(0) | LO(7)) -#define SUB_S (HI(17) | FMT_S | LO(1)) -#define SUBU (HI(0) | LO(35)) -#define SW (HI(43)) -#define TRUNC_W_S (HI(17) | FMT_S | LO(13)) -#define XOR (HI(0) | LO(38)) -#define XORI (HI(14)) - -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) -#define CLZ (HI(28) | LO(32)) -#define DCLZ (HI(28) | LO(36)) -#define MUL (HI(28) | LO(2)) -#define SEB (HI(31) | (16 << 6) | LO(32)) -#define SEH (HI(31) | (24 << 6) | LO(32)) -#endif - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define ADDU_W ADDU -#define ADDIU_W ADDIU -#define SLL_W SLL -#define SUBU_W SUBU -#else -#define ADDU_W DADDU -#define ADDIU_W DADDIU -#define SLL_W DSLL -#define SUBU_W DSUBU -#endif - -#define SIMM_MAX (0x7fff) -#define SIMM_MIN (-0x8000) -#define UIMM_MAX (0xffff) - -/* dest_reg is the absolute name of the register - Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) -{ - SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS - || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); - sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - compiler->delay_slot = delay_slot; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_ins invert_branch(sljit_si flags) -{ - return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); -} - -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - sljit_ins *inst; - sljit_ins saved_inst; - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) - return code_ptr; -#else - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return code_ptr; -#endif - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - inst = (sljit_ins*)jump->addr; - if (jump->flags & IS_COND) - inst--; - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (jump->flags & IS_CALL) - goto keep_address; -#endif - - /* B instructions. */ - if (jump->flags & IS_MOVABLE) { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; - if (diff <= SIMM_MAX && diff >= SIMM_MIN) { - jump->flags |= PATCH_B; - - if (!(jump->flags & IS_COND)) { - inst[0] = inst[-1]; - inst[-1] = (jump->flags & IS_JAL) ? BAL : B; - jump->addr -= sizeof(sljit_ins); - return inst; - } - saved_inst = inst[0]; - inst[0] = inst[-1]; - inst[-1] = saved_inst ^ invert_branch(jump->flags); - jump->addr -= 2 * sizeof(sljit_ins); - return inst; - } - } - else { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2; - if (diff <= SIMM_MAX && diff >= SIMM_MIN) { - jump->flags |= PATCH_B; - - if (!(jump->flags & IS_COND)) { - inst[0] = (jump->flags & IS_JAL) ? BAL : B; - inst[1] = NOP; - return inst + 1; - } - inst[0] = inst[0] ^ invert_branch(jump->flags); - inst[1] = NOP; - jump->addr -= sizeof(sljit_ins); - return inst + 1; - } - } - - if (jump->flags & IS_COND) { - if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) { - jump->flags |= PATCH_J; - saved_inst = inst[0]; - inst[0] = inst[-1]; - inst[-1] = (saved_inst & 0xffff0000) | 3; - inst[1] = J; - inst[2] = NOP; - return inst + 2; - } - else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { - jump->flags |= PATCH_J; - inst[0] = (inst[0] & 0xffff0000) | 3; - inst[1] = NOP; - inst[2] = J; - inst[3] = NOP; - jump->addr += sizeof(sljit_ins); - return inst + 3; - } - } - else { - /* J instuctions. */ - if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { - jump->flags |= PATCH_J; - inst[0] = inst[-1]; - inst[-1] = (jump->flags & IS_JAL) ? JAL : J; - jump->addr -= sizeof(sljit_ins); - return inst; - } - - if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { - jump->flags |= PATCH_J; - inst[0] = (jump->flags & IS_JAL) ? JAL : J; - inst[1] = NOP; - return inst + 1; - } - } - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -keep_address: - if (target_addr <= 0x7fffffff) { - jump->flags |= PATCH_ABS32; - if (jump->flags & IS_COND) { - inst[0] -= 4; - inst++; - } - inst[2] = inst[6]; - inst[3] = inst[7]; - return inst + 3; - } - if (target_addr <= 0x7fffffffffffl) { - jump->flags |= PATCH_ABS48; - if (jump->flags & IS_COND) { - inst[0] -= 2; - inst++; - } - inst[4] = inst[6]; - inst[5] = inst[7]; - return inst + 5; - } -#endif - - return code_ptr; -} - -#ifdef __GNUC__ -static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr) -{ - SLJIT_CACHE_FLUSH(code, code_ptr); -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = (sljit_ins*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 2); - do { - *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - jump->addr = (sljit_uw)(code_ptr - 3); -#else - jump->addr = (sljit_uw)(code_ptr - 7); -#endif - code_ptr = detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; - } - code_ptr ++; - word_count ++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; - - if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN); - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); - break; - } - if (jump->flags & PATCH_J) { - SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); - buf_ptr[0] |= (addr >> 2) & 0x03ffffff; - break; - } - - /* Set the fields of immediate loads. */ -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); -#else - if (jump->flags & PATCH_ABS32) { - SLJIT_ASSERT(addr <= 0x7fffffff); - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); - } - else if (jump->flags & PATCH_ABS48) { - SLJIT_ASSERT(addr <= 0x7fffffffffffl); - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); - } - else { - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); - buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff); - } -#endif - } while (0); - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); -#ifndef __GNUC__ - SLJIT_CACHE_FLUSH(code, code_ptr); -#else - /* GCC workaround for invalid code generation with -O2. */ - sljit_cache_flush(code, code_ptr); -#endif - return code; -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -/* Creates an index in data_transfer_insts array. */ -#define LOAD_DATA 0x01 -#define WORD_DATA 0x00 -#define BYTE_DATA 0x02 -#define HALF_DATA 0x04 -#define INT_DATA 0x06 -#define SIGNED_DATA 0x08 -/* Separates integer and floating point registers */ -#define GPR_REG 0x0f -#define DOUBLE_DATA 0x10 -#define SINGLE_DATA 0x12 - -#define MEM_MASK 0x1f - -#define WRITE_BACK 0x00020 -#define ARG_TEST 0x00040 -#define ALT_KEEP_CACHE 0x00080 -#define CUMULATIVE_OP 0x00100 -#define LOGICAL_OP 0x00200 -#define IMM_OP 0x00400 -#define SRC2_IMM 0x00800 - -#define UNUSED_DEST 0x01000 -#define REG_DEST 0x02000 -#define REG1_SOURCE 0x04000 -#define REG2_SOURCE 0x08000 -#define SLOW_SRC1 0x10000 -#define SLOW_SRC2 0x20000 -#define SLOW_DEST 0x40000 - -/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ -#define CHECK_FLAGS(list) \ - (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define STACK_STORE SW -#define STACK_LOAD LW -#else -#define STACK_STORE SD -#define STACK_LOAD LD -#endif - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#include "sljitNativeMIPS_32.c" -#else -#include "sljitNativeMIPS_64.c" -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_ins base; - sljit_si i, tmp, offs; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - local_size = (local_size + 15) & ~0xf; -#else - local_size = (local_size + 31) & ~0x1f; -#endif - compiler->local_size = local_size; - - if (local_size <= SIMM_MAX) { - /* Frequent case. */ - FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP))); - base = S(SLJIT_SP); - } - else { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP))); - base = S(TMP_REG2); - local_size = 0; - } - - offs = local_size - (sljit_sw)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS)); - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); - } - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); - } - - if (args >= 1) - FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0))); - if (args >= 2) - FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_S1), DR(SLJIT_S1))); - if (args >= 3) - FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_S2), DR(SLJIT_S2))); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - compiler->local_size = (local_size + 15) & ~0xf; -#else - compiler->local_size = (local_size + 31) & ~0x1f; -#endif - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si local_size, i, tmp, offs; - sljit_ins base; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - local_size = compiler->local_size; - if (local_size <= SIMM_MAX) - base = S(SLJIT_SP); - else { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1))); - base = S(TMP_REG1); - local_size = 0; - } - - FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); - offs = local_size - (sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); - - tmp = compiler->scratches; - for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); - } - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - for (i = tmp; i <= SLJIT_S0; i++) { - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); - } - - SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw))); - - FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); - if (compiler->local_size <= SIMM_MAX) - return push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(compiler->local_size), UNMOVABLE_INS); - else - return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_SP), UNMOVABLE_INS); -} - -#undef STACK_STORE -#undef STACK_LOAD - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define ARCH_32_64(a, b) a -#else -#define ARCH_32_64(a, b) b -#endif - -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { -/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), -/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), -/* u b s */ HI(40) /* sb */, -/* u b l */ HI(36) /* lbu */, -/* u h s */ HI(41) /* sh */, -/* u h l */ HI(37) /* lhu */, -/* u i s */ HI(43) /* sw */, -/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */), - -/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), -/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), -/* s b s */ HI(40) /* sb */, -/* s b l */ HI(32) /* lb */, -/* s h s */ HI(41) /* sh */, -/* s h l */ HI(33) /* lh */, -/* s i s */ HI(43) /* sw */, -/* s i l */ HI(35) /* lw */, - -/* d s */ HI(61) /* sdc1 */, -/* d l */ HI(53) /* ldc1 */, -/* s s */ HI(57) /* swc1 */, -/* s l */ HI(49) /* lwc1 */, -}; - -#undef ARCH_32_64 - -/* reg_ar is an absoulute register! */ - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) -{ - SLJIT_ASSERT(arg & SLJIT_MEM); - - if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) { - /* Works for both absoulte and relative addresses. */ - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK) - | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); - return -1; - } - return 0; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - - /* Simple operation except for updates. */ - if (arg & OFFS_REG_MASK) { - argw &= 0x3; - next_argw &= 0x3; - if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) - return 1; - return 0; - } - - if (arg == next_arg) { - if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) - return 1; - return 0; - } - - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si tmp_ar, base, delay_slot; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { - tmp_ar = reg_ar; - delay_slot = reg_ar; - } else { - tmp_ar = DR(TMP_REG1); - delay_slot = MOVABLE_INS; - } - base = arg & REG_MASK; - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - if ((flags & WRITE_BACK) && reg_ar == DR(base)) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); - FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); - reg_ar = DR(TMP_REG1); - } - - /* Using the cache. */ - if (argw == compiler->cache_argw) { - if (!(flags & WRITE_BACK)) { - if (arg == compiler->cache_arg) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); - } - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); - } - } - else { - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); - } - } - } - - if (SLJIT_UNLIKELY(argw)) { - compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); - compiler->cache_argw = argw; - FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); - } - - if (!(flags & WRITE_BACK)) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); - tmp_ar = DR(TMP_REG3); - } - else - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); - } - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(base), DR(base))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); - } - - if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { - /* Update only applies if a base register exists. */ - if (reg_ar == DR(base)) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); - if (argw <= SIMM_MAX && argw >= SIMM_MIN) { - FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS)); - if (argw) - return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)); - return SLJIT_SUCCESS; - } - FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); - reg_ar = DR(TMP_REG1); - } - - if (argw <= SIMM_MAX && argw >= SIMM_MIN) { - if (argw) - FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base))); - } - else { - if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); - compiler->cache_argw = argw; - } - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); - } - else { - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); - } - } - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); - } - - if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); - compiler->cache_argw = argw; - } - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); - } - - if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { - if (argw != compiler->cache_argw) - FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); - } - else { - compiler->cache_arg = SLJIT_MEM; - FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); - } - compiler->cache_argw = argw; - - if (!base) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); - - if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { - compiler->cache_arg = arg; - FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); - } - - FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg - arg2 goes to TMP_REG2, imm or src reg - TMP_REG3 can be used for caching - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; - sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - - if (!(flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } - - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - if (GET_FLAGS(op)) - flags |= UNUSED_DEST; - } - else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } - else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) - flags |= SLOW_DEST; - - if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w) { - if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN)) - || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) { - flags |= SRC2_IMM; - src2_r = src2w; - } - } - if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { - if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) - || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { - flags |= SRC2_IMM; - src2_r = src1w; - - /* And swap arguments. */ - src1 = src2; - src1w = src2w; - src2 = SLJIT_IMM; - /* src2w = src2_r unneeded. */ - } - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) { - src1_r = src1; - flags |= REG1_SOURCE; - } - else if (src1 & SLJIT_IMM) { - if (src1w) { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); - src1_r = TMP_REG1; - } - else - src1_r = 0; - } - else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - src1_r = TMP_REG1; - } - - /* Source 2. */ - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - dst_r = src2_r; - } - else if (src2 & SLJIT_IMM) { - if (!(flags & SRC2_IMM)) { - if (src2w) { - FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); - src2_r = sugg_src2_r; - } - else { - src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) - dst_r = 0; - } - } - } - else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - src2_r = sugg_src2_r; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - SLJIT_ASSERT(src2_r == TMP_REG2); - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw)); - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw); - return compiler->error; - } - return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - sljit_si int_op = op & SLJIT_INT_OP; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - return push_inst(compiler, BREAK, UNMOVABLE_INS); - case SLJIT_NOP: - return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#else - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); - return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); -#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (int_op) - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); - else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#endif - - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); - return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 -#else - sljit_si flags = 0; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) { - flags |= INT_DATA | SIGNED_DATA; - if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; - } -#endif - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UI: -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); -#else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); -#endif - - case SLJIT_MOV_SI: -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); -#else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); -#endif - - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_MOVU: - case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UI: -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); -#else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); -#endif - - case SLJIT_MOVU_SI: -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); -#else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); -#endif - - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: - return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); - - case SLJIT_CLZ: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); - } - - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 -#else - sljit_si flags = 0; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op & SLJIT_INT_OP) { - flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) - src1w = (sljit_si)src1w; - if (src2 & SLJIT_IMM) - src2w = (sljit_si)src2w; - } -#endif - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - case SLJIT_ADDC: - return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUB: - case SLJIT_SUBC: - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_MUL: - return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_AND: - case SLJIT_OR: - case SLJIT_XOR: - return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (src2 & SLJIT_IMM) - src2w &= 0x1f; -#else - if (src2 & SLJIT_IMM) { - if (op & SLJIT_INT_OP) - src2w &= 0x1f; - else - src2w &= 0x3f; - } -#endif - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg << 1; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#elif defined(__GNUC__) - sljit_sw fir; - asm ("cfc1 %0, $0" : "=r"(fir)); - return (fir >> 22) & 0x1; -#else -#error "FIR check is not implemented for this architecture" -#endif -} - -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 -#else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVW_FROMD) << 21; -#endif - - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - src = TMP_FREG1; - } - else - src <<= 1; - - FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS)); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS); - - /* Store the integer value from a VFP register. */ - return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef is_long -#endif -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 -#else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVD_FROMW) << 21; -#endif - - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); - else if (src & SLJIT_MEM) { - /* Load the integer value into a VFP register. */ - FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - } - else { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; -#endif - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); - FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); - } - - FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); - - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags -#endif -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - src1 = TMP_FREG1; - } - else - src1 <<= 1; - - if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); - src2 = TMP_FREG2; - } - else - src2 <<= 1; - - /* src2 and src1 are swapped. */ - if (op & SLJIT_SET_E) { - FAIL_IF(push_inst(compiler, C_UEQ_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); - FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); - FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); - } - if (op & SLJIT_SET_S) { - /* Mixing the instructions for the two checks. */ - FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src1) | FS(src2), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); - FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); - FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); - } - return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; - - dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); - src = dst_r; - } - else - src <<= 1; - - switch (GET_OPCODE(op)) { - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); - break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); - break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_SINGLE_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; - break; - } - - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, flags = 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; - - if (src1 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1 = TMP_FREG1; - } else - flags |= SLOW_SRC1; - } - else - src1 <<= 1; - - if (src2 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { - FAIL_IF(compiler->error); - src2 = TMP_FREG2; - } else - flags |= SLOW_SRC2; - } - else - src2 <<= 1; - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - - if (flags & SLOW_SRC1) - src1 = TMP_FREG1; - if (flags & SLOW_SRC2) - src2 = TMP_FREG2; - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); - break; - - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); - break; - - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); - break; - - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); - break; - } - - if (dst_r == TMP_FREG2) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); - - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); - - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); - else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); - - FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); - return push_inst(compiler, NOP, UNMOVABLE_INS); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - compiler->delay_slot = UNMOVABLE_INS; - return label; -} - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define JUMP_LENGTH 4 -#else -#define JUMP_LENGTH 8 -#endif - -#define BR_Z(src) \ - inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \ - flags = IS_BIT26_COND; \ - delay_check = src; - -#define BR_NZ(src) \ - inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \ - flags = IS_BIT26_COND; \ - delay_check = src; - -#define BR_T() \ - inst = BC1T | JUMP_LENGTH; \ - flags = IS_BIT16_COND; \ - delay_check = FCSR_FCC; - -#define BR_F() \ - inst = BC1F | JUMP_LENGTH; \ - flags = IS_BIT16_COND; \ - delay_check = FCSR_FCC; - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - sljit_ins inst; - sljit_si flags = 0; - sljit_si delay_check = UNMOVABLE_INS; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - switch (type) { - case SLJIT_EQUAL: - case SLJIT_D_NOT_EQUAL: - BR_NZ(EQUAL_FLAG); - break; - case SLJIT_NOT_EQUAL: - case SLJIT_D_EQUAL: - BR_Z(EQUAL_FLAG); - break; - case SLJIT_LESS: - case SLJIT_D_LESS: - BR_Z(ULESS_FLAG); - break; - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - BR_NZ(ULESS_FLAG); - break; - case SLJIT_GREATER: - case SLJIT_D_GREATER: - BR_Z(UGREATER_FLAG); - break; - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - BR_NZ(UGREATER_FLAG); - break; - case SLJIT_SIG_LESS: - BR_Z(LESS_FLAG); - break; - case SLJIT_SIG_GREATER_EQUAL: - BR_NZ(LESS_FLAG); - break; - case SLJIT_SIG_GREATER: - BR_Z(GREATER_FLAG); - break; - case SLJIT_SIG_LESS_EQUAL: - BR_NZ(GREATER_FLAG); - break; - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - BR_Z(OVERFLOW_FLAG); - break; - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - BR_NZ(OVERFLOW_FLAG); - break; - case SLJIT_D_UNORDERED: - BR_F(); - break; - case SLJIT_D_ORDERED: - BR_T(); - break; - default: - /* Not conditional branch. */ - inst = 0; - break; - } - - jump->flags |= flags; - if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check)) - jump->flags |= IS_MOVABLE; - - if (inst) - PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); - - PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - if (type <= SLJIT_JUMP) { - PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - } else { - SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - /* Cannot be optimized out if type is >= CALL0. */ - jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 0); - PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); - jump->addr = compiler->size; - /* A NOP if type < CALL1. */ - PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS)); - } - return jump; -} - -#define RESOLVE_IMM1() \ - if (src1 & SLJIT_IMM) { \ - if (src1w) { \ - PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ - src1 = TMP_REG1; \ - } \ - else \ - src1 = 0; \ - } - -#define RESOLVE_IMM2() \ - if (src2 & SLJIT_IMM) { \ - if (src2w) { \ - PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ - src2 = TMP_REG2; \ - } \ - else \ - src2 = 0; \ - } - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - struct sljit_jump *jump; - sljit_si flags; - sljit_ins inst; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; - if (src1 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); - src1 = TMP_REG1; - } - if (src2 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); - src2 = TMP_REG2; - } - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - if (type <= SLJIT_NOT_EQUAL) { - RESOLVE_IMM1(); - RESOLVE_IMM2(); - jump->flags |= IS_BIT26_COND; - if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) - jump->flags |= IS_MOVABLE; - PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS)); - } - else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { - inst = NOP; - if ((src1 & SLJIT_IMM) && (src1w == 0)) { - RESOLVE_IMM2(); - switch (type) { - case SLJIT_SIG_LESS: - inst = BLEZ; - jump->flags |= IS_BIT26_COND; - break; - case SLJIT_SIG_GREATER_EQUAL: - inst = BGTZ; - jump->flags |= IS_BIT26_COND; - break; - case SLJIT_SIG_GREATER: - inst = BGEZ; - jump->flags |= IS_BIT16_COND; - break; - case SLJIT_SIG_LESS_EQUAL: - inst = BLTZ; - jump->flags |= IS_BIT16_COND; - break; - } - src1 = src2; - } - else { - RESOLVE_IMM1(); - switch (type) { - case SLJIT_SIG_LESS: - inst = BGEZ; - jump->flags |= IS_BIT16_COND; - break; - case SLJIT_SIG_GREATER_EQUAL: - inst = BLTZ; - jump->flags |= IS_BIT16_COND; - break; - case SLJIT_SIG_GREATER: - inst = BLEZ; - jump->flags |= IS_BIT26_COND; - break; - case SLJIT_SIG_LESS_EQUAL: - inst = BGTZ; - jump->flags |= IS_BIT26_COND; - break; - } - } - PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS)); - } - else { - if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) { - RESOLVE_IMM1(); - if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) - PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); - else { - RESOLVE_IMM2(); - PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1))); - } - type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL; - } - else { - RESOLVE_IMM2(); - if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) - PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); - else { - RESOLVE_IMM1(); - PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); - } - type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL; - } - - jump->flags |= IS_BIT26_COND; - PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS)); - } - - PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - return jump; -} - -#undef RESOLVE_IMM1 -#undef RESOLVE_IMM2 - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - struct sljit_jump *jump; - sljit_ins inst; - sljit_si if_true; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - if (src1 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - src1 = TMP_FREG1; - } - else - src1 <<= 1; - - if (src2 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); - src2 = TMP_FREG2; - } - else - src2 <<= 1; - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - jump->flags |= IS_BIT16_COND; - - switch (type & 0xff) { - case SLJIT_D_EQUAL: - inst = C_UEQ_S; - if_true = 1; - break; - case SLJIT_D_NOT_EQUAL: - inst = C_UEQ_S; - if_true = 0; - break; - case SLJIT_D_LESS: - inst = C_ULT_S; - if_true = 1; - break; - case SLJIT_D_GREATER_EQUAL: - inst = C_ULT_S; - if_true = 0; - break; - case SLJIT_D_GREATER: - inst = C_ULE_S; - if_true = 0; - break; - case SLJIT_D_LESS_EQUAL: - inst = C_ULE_S; - if_true = 1; - break; - case SLJIT_D_UNORDERED: - inst = C_UN_S; - if_true = 1; - break; - default: /* Make compilers happy. */ - SLJIT_ASSERT_STOP(); - case SLJIT_D_ORDERED: - inst = C_UN_S; - if_true = 0; - break; - } - - PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | FT(src2) | FS(src1), UNMOVABLE_INS)); - /* Intentionally the other opcode. */ - PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); - PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - return jump; -} - -#undef JUMP_LENGTH -#undef BR_Z -#undef BR_NZ -#undef BR_T -#undef BR_F - -#undef FLOAT_DATA -#undef FMT - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - sljit_si src_r = TMP_REG2; - struct sljit_jump *jump = NULL; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) { - if (DR(src) != 4) - src_r = src; - else - FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - } - - if (type >= SLJIT_CALL0) { - SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - if (src & (SLJIT_IMM | SLJIT_MEM)) { - if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); - else { - SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - } - FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); - /* We need an extra instruction in any case. */ - return push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS); - } - - /* Register input. */ - if (type >= SLJIT_CALL1) - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), 4)); - FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); - return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); - } - - if (src & SLJIT_IMM) { - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); - jump->u.target = srcw; - - if (compiler->delay_slot != UNMOVABLE_INS) - jump->flags |= IS_MOVABLE; - - FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - } - else if (src & SLJIT_MEM) - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - - FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); - if (jump) - jump->addr = compiler->size; - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define mem_type WORD_DATA -#else - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - op = GET_OPCODE(op); -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) - mem_type = INT_DATA | SIGNED_DATA; -#endif - sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } - - switch (type & 0xff) { - case SLJIT_EQUAL: - case SLJIT_NOT_EQUAL: - FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); - dst_ar = sugg_dst_ar; - break; - case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS: - case SLJIT_D_GREATER_EQUAL: - dst_ar = ULESS_FLAG; - break; - case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: - case SLJIT_D_GREATER: - case SLJIT_D_LESS_EQUAL: - dst_ar = UGREATER_FLAG; - break; - case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: - dst_ar = LESS_FLAG; - break; - case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: - dst_ar = GREATER_FLAG; - break; - case SLJIT_OVERFLOW: - case SLJIT_NOT_OVERFLOW: - dst_ar = OVERFLOW_FLAG; - break; - case SLJIT_MUL_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); - dst_ar = sugg_dst_ar; - type ^= 0x1; /* Flip type bit for the XORI below. */ - break; - case SLJIT_D_EQUAL: - case SLJIT_D_NOT_EQUAL: - dst_ar = EQUAL_FLAG; - break; - - case SLJIT_D_UNORDERED: - case SLJIT_D_ORDERED: - FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); - FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); - FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); - dst_ar = sugg_dst_ar; - break; - - default: - SLJIT_ASSERT_STOP(); - dst_ar = sugg_dst_ar; - break; - } - - if (type & 0x1) { - FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); - dst_ar = sugg_dst_ar; - } - - if (op >= SLJIT_ADD) { - if (DR(TMP_REG2) != dst_ar) - FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); - } - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw); - - if (sugg_dst_ar != dst_ar) - return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar); - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef mem_type -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si reg; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); - return const_; -} diff --git a/pcre2/src/sljit/sljitNativePPC_32.c b/pcre2/src/sljit/sljitNativePPC_32.c deleted file mode 100644 index b14b75ceb..000000000 --- a/pcre2/src/sljit/sljitNativePPC_32.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* ppc 32-bit arch dependent functions. */ - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) -{ - if (imm <= SIMM_MAX && imm >= SIMM_MIN) - return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); - - if (!(imm & ~0xffff)) - return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); - - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); - return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; -} - -#define INS_CLEAR_LEFT(dst, src, from) \ - (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) -{ - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1); - if (dst != src2) - return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); - } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) - return push_inst(compiler, EXTSH | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - - case SLJIT_NEG: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); - - case SLJIT_ADD: - if (flags & ALT_FORM1) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM2) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM4) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); - return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); - } - if (!(flags & ALT_SET_FLAGS)) - return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); - return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); - - case SLJIT_ADDC: - if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); - FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); - return push_inst(compiler, MTXER | S(0)); - } - return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); - - case SLJIT_SUB: - if (flags & ALT_FORM1) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); - } - if (flags & (ALT_FORM2 | ALT_FORM3)) { - SLJIT_ASSERT(src2 == TMP_REG2); - if (flags & ALT_FORM2) - FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm)); - if (flags & ALT_FORM3) - return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm); - return SLJIT_SUCCESS; - } - if (flags & (ALT_FORM4 | ALT_FORM5)) { - if (flags & ALT_FORM4) - FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); - if (flags & ALT_FORM5) - FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2))); - return SLJIT_SUCCESS; - } - if (!(flags & ALT_SET_FLAGS)) - return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); - if (flags & ALT_FORM6) - FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); - return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); - - case SLJIT_SUBC: - if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); - FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); - return push_inst(compiler, MTXER | S(0)); - } - return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); - - case SLJIT_MUL: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); - } - return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); - - case SLJIT_AND: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); - } - return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_OR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); - return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); - } - return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_XOR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); - return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); - } - return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_SHL: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - compiler->imm &= 0x1f; - return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); - } - return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_LSHR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - compiler->imm &= 0x1f; - return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); - } - return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_ASHR: - if (flags & ALT_FORM3) - FAIL_IF(push_inst(compiler, MFXER | D(0))); - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - compiler->imm &= 0x1f; - FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); - } - else - FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2))); - return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) -{ - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); - return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} diff --git a/pcre2/src/sljit/sljitNativePPC_64.c b/pcre2/src/sljit/sljitNativePPC_64.c deleted file mode 100644 index 182ac7b3d..000000000 --- a/pcre2/src/sljit/sljitNativePPC_64.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* ppc 64-bit arch dependent functions. */ - -#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) -#define ASM_SLJIT_CLZ(src, dst) \ - __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) -#elif defined(__xlc__) -#error "Please enable GCC syntax for inline assembly statements" -#else -#error "Must implement count leading zeroes" -#endif - -#define RLDI(dst, src, sh, mb, type) \ - (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) - -#define PUSH_RLDICR(reg, shift) \ - push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) -{ - sljit_uw tmp; - sljit_uw shift; - sljit_uw tmp2; - sljit_uw shift2; - - if (imm <= SIMM_MAX && imm >= SIMM_MIN) - return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); - - if (!(imm & ~0xffff)) - return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); - - if (imm <= 0x7fffffffl && imm >= -0x80000000l) { - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); - return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; - } - - /* Count leading zeroes. */ - tmp = (imm >= 0) ? imm : ~imm; - ASM_SLJIT_CLZ(tmp, shift); - SLJIT_ASSERT(shift > 0); - shift--; - tmp = (imm << shift); - - if ((tmp & ~0xffff000000000000ul) == 0) { - FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); - shift += 15; - return PUSH_RLDICR(reg, shift); - } - - if ((tmp & ~0xffffffff00000000ul) == 0) { - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48))); - FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32))); - shift += 31; - return PUSH_RLDICR(reg, shift); - } - - /* Cut out the 16 bit from immediate. */ - shift += 15; - tmp2 = imm & ((1ul << (63 - shift)) - 1); - - if (tmp2 <= 0xffff) { - FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); - FAIL_IF(PUSH_RLDICR(reg, shift)); - return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2); - } - - if (tmp2 <= 0xffffffff) { - FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); - FAIL_IF(PUSH_RLDICR(reg, shift)); - FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16))); - return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS; - } - - ASM_SLJIT_CLZ(tmp2, shift2); - tmp2 <<= shift2; - - if ((tmp2 & ~0xffff000000000000ul) == 0) { - FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); - shift2 += 15; - shift += (63 - shift2); - FAIL_IF(PUSH_RLDICR(reg, shift)); - FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48))); - return PUSH_RLDICR(reg, shift2); - } - - /* The general version. */ - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48))); - FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32))); - FAIL_IF(PUSH_RLDICR(reg, 31)); - FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16))); - return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)); -} - -/* Simplified mnemonics: clrldi. */ -#define INS_CLEAR_LEFT(dst, src, from) \ - (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5)) - -/* Sign extension for integer operations. */ -#define UN_EXTS() \ - if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \ - FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ - src2 = TMP_REG2; \ - } - -#define BIN_EXTS() \ - if (flags & ALT_SIGN_EXT) { \ - if (flags & REG1_SOURCE) { \ - FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ - src1 = TMP_REG1; \ - } \ - if (flags & REG2_SOURCE) { \ - FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ - src2 = TMP_REG2; \ - } \ - } - -#define BIN_IMM_EXTS() \ - if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \ - FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ - src1 = TMP_REG1; \ - } - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) -{ - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1); - if (dst != src2) - return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) - return push_inst(compiler, EXTSW | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); - } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) - return push_inst(compiler, EXTSH | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - - case SLJIT_NEG: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1); - if (flags & ALT_FORM1) - return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); - return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); - - case SLJIT_ADD: - if (flags & ALT_FORM1) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM2) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - BIN_IMM_EXTS(); - return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); - } - if (flags & ALT_FORM4) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); - return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); - } - if (!(flags & ALT_SET_FLAGS)) - return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); - BIN_EXTS(); - return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); - - case SLJIT_ADDC: - if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); - FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); - return push_inst(compiler, MTXER | S(0)); - } - BIN_EXTS(); - return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); - - case SLJIT_SUB: - if (flags & ALT_FORM1) { - /* Flags does not set: BIN_IMM_EXTS unnecessary. */ - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); - } - if (flags & (ALT_FORM2 | ALT_FORM3)) { - SLJIT_ASSERT(src2 == TMP_REG2); - if (flags & ALT_FORM2) - FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm)); - if (flags & ALT_FORM3) - return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm); - return SLJIT_SUCCESS; - } - if (flags & (ALT_FORM4 | ALT_FORM5)) { - if (flags & ALT_FORM4) - FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); - if (flags & ALT_FORM5) - return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)); - return SLJIT_SUCCESS; - } - if (!(flags & ALT_SET_FLAGS)) - return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); - BIN_EXTS(); - if (flags & ALT_FORM6) - FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); - return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); - - case SLJIT_SUBC: - if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); - FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); - return push_inst(compiler, MTXER | S(0)); - } - BIN_EXTS(); - return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); - - case SLJIT_MUL: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); - } - BIN_EXTS(); - if (flags & ALT_FORM2) - return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); - return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1)); - - case SLJIT_AND: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); - } - return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_OR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); - return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); - } - return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_XOR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM2) { - SLJIT_ASSERT(src2 == TMP_REG2); - return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); - } - if (flags & ALT_FORM3) { - SLJIT_ASSERT(src2 == TMP_REG2); - FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); - return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); - } - return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_SHL: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - if (flags & ALT_FORM2) { - compiler->imm &= 0x1f; - return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); - } - else { - compiler->imm &= 0x3f; - return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags)); - } - } - return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_LSHR: - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - if (flags & ALT_FORM2) { - compiler->imm &= 0x1f; - return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); - } - else { - compiler->imm &= 0x3f; - return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags)); - } - } - return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2)); - - case SLJIT_ASHR: - if (flags & ALT_FORM3) - FAIL_IF(push_inst(compiler, MFXER | D(0))); - if (flags & ALT_FORM1) { - SLJIT_ASSERT(src2 == TMP_REG2); - if (flags & ALT_FORM2) { - compiler->imm &= 0x1f; - FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); - } - else { - compiler->imm &= 0x3f; - FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4))); - } - } - else - FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2))); - return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) -{ - FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); - FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); - FAIL_IF(PUSH_RLDICR(reg, 31)); - FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16))); - return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 5); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); - SLJIT_CACHE_FLUSH(inst, inst + 5); -} diff --git a/pcre2/src/sljit/sljitNativePPC_common.c b/pcre2/src/sljit/sljitNativePPC_common.c deleted file mode 100644 index b6a043f4e..000000000 --- a/pcre2/src/sljit/sljitNativePPC_common.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "PowerPC" SLJIT_CPUINFO; -} - -/* Length of an instruction word. - Both for ppc-32 and ppc-64. */ -typedef sljit_ui sljit_ins; - -#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_PPC_STACK_FRAME_V2 1 -#endif - -#ifdef _AIX -#include -#endif - -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 -#endif - -static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) -{ -#ifdef _AIX - _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from)); -#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) -# if defined(_ARCH_PWR) || defined(_ARCH_PWR2) - /* Cache flush for POWER architecture. */ - while (from < to) { - __asm__ volatile ( - "clf 0, %0\n" - "dcs\n" - : : "r"(from) - ); - from++; - } - __asm__ volatile ( "ics" ); -# elif defined(_ARCH_COM) && !defined(_ARCH_PPC) -# error "Cache flush is not implemented for PowerPC/POWER common mode." -# else - /* Cache flush for PowerPC architecture. */ - while (from < to) { - __asm__ volatile ( - "dcbf 0, %0\n" - "sync\n" - "icbi 0, %0\n" - : : "r"(from) - ); - from++; - } - __asm__ volatile ( "isync" ); -# endif -# ifdef __xlc__ -# warning "This file may fail to compile if -qfuncsect is used" -# endif -#elif defined(__xlc__) -#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc" -#else -#error "This platform requires a cache flush implementation." -#endif /* _AIX */ -} - -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5) - -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) -#define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6) -#else -#define TMP_CALL_REG TMP_REG2 -#endif - -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { - 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12 -}; - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ -#define D(d) (reg_map[d] << 21) -#define S(s) (reg_map[s] << 21) -#define A(a) (reg_map[a] << 16) -#define B(b) (reg_map[b] << 11) -#define C(c) (reg_map[c] << 6) -#define FD(fd) ((fd) << 21) -#define FS(fs) ((fs) << 21) -#define FA(fa) ((fa) << 16) -#define FB(fb) ((fb) << 11) -#define FC(fc) ((fc) << 6) -#define IMM(imm) ((imm) & 0xffff) -#define CRD(d) ((d) << 21) - -/* Instruction bit sections. - OE and Rc flag (see ALT_SET_FLAGS). */ -#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS)) -/* Rc flag (see ALT_SET_FLAGS). */ -#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10) -#define HI(opcode) ((opcode) << 26) -#define LO(opcode) ((opcode) << 1) - -#define ADD (HI(31) | LO(266)) -#define ADDC (HI(31) | LO(10)) -#define ADDE (HI(31) | LO(138)) -#define ADDI (HI(14)) -#define ADDIC (HI(13)) -#define ADDIS (HI(15)) -#define ADDME (HI(31) | LO(234)) -#define AND (HI(31) | LO(28)) -#define ANDI (HI(28)) -#define ANDIS (HI(29)) -#define Bx (HI(18)) -#define BCx (HI(16)) -#define BCCTR (HI(19) | LO(528) | (3 << 11)) -#define BLR (HI(19) | LO(16) | (0x14 << 21)) -#define CNTLZD (HI(31) | LO(58)) -#define CNTLZW (HI(31) | LO(26)) -#define CMP (HI(31) | LO(0)) -#define CMPI (HI(11)) -#define CMPL (HI(31) | LO(32)) -#define CMPLI (HI(10)) -#define CROR (HI(19) | LO(449)) -#define DIVD (HI(31) | LO(489)) -#define DIVDU (HI(31) | LO(457)) -#define DIVW (HI(31) | LO(491)) -#define DIVWU (HI(31) | LO(459)) -#define EXTSB (HI(31) | LO(954)) -#define EXTSH (HI(31) | LO(922)) -#define EXTSW (HI(31) | LO(986)) -#define FABS (HI(63) | LO(264)) -#define FADD (HI(63) | LO(21)) -#define FADDS (HI(59) | LO(21)) -#define FCFID (HI(63) | LO(846)) -#define FCMPU (HI(63) | LO(0)) -#define FCTIDZ (HI(63) | LO(815)) -#define FCTIWZ (HI(63) | LO(15)) -#define FDIV (HI(63) | LO(18)) -#define FDIVS (HI(59) | LO(18)) -#define FMR (HI(63) | LO(72)) -#define FMUL (HI(63) | LO(25)) -#define FMULS (HI(59) | LO(25)) -#define FNEG (HI(63) | LO(40)) -#define FRSP (HI(63) | LO(12)) -#define FSUB (HI(63) | LO(20)) -#define FSUBS (HI(59) | LO(20)) -#define LD (HI(58) | 0) -#define LWZ (HI(32)) -#define MFCR (HI(31) | LO(19)) -#define MFLR (HI(31) | LO(339) | 0x80000) -#define MFXER (HI(31) | LO(339) | 0x10000) -#define MTCTR (HI(31) | LO(467) | 0x90000) -#define MTLR (HI(31) | LO(467) | 0x80000) -#define MTXER (HI(31) | LO(467) | 0x10000) -#define MULHD (HI(31) | LO(73)) -#define MULHDU (HI(31) | LO(9)) -#define MULHW (HI(31) | LO(75)) -#define MULHWU (HI(31) | LO(11)) -#define MULLD (HI(31) | LO(233)) -#define MULLI (HI(7)) -#define MULLW (HI(31) | LO(235)) -#define NEG (HI(31) | LO(104)) -#define NOP (HI(24)) -#define NOR (HI(31) | LO(124)) -#define OR (HI(31) | LO(444)) -#define ORI (HI(24)) -#define ORIS (HI(25)) -#define RLDICL (HI(30)) -#define RLWINM (HI(21)) -#define SLD (HI(31) | LO(27)) -#define SLW (HI(31) | LO(24)) -#define SRAD (HI(31) | LO(794)) -#define SRADI (HI(31) | LO(413 << 1)) -#define SRAW (HI(31) | LO(792)) -#define SRAWI (HI(31) | LO(824)) -#define SRD (HI(31) | LO(539)) -#define SRW (HI(31) | LO(536)) -#define STD (HI(62) | 0) -#define STDU (HI(62) | 1) -#define STDUX (HI(31) | LO(181)) -#define STFIWX (HI(31) | LO(983)) -#define STW (HI(36)) -#define STWU (HI(37)) -#define STWUX (HI(31) | LO(183)) -#define SUBF (HI(31) | LO(40)) -#define SUBFC (HI(31) | LO(8)) -#define SUBFE (HI(31) | LO(136)) -#define SUBFIC (HI(8)) -#define XOR (HI(31) | LO(316)) -#define XORI (HI(26)) -#define XORIS (HI(27)) - -#define SIMM_MAX (0x7fff) -#define SIMM_MIN (-0x8000) -#define UIMM_MAX (0xffff) - -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) -{ - sljit_sw* ptrs; - if (func_ptr) - *func_ptr = (void*)context; - ptrs = (sljit_sw*)func; - context->addr = addr ? addr : ptrs[0]; - context->r2 = ptrs[1]; - context->r11 = ptrs[2]; -} -#endif - -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - sljit_sw extra_jump_flags; - -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) - return 0; -#else - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return 0; -#endif - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (jump->flags & IS_CALL) - goto keep_address; -#endif - - diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l; - - extra_jump_flags = 0; - if (jump->flags & IS_COND) { - if (diff <= 0x7fff && diff >= -0x8000) { - jump->flags |= PATCH_B; - return 1; - } - if (target_addr <= 0xffff) { - jump->flags |= PATCH_B | PATCH_ABS_B; - return 1; - } - extra_jump_flags = REMOVE_COND; - - diff -= sizeof(sljit_ins); - } - - if (diff <= 0x01ffffff && diff >= -0x02000000) { - jump->flags |= PATCH_B | extra_jump_flags; - return 1; - } - if (target_addr <= 0x03ffffff) { - jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags; - return 1; - } - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) -keep_address: -#endif - if (target_addr <= 0x7fffffff) { - jump->flags |= PATCH_ABS32; - return 1; - } - if (target_addr <= 0x7fffffffffffl) { - jump->flags |= PATCH_ABS48; - return 1; - } -#endif - - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); -#else - compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); -#endif -#endif - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = (sljit_ins*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 2); - do { - *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - jump->addr = (sljit_uw)(code_ptr - 3); -#else - jump->addr = (sljit_uw)(code_ptr - 6); -#endif - if (detect_jump_type(jump, code_ptr, code)) { -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - code_ptr[-3] = code_ptr[0]; - code_ptr -= 3; -#else - if (jump->flags & PATCH_ABS32) { - code_ptr -= 3; - code_ptr[-1] = code_ptr[2]; - code_ptr[0] = code_ptr[3]; - } - else if (jump->flags & PATCH_ABS48) { - code_ptr--; - code_ptr[-1] = code_ptr[0]; - code_ptr[0] = code_ptr[1]; - /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ - SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); - code_ptr[-3] ^= 0x8422; - /* oris -> ori */ - code_ptr[-2] ^= 0x4000000; - } - else { - code_ptr[-6] = code_ptr[0]; - code_ptr -= 6; - } -#endif - if (jump->flags & REMOVE_COND) { - code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); - code_ptr++; - jump->addr += sizeof(sljit_ins); - code_ptr[0] = Bx; - jump->flags -= IS_COND; - } - } - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; - } - code_ptr ++; - word_count ++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); -#else - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); -#endif - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; - if (jump->flags & PATCH_B) { - if (jump->flags & IS_COND) { - if (!(jump->flags & PATCH_ABS_B)) { - addr = addr - jump->addr; - SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); - *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); - } - else { - SLJIT_ASSERT(addr <= 0xffff); - *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); - } - } - else { - if (!(jump->flags & PATCH_ABS_B)) { - addr = addr - jump->addr; - SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); - *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); - } - else { - SLJIT_ASSERT(addr <= 0x03ffffff); - *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); - } - } - break; - } - /* Set the fields of immediate loads. */ -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); -#else - if (jump->flags & PATCH_ABS32) { - SLJIT_ASSERT(addr <= 0x7fffffff); - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); - break; - } - if (jump->flags & PATCH_ABS48) { - SLJIT_ASSERT(addr <= 0x7fffffffffff); - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); - break; - } - buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); - buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); - buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); - buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); -#endif - } while (0); - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); - -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (((sljit_sw)code_ptr) & 0x4) - code_ptr++; - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); - return code_ptr; -#else - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); - return code_ptr; -#endif -#else - return code; -#endif -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -/* inp_flags: */ - -/* Creates an index in data_transfer_insts array. */ -#define LOAD_DATA 0x01 -#define INDEXED 0x02 -#define WRITE_BACK 0x04 -#define WORD_DATA 0x00 -#define BYTE_DATA 0x08 -#define HALF_DATA 0x10 -#define INT_DATA 0x18 -#define SIGNED_DATA 0x20 -/* Separates integer and floating point registers */ -#define GPR_REG 0x3f -#define DOUBLE_DATA 0x40 - -#define MEM_MASK 0x7f - -/* Other inp_flags. */ - -#define ARG_TEST 0x000100 -/* Integer opertion and set flags -> requires exts on 64 bit systems. */ -#define ALT_SIGN_EXT 0x000200 -/* This flag affects the RC() and OERC() macros. */ -#define ALT_SET_FLAGS 0x000400 -#define ALT_KEEP_CACHE 0x000800 -#define ALT_FORM1 0x010000 -#define ALT_FORM2 0x020000 -#define ALT_FORM3 0x040000 -#define ALT_FORM4 0x080000 -#define ALT_FORM5 0x100000 -#define ALT_FORM6 0x200000 - -/* Source and destination is register. */ -#define REG_DEST 0x000001 -#define REG1_SOURCE 0x000002 -#define REG2_SOURCE 0x000004 -/* getput_arg_fast returned true. */ -#define FAST_DEST 0x000008 -/* Multiple instructions are required. */ -#define SLOW_DEST 0x000010 -/* -ALT_SIGN_EXT 0x000200 -ALT_SET_FLAGS 0x000400 -ALT_FORM1 0x010000 -... -ALT_FORM6 0x200000 */ - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -#include "sljitNativePPC_32.c" -#else -#include "sljitNativePPC_64.c" -#endif - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -#define STACK_STORE STW -#define STACK_LOAD LWZ -#else -#define STACK_STORE STD -#define STACK_LOAD LD -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si i, tmp, offs; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - FAIL_IF(push_inst(compiler, MFLR | D(0))); - offs = -(sljit_si)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); - } - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); - FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); - } - - SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); - -#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) - FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); -#else - FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); -#endif - - FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0)); - if (args >= 1) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0))); - if (args >= 2) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1))); - if (args >= 3) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2))); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; - local_size = (local_size + 15) & ~0xf; - compiler->local_size = local_size; - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - if (local_size <= SIMM_MAX) - FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); - else { - FAIL_IF(load_immediate(compiler, 0, -local_size)); - FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); - } -#else - if (local_size <= SIMM_MAX) - FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); - else { - FAIL_IF(load_immediate(compiler, 0, -local_size)); - FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); - } -#endif - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; - compiler->local_size = (local_size + 15) & ~0xf; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si i, tmp, offs; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - if (compiler->local_size <= SIMM_MAX) - FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size))); - else { - FAIL_IF(load_immediate(compiler, 0, compiler->local_size)); - FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0))); - } - -#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); -#else - FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); -#endif - - offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); - - tmp = compiler->scratches; - for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { - FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); - } - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - for (i = tmp; i <= SLJIT_S0; i++) { - FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); - } - - FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); - SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw))); - - FAIL_IF(push_inst(compiler, MTLR | S(0))); - FAIL_IF(push_inst(compiler, BLR)); - - return SLJIT_SUCCESS; -} - -#undef STACK_STORE -#undef STACK_LOAD - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -/* i/x - immediate/indexed form - n/w - no write-back / write-back (1 bit) - s/l - store/load (1 bit) - u/s - signed/unsigned (1 bit) - w/b/h/i - word/byte/half/int allowed (2 bit) - It contans 32 items, but not all are different. */ - -/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ -#define INT_ALIGNED 0x10000 -/* 64-bit only: there is no lwau instruction. */ -#define UPDATE_REQ 0x20000 - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -#define ARCH_32_64(a, b) a -#define INST_CODE_AND_DST(inst, flags, reg) \ - ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) -#else -#define ARCH_32_64(a, b) b -#define INST_CODE_AND_DST(inst, flags, reg) \ - (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) -#endif - -static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { - -/* -------- Unsigned -------- */ - -/* Word. */ - -/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), -/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), -/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), -/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), - -/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), -/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), -/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), -/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), - -/* Byte. */ - -/* u b n i s */ HI(38) /* stb */, -/* u b n i l */ HI(34) /* lbz */, -/* u b n x s */ HI(31) | LO(215) /* stbx */, -/* u b n x l */ HI(31) | LO(87) /* lbzx */, - -/* u b w i s */ HI(39) /* stbu */, -/* u b w i l */ HI(35) /* lbzu */, -/* u b w x s */ HI(31) | LO(247) /* stbux */, -/* u b w x l */ HI(31) | LO(119) /* lbzux */, - -/* Half. */ - -/* u h n i s */ HI(44) /* sth */, -/* u h n i l */ HI(40) /* lhz */, -/* u h n x s */ HI(31) | LO(407) /* sthx */, -/* u h n x l */ HI(31) | LO(279) /* lhzx */, - -/* u h w i s */ HI(45) /* sthu */, -/* u h w i l */ HI(41) /* lhzu */, -/* u h w x s */ HI(31) | LO(439) /* sthux */, -/* u h w x l */ HI(31) | LO(311) /* lhzux */, - -/* Int. */ - -/* u i n i s */ HI(36) /* stw */, -/* u i n i l */ HI(32) /* lwz */, -/* u i n x s */ HI(31) | LO(151) /* stwx */, -/* u i n x l */ HI(31) | LO(23) /* lwzx */, - -/* u i w i s */ HI(37) /* stwu */, -/* u i w i l */ HI(33) /* lwzu */, -/* u i w x s */ HI(31) | LO(183) /* stwux */, -/* u i w x l */ HI(31) | LO(55) /* lwzux */, - -/* -------- Signed -------- */ - -/* Word. */ - -/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), -/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), -/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), -/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), - -/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), -/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), -/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), -/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), - -/* Byte. */ - -/* s b n i s */ HI(38) /* stb */, -/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */, -/* s b n x s */ HI(31) | LO(215) /* stbx */, -/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, - -/* s b w i s */ HI(39) /* stbu */, -/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */, -/* s b w x s */ HI(31) | LO(247) /* stbux */, -/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, - -/* Half. */ - -/* s h n i s */ HI(44) /* sth */, -/* s h n i l */ HI(42) /* lha */, -/* s h n x s */ HI(31) | LO(407) /* sthx */, -/* s h n x l */ HI(31) | LO(343) /* lhax */, - -/* s h w i s */ HI(45) /* sthu */, -/* s h w i l */ HI(43) /* lhau */, -/* s h w x s */ HI(31) | LO(439) /* sthux */, -/* s h w x l */ HI(31) | LO(375) /* lhaux */, - -/* Int. */ - -/* s i n i s */ HI(36) /* stw */, -/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */), -/* s i n x s */ HI(31) | LO(151) /* stwx */, -/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), - -/* s i w i s */ HI(37) /* stwu */, -/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */), -/* s i w x s */ HI(31) | LO(183) /* stwux */, -/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), - -/* -------- Double -------- */ - -/* d n i s */ HI(54) /* stfd */, -/* d n i l */ HI(50) /* lfd */, -/* d n x s */ HI(31) | LO(727) /* stfdx */, -/* d n x l */ HI(31) | LO(599) /* lfdx */, - -/* s n i s */ HI(52) /* stfs */, -/* s n i l */ HI(48) /* lfs */, -/* s n x s */ HI(31) | LO(663) /* stfsx */, -/* s n x l */ HI(31) | LO(535) /* lfsx */, - -}; - -#undef ARCH_32_64 - -/* Simple cases, (no caching is required). */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - sljit_ins inst; - - /* Should work when (arg & REG_MASK) == 0. */ - SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0); - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (arg & OFFS_REG_MASK) { - if (argw & 0x3) - return 0; - if (inp_flags & ARG_TEST) - return 1; - - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); - FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg)))); - return -1; - } - - if (SLJIT_UNLIKELY(!(arg & REG_MASK))) - inp_flags &= ~WRITE_BACK; - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - inst = data_transfer_insts[inp_flags & MEM_MASK]; - SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); - - if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ)) - return 0; - if (inp_flags & ARG_TEST) - return 1; -#endif - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - if (argw > SIMM_MAX || argw < SIMM_MIN) - return 0; - if (inp_flags & ARG_TEST) - return 1; - - inst = data_transfer_insts[inp_flags & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); -#endif - - FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw))); - return -1; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those operator always - uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_sw high_short, next_high_short; -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_sw diff; -#endif - - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - - if (arg & OFFS_REG_MASK) - return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3)); - - if (next_arg & OFFS_REG_MASK) - return 0; - -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; - next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; - return high_short == next_high_short; -#else - if (argw <= 0x7fffffffl && argw >= -0x80000000l) { - high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; - next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; - if (high_short == next_high_short) - return 1; - } - - diff = argw - next_argw; - if (!(arg & REG_MASK)) - return diff <= SIMM_MAX && diff >= SIMM_MIN; - - if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN) - return 1; - - return 0; -#endif -} - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define ADJUST_CACHED_IMM(imm) \ - if ((inst & INT_ALIGNED) && (imm & 0x3)) { \ - /* Adjust cached value. Fortunately this is really a rare case */ \ - compiler->cache_argw += imm & 0x3; \ - FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \ - imm &= ~0x3; \ - } -#endif - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si tmp_r; - sljit_ins inst; - sljit_sw high_short, next_high_short; -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_sw diff; -#endif - - SLJIT_ASSERT(arg & SLJIT_MEM); - - tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; - /* Special case for "mov reg, [reg, ... ]". */ - if ((arg & REG_MASK) == tmp_r) - tmp_r = TMP_REG1; - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - /* Otherwise getput_arg_fast would capture it. */ - SLJIT_ASSERT(argw); - - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw) - tmp_r = TMP_REG3; - else { - if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { - compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); -#else - FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1))); -#endif - } - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); - } - - if (SLJIT_UNLIKELY(!(arg & REG_MASK))) - inp_flags &= ~WRITE_BACK; - - inst = data_transfer_insts[inp_flags & MEM_MASK]; - SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (argw <= 0x7fff7fffl && argw >= -0x80000000l - && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) { -#endif - - arg &= REG_MASK; - high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff; - /* The getput_arg_fast should handle this otherwise. */ -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); -#else - SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ))); -#endif - - if (inp_flags & WRITE_BACK) { - if (arg == reg) { - FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg))); - reg = tmp_r; - } - tmp_r = arg; - FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16))); - } - else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) { - if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { - next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; - if (high_short == next_high_short) { - compiler->cache_arg = SLJIT_MEM | arg; - compiler->cache_argw = high_short; - tmp_r = TMP_REG3; - } - } - FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16))); - } - else - tmp_r = TMP_REG3; - - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw)); - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - } - - /* Everything else is PPC-64 only. */ - if (SLJIT_UNLIKELY(!(arg & REG_MASK))) { - diff = argw - compiler->cache_argw; - if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { - ADJUST_CACHED_IMM(diff); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); - } - - diff = argw - next_argw; - if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } - - FAIL_IF(load_immediate(compiler, tmp_r, argw)); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); - } - - diff = argw - compiler->cache_argw; - if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) { - SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ)); - ADJUST_CACHED_IMM(diff); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); - } - - if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); - if (compiler->cache_argw != argw) { - FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff))); - compiler->cache_argw = argw; - } - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); - } - - if (argw == next_argw && (next_arg & SLJIT_MEM)) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); - } - - diff = argw - next_argw; - if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK))); - - compiler->cache_arg = arg; - compiler->cache_argw = argw; - - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3)); - } - - if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { - SLJIT_ASSERT(inp_flags & LOAD_DATA); - FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - - compiler->cache_arg = SLJIT_IMM; - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } - else - FAIL_IF(load_immediate(compiler, tmp_r, argw)); - - /* Get the indexed version instead of the normal one. */ - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); -#endif -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg - arg2 goes to TMP_REG2, imm or src reg - TMP_REG3 can be used for caching - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); - - if (!(input_flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } - - /* Destination check. */ - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } - else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } - else { - SLJIT_ASSERT(dst & SLJIT_MEM); - if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) { - flags |= FAST_DEST; - dst_r = TMP_REG2; - } - else { - flags |= SLOW_DEST; - dst_r = 0; - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) { - src1_r = src1; - flags |= REG1_SOURCE; - } - else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1_r = TMP_REG1; - } - else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1_r = TMP_REG1; - } - else - src1_r = 0; - - /* Source 2. */ - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - dst_r = src2_r; - } - else if (src2 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); - src2_r = sugg_src2_r; - } - else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { - FAIL_IF(compiler->error); - src2_r = sugg_src2_r; - } - else - src2_r = 0; - - /* src1_r, src2_r and dst_r can be zero (=unprocessed). - All arguments are complex addressing modes, and it is a binary operator. */ - if (src1_r == 0 && src2_r == 0 && dst_r == 0) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); - } - src1_r = TMP_REG1; - src2_r = TMP_REG2; - } - else if (src1_r == 0 && src2_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - src1_r = TMP_REG1; - } - else if (src1_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); - src1_r = TMP_REG1; - } - else if (src2_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); - src2_r = sugg_src2_r; - } - - if (dst_r == 0) - dst_r = TMP_REG2; - - if (src1_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); - src1_r = TMP_REG1; - } - - if (src2_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); - src2_r = sugg_src2_r; - } - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (flags & (FAST_DEST | SLOW_DEST)) { - if (flags & FAST_DEST) - FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw)); - else - FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0)); - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si int_op = op & SLJIT_INT_OP; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - case SLJIT_NOP: - return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); -#else - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); -#endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); - FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); -#else - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); -#endif - return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); -#else - return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); -#endif - } - - return SLJIT_SUCCESS; -} - -#define EMIT_MOV(type, type_flags, type_cast) \ - emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; - sljit_si op_flags = GET_ALL_FLAGS(op); - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - op = GET_OPCODE(op); - if ((src & SLJIT_IMM) && srcw == 0) - src = TMP_ZERO; - - if (op_flags & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - - if (op_flags & SLJIT_INT_OP) { - if (op < SLJIT_NOT) { - if (FAST_IS_REG(src) && src == dst) { - if (!TYPE_CAST_NEEDED(op)) - return SLJIT_SUCCESS; - } -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; -#endif - } -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - else { - /* Most operations expect sign extended arguments. */ - flags |= INT_DATA | SIGNED_DATA; - if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; - } -#endif - } - - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: -#endif - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOV_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); - - case SLJIT_MOV_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); -#endif - - case SLJIT_MOV_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); - - case SLJIT_MOV_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); - - case SLJIT_MOV_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); - - case SLJIT_MOV_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); - - case SLJIT_MOVU: - case SLJIT_MOVU_P: -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: -#endif - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOVU_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); - - case SLJIT_MOVU_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); -#endif - - case SLJIT_MOVU_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); - - case SLJIT_MOVU_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); - - case SLJIT_MOVU_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); - - case SLJIT_MOVU_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); - - case SLJIT_NOT: - return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: - return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_CLZ: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); -#else - return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); -#endif - } - - return SLJIT_SUCCESS; -} - -#undef EMIT_MOV - -#define TEST_SL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) - -#define TEST_UL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) -#else -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) -#endif - -#define TEST_UH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000)) - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define TEST_ADD_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) -#else -#define TEST_ADD_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define TEST_UI_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) -#else -#define TEST_UI_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - if ((src1 & SLJIT_IMM) && src1w == 0) - src1 = TMP_ZERO; - if ((src2 & SLJIT_IMM) && src2w == 0) - src2 = TMP_ZERO; - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) { - /* Most operations expect sign extended arguments. */ - flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) - src1w = (sljit_si)(src1w); - if (src2 & SLJIT_IMM) - src2w = (sljit_si)(src2w); - if (GET_FLAGS(op)) - flags |= ALT_SIGN_EXT; - } -#endif - if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - if (src2 == TMP_REG2) - flags |= ALT_KEEP_CACHE; - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { - if (TEST_SL_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_SL_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); - } - if (TEST_SH_IMM(src2, src2w)) { - compiler->imm = (src2w >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_SH_IMM(src1, src1w)) { - compiler->imm = (src1w >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); - } - /* Range between -1 and -32768 is covered above. */ - if (TEST_ADD_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_ADD_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) { - if (TEST_SL_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_SL_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_ADDC: - return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUB: - if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { - if (TEST_SL_IMM(src2, -src2w)) { - compiler->imm = (-src2w) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_SL_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); - } - if (TEST_SH_IMM(src2, -src2w)) { - compiler->imm = ((-src2w) >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); - } - /* Range between -1 and -32768 is covered above. */ - if (TEST_ADD_IMM(src2, -src2w)) { - compiler->imm = -src2w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); - } - } - if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { - if (!(op & SLJIT_SET_U)) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ - if (TEST_SL_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ - if (TEST_UL_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); - } - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); - } - if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) { - compiler->imm = src2w; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); - } - return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); - } - if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) { - if (TEST_SL_IMM(src2, -src2w)) { - compiler->imm = (-src2w) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); - } - } - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ - return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUBC: - return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_MUL: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) - flags |= ALT_FORM2; -#endif - if (!GET_FLAGS(op)) { - if (TEST_SL_IMM(src2, src2w)) { - compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_SL_IMM(src1, src1w)) { - compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_AND: - case SLJIT_OR: - case SLJIT_XOR: - /* Commutative unsigned operations. */ - if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { - if (TEST_UL_IMM(src2, src2w)) { - compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_UL_IMM(src1, src1w)) { - compiler->imm = src1w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); - } - if (TEST_UH_IMM(src2, src2w)) { - compiler->imm = (src2w >> 16) & 0xffff; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_UH_IMM(src1, src1w)) { - compiler->imm = (src1w >> 16) & 0xffff; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) { - if (TEST_UI_IMM(src2, src2w)) { - compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); - } - if (TEST_UI_IMM(src1, src1w)) { - compiler->imm = src1w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); - } - } - return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_ASHR: - if (op & SLJIT_KEEP_FLAGS) - flags |= ALT_FORM3; - /* Fall through. */ - case SLJIT_SHL: - case SLJIT_LSHR: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) - flags |= ALT_FORM2; -#endif - if (src2 & SLJIT_IMM) { - compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); - } - return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - return push_inst(compiler, *(sljit_ins*)instruction); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#else - /* Available by default. */ - return 1; -#endif -} - -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) - -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw)) -#endif - -#endif /* SLJIT_CONFIG_PPC_64 */ - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (src & SLJIT_MEM) { - /* We can ignore the temporary data store on the stack from caching point of view. */ - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - src = TMP_FREG1; - } - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - op = GET_OPCODE(op); - FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (op == SLJIT_CONVW_FROMD) { - if (FAST_IS_REG(dst)) { - FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0)); - return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); - } - return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0); - } - -#else - FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src))); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; -#endif - - if (FAST_IS_REG(dst)) { - FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET)); - FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1))); - return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); - } - - SLJIT_ASSERT(dst & SLJIT_MEM); - - if (dst & OFFS_REG_MASK) { - dstw &= 0x3; - if (dstw) { -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1))); -#else - FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1))); -#endif - dstw = TMP_REG1; - } - else - dstw = OFFS_REG(dst); - } - else { - if ((dst & REG_MASK) && !dstw) { - dstw = dst & REG_MASK; - dst = 0; - } - else { - /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */ - FAIL_IF(load_immediate(compiler, TMP_REG1, dstw)); - dstw = TMP_REG1; - } - } - - return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) { - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); - else - FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - src = TMP_REG1; - } - - if (FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw)); - } - else - FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - - FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); - - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#else - - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_si invert_sign = 1; - - if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000)); - src = TMP_REG1; - invert_sign = 0; - } - else if (!FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); - src = TMP_REG1; - } - - /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31))) - The double precision format has exactly 53 bit precision, so the lower 32 bit represents - the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000 - to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating - point value, we need to substract 2^53 + 2^31 from the constructed value. */ - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); - if (invert_sign) - FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI)); - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); - FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); - - FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); - - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#endif -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - src1 = TMP_FREG1; - } - - if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); - src2 = TMP_FREG2; - } - - return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); - src = dst_r; - } - - switch (GET_OPCODE(op)) { - case SLJIT_CONVD_FROMS: - op ^= SLJIT_SINGLE_OP; - if (op & SLJIT_SINGLE_OP) { - FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src))); - break; - } - /* Fall through. */ - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src))); - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src))); - break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src))); - break; - } - - if (dst & SLJIT_MEM) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0)); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, flags = 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2; - - if (src1 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1 = TMP_FREG1; - } else - flags |= ALT_FORM1; - } - - if (src2 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { - FAIL_IF(compiler->error); - src2 = TMP_FREG2; - } else - flags |= ALT_FORM2; - } - - if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - } - } - else if (flags & ALT_FORM1) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - else if (flags & ALT_FORM2) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - - if (flags & ALT_FORM1) - src1 = TMP_FREG1; - if (flags & ALT_FORM2) - src2 = TMP_FREG2; - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); - break; - - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); - break; - - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); - break; - - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); - break; - } - - if (dst_r == TMP_FREG2) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); - - return SLJIT_SUCCESS; -} - -#undef FLOAT_DATA -#undef SELECT_FOP - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, MFLR | D(dst)); - - /* Memory. */ - FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, MTLR | S(src))); - else { - if (src & SLJIT_MEM) - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); - FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); - } - return push_inst(compiler, BLR); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -static sljit_ins get_bo_bi_flags(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - return (12 << 21) | (2 << 16); - - case SLJIT_NOT_EQUAL: - return (4 << 21) | (2 << 16); - - case SLJIT_LESS: - case SLJIT_D_LESS: - return (12 << 21) | ((4 + 0) << 16); - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - return (4 << 21) | ((4 + 0) << 16); - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - return (12 << 21) | ((4 + 1) << 16); - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - return (4 << 21) | ((4 + 1) << 16); - - case SLJIT_SIG_LESS: - return (12 << 21) | (0 << 16); - - case SLJIT_SIG_GREATER_EQUAL: - return (4 << 21) | (0 << 16); - - case SLJIT_SIG_GREATER: - return (12 << 21) | (1 << 16); - - case SLJIT_SIG_LESS_EQUAL: - return (4 << 21) | (1 << 16); - - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - return (12 << 21) | (3 << 16); - - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - return (4 << 21) | (3 << 16); - - case SLJIT_D_EQUAL: - return (12 << 21) | ((4 + 2) << 16); - - case SLJIT_D_NOT_EQUAL: - return (4 << 21) | ((4 + 2) << 16); - - case SLJIT_D_UNORDERED: - return (12 << 21) | ((4 + 3) << 16); - - case SLJIT_D_ORDERED: - return (4 << 21) | ((4 + 3) << 16); - - default: - SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); - return (20 << 21); - } -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - sljit_ins bo_bi_flags; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - bo_bi_flags = get_bo_bi_flags(type & 0xff); - if (!bo_bi_flags) - return NULL; - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - /* In PPC, we don't need to touch the arguments. */ - if (type < SLJIT_JUMP) - jump->flags |= IS_COND; -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) - if (type >= SLJIT_CALL0) - jump->flags |= IS_CALL; -#endif - - PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); - PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG))); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump = NULL; - sljit_si src_r; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) { -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) - if (type >= SLJIT_CALL0) { - FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src))); - src_r = TMP_CALL_REG; - } - else - src_r = src; -#else - src_r = src; -#endif - } else if (src & SLJIT_IMM) { - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR); - jump->u.target = srcw; -#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) - if (type >= SLJIT_CALL0) - jump->flags |= IS_CALL; -#endif - FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); - src_r = TMP_CALL_REG; - } - else { - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw)); - src_r = TMP_CALL_REG; - } - - FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); - if (jump) - jump->addr = compiler->size; - return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)); -} - -/* Get a bit from CR, all other bits are zeroed. */ -#define GET_CR_BIT(bit, dst) \ - FAIL_IF(push_inst(compiler, MFCR | D(dst))); \ - FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1))); - -#define INVERT_BIT(dst) \ - FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si reg, input_flags; - sljit_si flags = GET_ALL_FLAGS(op); - sljit_sw original_dstw = dstw; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; -#else - input_flags = WORD_DATA; -#endif - FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } - - switch (type & 0xff) { - case SLJIT_EQUAL: - GET_CR_BIT(2, reg); - break; - - case SLJIT_NOT_EQUAL: - GET_CR_BIT(2, reg); - INVERT_BIT(reg); - break; - - case SLJIT_LESS: - case SLJIT_D_LESS: - GET_CR_BIT(4 + 0, reg); - break; - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - GET_CR_BIT(4 + 0, reg); - INVERT_BIT(reg); - break; - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - GET_CR_BIT(4 + 1, reg); - break; - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - GET_CR_BIT(4 + 1, reg); - INVERT_BIT(reg); - break; - - case SLJIT_SIG_LESS: - GET_CR_BIT(0, reg); - break; - - case SLJIT_SIG_GREATER_EQUAL: - GET_CR_BIT(0, reg); - INVERT_BIT(reg); - break; - - case SLJIT_SIG_GREATER: - GET_CR_BIT(1, reg); - break; - - case SLJIT_SIG_LESS_EQUAL: - GET_CR_BIT(1, reg); - INVERT_BIT(reg); - break; - - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - GET_CR_BIT(3, reg); - break; - - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - GET_CR_BIT(3, reg); - INVERT_BIT(reg); - break; - - case SLJIT_D_EQUAL: - GET_CR_BIT(4 + 2, reg); - break; - - case SLJIT_D_NOT_EQUAL: - GET_CR_BIT(4 + 2, reg); - INVERT_BIT(reg); - break; - - case SLJIT_D_UNORDERED: - GET_CR_BIT(4 + 3, reg); - break; - - case SLJIT_D_ORDERED: - GET_CR_BIT(4 + 3, reg); - INVERT_BIT(reg); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - - if (op < SLJIT_ADD) { -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV) - input_flags = WORD_DATA; - else { - op = SLJIT_MOV_UI; - input_flags = INT_DATA; - } -#else - op = SLJIT_MOV; - input_flags = WORD_DATA; -#endif - if (reg != TMP_REG2) - return SLJIT_SUCCESS; - return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); - } - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si reg; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); - return const_; -} diff --git a/pcre2/src/sljit/sljitNativeSPARC_32.c b/pcre2/src/sljit/sljitNativeSPARC_32.c deleted file mode 100644 index 4a2e6293d..000000000 --- a/pcre2/src/sljit/sljitNativeSPARC_32.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm) -{ - if (imm <= SIMM_MAX && imm >= SIMM_MIN) - return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst)); - - FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst))); - return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS; -} - -#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2)) - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) -{ - SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same); - - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_UB) - return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst)); - FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst))); - return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst))); - return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - /* sparc 32 does not support SLJIT_KEEP_FLAGS. Not sure I can fix this. */ - FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS)); - FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS | (flags & SET_FLAGS))); - FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst))); - - /* Loop. */ - FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS)); - FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS)); - return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS | (flags & SET_FLAGS)); - - case SLJIT_ADD: - return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_ADDC: - return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_SUB: - return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_SUBC: - return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_MUL: - FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); - if (!(flags & SET_FLAGS)) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK))); - return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS); - - case SLJIT_AND: - return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_OR: - return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_XOR: - return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); - - case SLJIT_SHL: - FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); - return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); - - case SLJIT_LSHR: - FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); - return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); - - case SLJIT_ASHR: - FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); - return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) -{ - FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst))); - return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff); - inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); - inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); - SLJIT_CACHE_FLUSH(inst, inst + 2); -} diff --git a/pcre2/src/sljit/sljitNativeSPARC_common.c b/pcre2/src/sljit/sljitNativeSPARC_common.c deleted file mode 100644 index 327c4267b..000000000 --- a/pcre2/src/sljit/sljitNativeSPARC_common.c +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "SPARC" SLJIT_CPUINFO; -} - -/* Length of an instruction word - Both for sparc-32 and sparc-64 */ -typedef sljit_ui sljit_ins; - -static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) -{ -#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590 - __asm ( - /* if (from == to) return */ - "cmp %i0, %i1\n" - "be .leave\n" - "nop\n" - - /* loop until from >= to */ - ".mainloop:\n" - "flush %i0\n" - "add %i0, 8, %i0\n" - "cmp %i0, %i1\n" - "bcs .mainloop\n" - "nop\n" - - /* The comparison was done above. */ - "bne .leave\n" - /* nop is not necessary here, since the - sub operation has no side effect. */ - "sub %i0, 4, %i0\n" - "flush %i0\n" - ".leave:" - ); -#else - if (SLJIT_UNLIKELY(from == to)) - return; - - do { - __asm__ volatile ( - "flush %0\n" - : : "r"(from) - ); - /* Operates at least on doubleword. */ - from += 2; - } while (from < to); - - if (from == to) { - /* Flush the last word. */ - from --; - __asm__ volatile ( - "flush %0\n" - : : "r"(from) - ); - } -#endif -} - -/* TMP_REG2 is not used by getput_arg */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5) - -#define TMP_FREG1 (0) -#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { - 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15 -}; - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -#define D(d) (reg_map[d] << 25) -#define DA(d) ((d) << 25) -#define S1(s1) (reg_map[s1] << 14) -#define S2(s2) (reg_map[s2]) -#define S1A(s1) ((s1) << 14) -#define S2A(s2) (s2) -#define IMM_ARG 0x2000 -#define DOP(op) ((op) << 5) -#define IMM(imm) (((imm) & 0x1fff) | IMM_ARG) - -#define DR(dr) (reg_map[dr]) -#define OPC1(opcode) ((opcode) << 30) -#define OPC2(opcode) ((opcode) << 22) -#define OPC3(opcode) ((opcode) << 19) -#define SET_FLAGS OPC3(0x10) - -#define ADD (OPC1(0x2) | OPC3(0x00)) -#define ADDC (OPC1(0x2) | OPC3(0x08)) -#define AND (OPC1(0x2) | OPC3(0x01)) -#define ANDN (OPC1(0x2) | OPC3(0x05)) -#define CALL (OPC1(0x1)) -#define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09)) -#define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42)) -#define FADDS (OPC1(0x2) | OPC3(0x34) | DOP(0x41)) -#define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52)) -#define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51)) -#define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e)) -#define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d)) -#define FDTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd2)) -#define FDTOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc6)) -#define FITOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc8)) -#define FITOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc4)) -#define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01)) -#define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a)) -#define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49)) -#define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05)) -#define FSTOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc9)) -#define FSTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd1)) -#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46)) -#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45)) -#define JMPL (OPC1(0x2) | OPC3(0x38)) -#define NOP (OPC1(0x0) | OPC2(0x04)) -#define OR (OPC1(0x2) | OPC3(0x02)) -#define ORN (OPC1(0x2) | OPC3(0x06)) -#define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0)) -#define RESTORE (OPC1(0x2) | OPC3(0x3d)) -#define SAVE (OPC1(0x2) | OPC3(0x3c)) -#define SETHI (OPC1(0x0) | OPC2(0x04)) -#define SLL (OPC1(0x2) | OPC3(0x25)) -#define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12)) -#define SRA (OPC1(0x2) | OPC3(0x27)) -#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12)) -#define SRL (OPC1(0x2) | OPC3(0x26)) -#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12)) -#define SUB (OPC1(0x2) | OPC3(0x04)) -#define SUBC (OPC1(0x2) | OPC3(0x0c)) -#define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25)) -#define WRY (OPC1(0x2) | OPC3(0x30) | DA(0)) -#define XOR (OPC1(0x2) | OPC3(0x03)) -#define XNOR (OPC1(0x2) | OPC3(0x07)) - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#define MAX_DISP (0x1fffff) -#define MIN_DISP (-0x200000) -#define DISP_MASK (0x3fffff) - -#define BICC (OPC1(0x0) | OPC2(0x2)) -#define FBFCC (OPC1(0x0) | OPC2(0x6)) -#define SLL_W SLL -#define SDIV (OPC1(0x2) | OPC3(0x0f)) -#define SMUL (OPC1(0x2) | OPC3(0x0b)) -#define UDIV (OPC1(0x2) | OPC3(0x0e)) -#define UMUL (OPC1(0x2) | OPC3(0x0a)) -#else -#define SLL_W SLLX -#endif - -#define SIMM_MAX (0x0fff) -#define SIMM_MIN (-0x1000) - -/* dest_reg is the absolute name of the register - Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) -{ - sljit_ins *ptr; - SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS - || (delay_slot & DST_INS_MASK) == MOVABLE_INS - || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f)); - ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - compiler->delay_slot = delay_slot; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - sljit_ins *inst; - sljit_ins saved_inst; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return code_ptr; - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - inst = (sljit_ins*)jump->addr; - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - if (jump->flags & IS_CALL) { - /* Call is always patchable on sparc 32. */ - jump->flags |= PATCH_CALL; - if (jump->flags & IS_MOVABLE) { - inst[0] = inst[-1]; - inst[-1] = CALL; - jump->addr -= sizeof(sljit_ins); - return inst; - } - inst[0] = CALL; - inst[1] = NOP; - return inst + 1; - } -#else - /* Both calls and BPr instructions shall not pass this point. */ -#error "Implementation required" -#endif - - if (jump->flags & IS_COND) - inst--; - - if (jump->flags & IS_MOVABLE) { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2; - if (diff <= MAX_DISP && diff >= MIN_DISP) { - jump->flags |= PATCH_B; - inst--; - if (jump->flags & IS_COND) { - saved_inst = inst[0]; - inst[0] = inst[1] ^ (1 << 28); - inst[1] = saved_inst; - } else { - inst[1] = inst[0]; - inst[0] = BICC | DA(0x8); - } - jump->addr = (sljit_uw)inst; - return inst + 1; - } - } - - diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; - if (diff <= MAX_DISP && diff >= MIN_DISP) { - jump->flags |= PATCH_B; - if (jump->flags & IS_COND) - inst[0] ^= (1 << 28); - else - inst[0] = BICC | DA(0x8); - inst[1] = NOP; - jump->addr = (sljit_uw)inst; - return inst + 1; - } - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = (sljit_ins*)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 2); - do { - *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - jump->addr = (sljit_uw)(code_ptr - 3); -#else - jump->addr = (sljit_uw)(code_ptr - 6); -#endif - code_ptr = detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; - } - code_ptr ++; - word_count ++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size); - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; - - if (jump->flags & PATCH_CALL) { - addr = (sljit_sw)(addr - jump->addr) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000); - buf_ptr[0] = CALL | (addr & 0x3fffffff); - break; - } - if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - jump->addr) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP); - buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK); - break; - } - - /* Set the fields of immediate loads. */ -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); - buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); -#else -#error "Implementation required" -#endif - } while (0); - jump = jump->next; - } - - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); - return code; -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -/* Creates an index in data_transfer_insts array. */ -#define LOAD_DATA 0x01 -#define WORD_DATA 0x00 -#define BYTE_DATA 0x02 -#define HALF_DATA 0x04 -#define INT_DATA 0x06 -#define SIGNED_DATA 0x08 -/* Separates integer and floating point registers */ -#define GPR_REG 0x0f -#define DOUBLE_DATA 0x10 -#define SINGLE_DATA 0x12 - -#define MEM_MASK 0x1f - -#define WRITE_BACK 0x00020 -#define ARG_TEST 0x00040 -#define ALT_KEEP_CACHE 0x00080 -#define CUMULATIVE_OP 0x00100 -#define IMM_OP 0x00200 -#define SRC2_IMM 0x00400 - -#define REG_DEST 0x00800 -#define REG2_SOURCE 0x01000 -#define SLOW_SRC1 0x02000 -#define SLOW_SRC2 0x04000 -#define SLOW_DEST 0x08000 - -/* SET_FLAGS (0x10 << 19) also belong here! */ - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#include "sljitNativeSPARC_32.c" -#else -#include "sljitNativeSPARC_64.c" -#endif - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7; - compiler->local_size = local_size; - - if (local_size <= SIMM_MAX) { - FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS)); - } - else { - FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size)); - FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS)); - } - - /* Arguments are in their appropriate registers. */ - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - if (op != SLJIT_MOV || !FAST_IS_REG(src)) { - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - src = SLJIT_R0; - } - - FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS)); - return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS); -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#define ARCH_32_64(a, b) a -#else -#define ARCH_32_64(a, b) b -#endif - -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { -/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), -/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), -/* u b s */ OPC1(3) | OPC3(0x05) /* stb */, -/* u b l */ OPC1(3) | OPC3(0x01) /* ldub */, -/* u h s */ OPC1(3) | OPC3(0x06) /* sth */, -/* u h l */ OPC1(3) | OPC3(0x02) /* lduh */, -/* u i s */ OPC1(3) | OPC3(0x04) /* stw */, -/* u i l */ OPC1(3) | OPC3(0x00) /* lduw */, - -/* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), -/* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), -/* s b s */ OPC1(3) | OPC3(0x05) /* stb */, -/* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */, -/* s h s */ OPC1(3) | OPC3(0x06) /* sth */, -/* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */, -/* s i s */ OPC1(3) | OPC3(0x04) /* stw */, -/* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */), - -/* d s */ OPC1(3) | OPC3(0x27), -/* d l */ OPC1(3) | OPC3(0x23), -/* s s */ OPC1(3) | OPC3(0x24), -/* s l */ OPC1(3) | OPC3(0x20), -}; - -#undef ARCH_32_64 - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - SLJIT_ASSERT(arg & SLJIT_MEM); - - if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) { - if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) - || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) { - /* Works for both absoulte and relative addresses (immediate case). */ - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] - | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)) - | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)), - ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS)); - return -1; - } - } - return 0; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - - /* Simple operation except for updates. */ - if (arg & OFFS_REG_MASK) { - argw &= 0x3; - SLJIT_ASSERT(argw); - next_argw &= 0x3; - if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw) - return 1; - return 0; - } - - if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) - return 1; - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si base, arg2, delay_slot; - sljit_ins dest; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - base = arg & REG_MASK; - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - SLJIT_ASSERT(argw != 0); - - /* Using the cache. */ - if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw)) - arg2 = TMP_REG3; - else { - if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { - compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); - compiler->cache_argw = argw; - arg2 = TMP_REG3; - } - else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg)) - arg2 = reg; - else /* It must be a mov operation, so tmp1 must be free to use. */ - arg2 = TMP_REG1; - FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2))); - } - } - else { - /* Using the cache. */ - if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); - compiler->cache_argw = argw; - } - arg2 = TMP_REG3; - } else { - if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) { - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - arg2 = TMP_REG3; - } - else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base) - arg2 = reg; - else /* It must be a mov operation, so tmp1 must be free to use. */ - arg2 = TMP_REG1; - FAIL_IF(load_immediate(compiler, arg2, argw)); - } - } - - dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)); - delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS; - if (!base) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot); - if (!(flags & WRITE_BACK)) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot); - FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot)); - return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg - arg2 goes to TMP_REG2, imm or src reg - TMP_REG3 can be used for caching - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; - sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - - if (!(flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } - - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - } - else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } - else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) - flags |= SLOW_DEST; - - if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w) { - if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) { - flags |= SRC2_IMM; - src2_r = src2w; - } - } - if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { - if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) { - flags |= SRC2_IMM; - src2_r = src1w; - - /* And swap arguments. */ - src1 = src2; - src1w = src2w; - src2 = SLJIT_IMM; - /* src2w = src2_r unneeded. */ - } - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) - src1_r = src1; - else if (src1 & SLJIT_IMM) { - if (src1w) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1_r = TMP_REG1; - } - else - src1_r = 0; - } - else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - src1_r = TMP_REG1; - } - - /* Source 2. */ - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - dst_r = src2_r; - } - else if (src2 & SLJIT_IMM) { - if (!(flags & SRC2_IMM)) { - if (src2w) { - FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); - src2_r = sugg_src2_r; - } - else { - src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) - dst_r = 0; - } - } - } - else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - src2_r = sugg_src2_r; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - SLJIT_ASSERT(src2_r == TMP_REG2); - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, flags, dst_r, dst, dstw); - return compiler->error; - } - return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_BREAKPOINT: - return push_inst(compiler, TA, UNMOVABLE_INS); - case SLJIT_NOP: - return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); - return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1)); -#else -#error "Implementation required" -#endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - if ((op | 0x2) == SLJIT_UDIVI) - FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); - else { - FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); - } - if (op <= SLJIT_SDIVMOD) - FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); - if (op >= SLJIT_UDIVI) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1))); - return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)); -#else -#error "Implementation required" -#endif - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_MOVU: - case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); - - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); - - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); - - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); - - case SLJIT_NOT: - case SLJIT_CLZ: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: - return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_ADD: - case SLJIT_ADDC: - case SLJIT_MUL: - case SLJIT_AND: - case SLJIT_OR: - case SLJIT_XOR: - return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUB: - case SLJIT_SUBC: - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - if (src2 & SLJIT_IMM) - src2w &= 0x1f; -#else - SLJIT_ASSERT_STOP(); -#endif - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg << 1; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#else - /* Available by default. */ - return 1; -#endif -} - -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) -#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw)) - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - src = TMP_FREG1; - } - else - src <<= 1; - - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS)); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) { - FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET); - } - - /* Store the integer value from a VFP register. */ - return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - - if (src & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; -#endif - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; - } - - if (FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); - src = SLJIT_MEM1(SLJIT_SP); - srcw = FLOAT_TMP_MEM_OFFSET; - } - - FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS)); - - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - src1 = TMP_FREG1; - } - else - src1 <<= 1; - - if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); - src2 = TMP_FREG2; - } - else - src2 <<= 1; - - return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - - CHECK_ERROR(); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; - - dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); - src = dst_r; - } - else - src <<= 1; - - switch (GET_OPCODE(op)) { - case SLJIT_DMOV: - if (src != dst_r) { - if (dst_r != TMP_FREG1) { - FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (!(op & SLJIT_SINGLE_OP)) - FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); - } - else - dst_r = src; - } - break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) - FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); - break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) - FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); - break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; - break; - } - - if (dst & SLJIT_MEM) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0)); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r, flags = 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; - - if (src1 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1 = TMP_FREG1; - } else - flags |= SLOW_SRC1; - } - else - src1 <<= 1; - - if (src2 & SLJIT_MEM) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { - FAIL_IF(compiler->error); - src2 = TMP_FREG2; - } else - flags |= SLOW_SRC2; - } - else - src2 <<= 1; - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - } - else { - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - - if (flags & SLOW_SRC1) - src1 = TMP_FREG1; - if (flags & SLOW_SRC2) - src2 = TMP_FREG2; - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); - break; - - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); - break; - - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); - break; - - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); - break; - } - - if (dst_r == TMP_FREG2) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); - - return SLJIT_SUCCESS; -} - -#undef FLOAT_DATA -#undef SELECT_FOP - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst)); - - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK))); - else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw)); - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, TMP_LINK, srcw)); - - FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS)); - return push_inst(compiler, NOP, UNMOVABLE_INS); -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - compiler->delay_slot = UNMOVABLE_INS; - return label; -} - -static sljit_ins get_cc(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_NOT_EQUAL: /* Unordered. */ - return DA(0x1); - - case SLJIT_NOT_EQUAL: - case SLJIT_MUL_OVERFLOW: - case SLJIT_D_EQUAL: - return DA(0x9); - - case SLJIT_LESS: - case SLJIT_D_GREATER: /* Unordered. */ - return DA(0x5); - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS_EQUAL: - return DA(0xd); - - case SLJIT_GREATER: - case SLJIT_D_GREATER_EQUAL: /* Unordered. */ - return DA(0xc); - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS: - return DA(0x4); - - case SLJIT_SIG_LESS: - return DA(0x3); - - case SLJIT_SIG_GREATER_EQUAL: - return DA(0xb); - - case SLJIT_SIG_GREATER: - return DA(0xa); - - case SLJIT_SIG_LESS_EQUAL: - return DA(0x2); - - case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: - return DA(0x7); - - case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: - return DA(0xf); - - default: - SLJIT_ASSERT_STOP(); - return DA(0x8); - } -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - if (type < SLJIT_D_EQUAL) { - jump->flags |= IS_COND; - if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) - jump->flags |= IS_MOVABLE; -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); -#else -#error "Implementation required" -#endif - } - else if (type < SLJIT_JUMP) { - jump->flags |= IS_COND; - if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET)) - jump->flags |= IS_MOVABLE; -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); -#else -#error "Implementation required" -#endif - } else { - if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) - jump->flags |= IS_MOVABLE; - if (type >= SLJIT_FAST_CALL) - jump->flags |= IS_CALL; - } - - PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); - jump->addr = compiler->size; - PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - struct sljit_jump *jump = NULL; - sljit_si src_r; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - src_r = src; - else if (src & SLJIT_IMM) { - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR); - jump->u.target = srcw; - if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) - jump->flags |= IS_MOVABLE; - if (type >= SLJIT_FAST_CALL) - jump->flags |= IS_CALL; - - FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - src_r = TMP_REG2; - } - else { - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); - src_r = TMP_REG2; - } - - FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); - if (jump) - jump->addr = compiler->size; - return push_inst(compiler, NOP, UNMOVABLE_INS); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } - - type &= 0xff; - if (type < SLJIT_D_EQUAL) - FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); - else - FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); - - FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS)); - - if (op >= SLJIT_ADD) - return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); - - return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; -#else -#error "Implementation required" -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - sljit_si reg; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); - return const_; -} diff --git a/pcre2/src/sljit/sljitNativeTILEGX-encoder.c b/pcre2/src/sljit/sljitNativeTILEGX-encoder.c deleted file mode 100644 index 719632908..000000000 --- a/pcre2/src/sljit/sljitNativeTILEGX-encoder.c +++ /dev/null @@ -1,10159 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* This code is owned by Tilera Corporation, and distributed as part - of multiple projects. In sljit, the code is under BSD licence. */ - -#include -#include -#include -#define BFD_RELOC(x) R_##x - -/* Special registers. */ -#define TREG_LR 55 -#define TREG_SN 56 -#define TREG_ZERO 63 - -/* Canonical name of each register. */ -const char *const tilegx_register_names[] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", - "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", - "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", - "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero" -}; - -enum -{ - R_NONE = 0, - R_TILEGX_NONE = 0, - R_TILEGX_64 = 1, - R_TILEGX_32 = 2, - R_TILEGX_16 = 3, - R_TILEGX_8 = 4, - R_TILEGX_64_PCREL = 5, - R_TILEGX_32_PCREL = 6, - R_TILEGX_16_PCREL = 7, - R_TILEGX_8_PCREL = 8, - R_TILEGX_HW0 = 9, - R_TILEGX_HW1 = 10, - R_TILEGX_HW2 = 11, - R_TILEGX_HW3 = 12, - R_TILEGX_HW0_LAST = 13, - R_TILEGX_HW1_LAST = 14, - R_TILEGX_HW2_LAST = 15, - R_TILEGX_COPY = 16, - R_TILEGX_GLOB_DAT = 17, - R_TILEGX_JMP_SLOT = 18, - R_TILEGX_RELATIVE = 19, - R_TILEGX_BROFF_X1 = 20, - R_TILEGX_JUMPOFF_X1 = 21, - R_TILEGX_JUMPOFF_X1_PLT = 22, - R_TILEGX_IMM8_X0 = 23, - R_TILEGX_IMM8_Y0 = 24, - R_TILEGX_IMM8_X1 = 25, - R_TILEGX_IMM8_Y1 = 26, - R_TILEGX_DEST_IMM8_X1 = 27, - R_TILEGX_MT_IMM14_X1 = 28, - R_TILEGX_MF_IMM14_X1 = 29, - R_TILEGX_MMSTART_X0 = 30, - R_TILEGX_MMEND_X0 = 31, - R_TILEGX_SHAMT_X0 = 32, - R_TILEGX_SHAMT_X1 = 33, - R_TILEGX_SHAMT_Y0 = 34, - R_TILEGX_SHAMT_Y1 = 35, - R_TILEGX_IMM16_X0_HW0 = 36, - R_TILEGX_IMM16_X1_HW0 = 37, - R_TILEGX_IMM16_X0_HW1 = 38, - R_TILEGX_IMM16_X1_HW1 = 39, - R_TILEGX_IMM16_X0_HW2 = 40, - R_TILEGX_IMM16_X1_HW2 = 41, - R_TILEGX_IMM16_X0_HW3 = 42, - R_TILEGX_IMM16_X1_HW3 = 43, - R_TILEGX_IMM16_X0_HW0_LAST = 44, - R_TILEGX_IMM16_X1_HW0_LAST = 45, - R_TILEGX_IMM16_X0_HW1_LAST = 46, - R_TILEGX_IMM16_X1_HW1_LAST = 47, - R_TILEGX_IMM16_X0_HW2_LAST = 48, - R_TILEGX_IMM16_X1_HW2_LAST = 49, - R_TILEGX_IMM16_X0_HW0_PCREL = 50, - R_TILEGX_IMM16_X1_HW0_PCREL = 51, - R_TILEGX_IMM16_X0_HW1_PCREL = 52, - R_TILEGX_IMM16_X1_HW1_PCREL = 53, - R_TILEGX_IMM16_X0_HW2_PCREL = 54, - R_TILEGX_IMM16_X1_HW2_PCREL = 55, - R_TILEGX_IMM16_X0_HW3_PCREL = 56, - R_TILEGX_IMM16_X1_HW3_PCREL = 57, - R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58, - R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59, - R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60, - R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61, - R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62, - R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63, - R_TILEGX_IMM16_X0_HW0_GOT = 64, - R_TILEGX_IMM16_X1_HW0_GOT = 65, - - R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66, - R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67, - R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68, - R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69, - R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70, - R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71, - - R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72, - R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73, - R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74, - R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75, - R_TILEGX_IMM16_X0_HW0_TLS_GD = 78, - R_TILEGX_IMM16_X1_HW0_TLS_GD = 79, - R_TILEGX_IMM16_X0_HW0_TLS_LE = 80, - R_TILEGX_IMM16_X1_HW0_TLS_LE = 81, - R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85, - R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89, - R_TILEGX_IMM16_X0_HW0_TLS_IE = 92, - R_TILEGX_IMM16_X1_HW0_TLS_IE = 93, - - R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94, - R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95, - R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96, - R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97, - R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98, - R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99, - - R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103, - R_TILEGX_TLS_DTPMOD64 = 106, - R_TILEGX_TLS_DTPOFF64 = 107, - R_TILEGX_TLS_TPOFF64 = 108, - R_TILEGX_TLS_DTPMOD32 = 109, - R_TILEGX_TLS_DTPOFF32 = 110, - R_TILEGX_TLS_TPOFF32 = 111, - R_TILEGX_TLS_GD_CALL = 112, - R_TILEGX_IMM8_X0_TLS_GD_ADD = 113, - R_TILEGX_IMM8_X1_TLS_GD_ADD = 114, - R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115, - R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116, - R_TILEGX_TLS_IE_LOAD = 117, - R_TILEGX_IMM8_X0_TLS_ADD = 118, - R_TILEGX_IMM8_X1_TLS_ADD = 119, - R_TILEGX_IMM8_Y0_TLS_ADD = 120, - R_TILEGX_IMM8_Y1_TLS_ADD = 121, - R_TILEGX_GNU_VTINHERIT = 128, - R_TILEGX_GNU_VTENTRY = 129, - R_TILEGX_IRELATIVE = 130, - R_TILEGX_NUM = 131 -}; - -typedef enum -{ - TILEGX_PIPELINE_X0, - TILEGX_PIPELINE_X1, - TILEGX_PIPELINE_Y0, - TILEGX_PIPELINE_Y1, - TILEGX_PIPELINE_Y2, -} tilegx_pipeline; - -typedef unsigned long long tilegx_bundle_bits; - -/* These are the bits that determine if a bundle is in the X encoding. */ -#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62) - -enum -{ - /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */ - TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3, - - /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */ - TILEGX_NUM_PIPELINE_ENCODINGS = 5, - - /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */ - TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3, - - /* Instructions take this many bytes. */ - TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES, - - /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */ - TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3, - - /* Bundles should be aligned modulo this number of bytes. */ - TILEGX_BUNDLE_ALIGNMENT_IN_BYTES = - (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES), - - /* Number of registers (some are magic, such as network I/O). */ - TILEGX_NUM_REGISTERS = 64, -}; - -/* Make a few "tile_" variables to simplify common code between - architectures. */ - -typedef tilegx_bundle_bits tile_bundle_bits; -#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES -#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES -#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ - TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES - -/* 64-bit pattern for a { bpt ; nop } bundle. */ -#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL - -typedef enum -{ - TILEGX_OP_TYPE_REGISTER, - TILEGX_OP_TYPE_IMMEDIATE, - TILEGX_OP_TYPE_ADDRESS, - TILEGX_OP_TYPE_SPR -} tilegx_operand_type; - -struct tilegx_operand -{ - /* Is this operand a register, immediate or address? */ - tilegx_operand_type type; - - /* The default relocation type for this operand. */ - signed int default_reloc : 16; - - /* How many bits is this value? (used for range checking) */ - unsigned int num_bits : 5; - - /* Is the value signed? (used for range checking) */ - unsigned int is_signed : 1; - - /* Is this operand a source register? */ - unsigned int is_src_reg : 1; - - /* Is this operand written? (i.e. is it a destination register) */ - unsigned int is_dest_reg : 1; - - /* Is this operand PC-relative? */ - unsigned int is_pc_relative : 1; - - /* By how many bits do we right shift the value before inserting? */ - unsigned int rightshift : 2; - - /* Return the bits for this operand to be ORed into an existing bundle. */ - tilegx_bundle_bits (*insert) (int op); - - /* Extract this operand and return it. */ - unsigned int (*extract) (tilegx_bundle_bits bundle); -}; - -typedef enum -{ - TILEGX_OPC_BPT, - TILEGX_OPC_INFO, - TILEGX_OPC_INFOL, - TILEGX_OPC_LD4S_TLS, - TILEGX_OPC_LD_TLS, - TILEGX_OPC_MOVE, - TILEGX_OPC_MOVEI, - TILEGX_OPC_MOVELI, - TILEGX_OPC_PREFETCH, - TILEGX_OPC_PREFETCH_ADD_L1, - TILEGX_OPC_PREFETCH_ADD_L1_FAULT, - TILEGX_OPC_PREFETCH_ADD_L2, - TILEGX_OPC_PREFETCH_ADD_L2_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_L1, - TILEGX_OPC_PREFETCH_L1_FAULT, - TILEGX_OPC_PREFETCH_L2, - TILEGX_OPC_PREFETCH_L2_FAULT, - TILEGX_OPC_PREFETCH_L3, - TILEGX_OPC_PREFETCH_L3_FAULT, - TILEGX_OPC_RAISE, - TILEGX_OPC_ADD, - TILEGX_OPC_ADDI, - TILEGX_OPC_ADDLI, - TILEGX_OPC_ADDX, - TILEGX_OPC_ADDXI, - TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXSC, - TILEGX_OPC_AND, - TILEGX_OPC_ANDI, - TILEGX_OPC_BEQZ, - TILEGX_OPC_BEQZT, - TILEGX_OPC_BFEXTS, - TILEGX_OPC_BFEXTU, - TILEGX_OPC_BFINS, - TILEGX_OPC_BGEZ, - TILEGX_OPC_BGEZT, - TILEGX_OPC_BGTZ, - TILEGX_OPC_BGTZT, - TILEGX_OPC_BLBC, - TILEGX_OPC_BLBCT, - TILEGX_OPC_BLBS, - TILEGX_OPC_BLBST, - TILEGX_OPC_BLEZ, - TILEGX_OPC_BLEZT, - TILEGX_OPC_BLTZ, - TILEGX_OPC_BLTZT, - TILEGX_OPC_BNEZ, - TILEGX_OPC_BNEZT, - TILEGX_OPC_CLZ, - TILEGX_OPC_CMOVEQZ, - TILEGX_OPC_CMOVNEZ, - TILEGX_OPC_CMPEQ, - TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPEXCH, - TILEGX_OPC_CMPEXCH4, - TILEGX_OPC_CMPLES, - TILEGX_OPC_CMPLEU, - TILEGX_OPC_CMPLTS, - TILEGX_OPC_CMPLTSI, - TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPLTUI, - TILEGX_OPC_CMPNE, - TILEGX_OPC_CMUL, - TILEGX_OPC_CMULA, - TILEGX_OPC_CMULAF, - TILEGX_OPC_CMULF, - TILEGX_OPC_CMULFR, - TILEGX_OPC_CMULH, - TILEGX_OPC_CMULHR, - TILEGX_OPC_CRC32_32, - TILEGX_OPC_CRC32_8, - TILEGX_OPC_CTZ, - TILEGX_OPC_DBLALIGN, - TILEGX_OPC_DBLALIGN2, - TILEGX_OPC_DBLALIGN4, - TILEGX_OPC_DBLALIGN6, - TILEGX_OPC_DRAIN, - TILEGX_OPC_DTLBPR, - TILEGX_OPC_EXCH, - TILEGX_OPC_EXCH4, - TILEGX_OPC_FDOUBLE_ADD_FLAGS, - TILEGX_OPC_FDOUBLE_ADDSUB, - TILEGX_OPC_FDOUBLE_MUL_FLAGS, - TILEGX_OPC_FDOUBLE_PACK1, - TILEGX_OPC_FDOUBLE_PACK2, - TILEGX_OPC_FDOUBLE_SUB_FLAGS, - TILEGX_OPC_FDOUBLE_UNPACK_MAX, - TILEGX_OPC_FDOUBLE_UNPACK_MIN, - TILEGX_OPC_FETCHADD, - TILEGX_OPC_FETCHADD4, - TILEGX_OPC_FETCHADDGEZ, - TILEGX_OPC_FETCHADDGEZ4, - TILEGX_OPC_FETCHAND, - TILEGX_OPC_FETCHAND4, - TILEGX_OPC_FETCHOR, - TILEGX_OPC_FETCHOR4, - TILEGX_OPC_FINV, - TILEGX_OPC_FLUSH, - TILEGX_OPC_FLUSHWB, - TILEGX_OPC_FNOP, - TILEGX_OPC_FSINGLE_ADD1, - TILEGX_OPC_FSINGLE_ADDSUB2, - TILEGX_OPC_FSINGLE_MUL1, - TILEGX_OPC_FSINGLE_MUL2, - TILEGX_OPC_FSINGLE_PACK1, - TILEGX_OPC_FSINGLE_PACK2, - TILEGX_OPC_FSINGLE_SUB1, - TILEGX_OPC_ICOH, - TILEGX_OPC_ILL, - TILEGX_OPC_INV, - TILEGX_OPC_IRET, - TILEGX_OPC_J, - TILEGX_OPC_JAL, - TILEGX_OPC_JALR, - TILEGX_OPC_JALRP, - TILEGX_OPC_JR, - TILEGX_OPC_JRP, - TILEGX_OPC_LD, - TILEGX_OPC_LD1S, - TILEGX_OPC_LD1S_ADD, - TILEGX_OPC_LD1U, - TILEGX_OPC_LD1U_ADD, - TILEGX_OPC_LD2S, - TILEGX_OPC_LD2S_ADD, - TILEGX_OPC_LD2U, - TILEGX_OPC_LD2U_ADD, - TILEGX_OPC_LD4S, - TILEGX_OPC_LD4S_ADD, - TILEGX_OPC_LD4U, - TILEGX_OPC_LD4U_ADD, - TILEGX_OPC_LD_ADD, - TILEGX_OPC_LDNA, - TILEGX_OPC_LDNA_ADD, - TILEGX_OPC_LDNT, - TILEGX_OPC_LDNT1S, - TILEGX_OPC_LDNT1S_ADD, - TILEGX_OPC_LDNT1U, - TILEGX_OPC_LDNT1U_ADD, - TILEGX_OPC_LDNT2S, - TILEGX_OPC_LDNT2S_ADD, - TILEGX_OPC_LDNT2U, - TILEGX_OPC_LDNT2U_ADD, - TILEGX_OPC_LDNT4S, - TILEGX_OPC_LDNT4S_ADD, - TILEGX_OPC_LDNT4U, - TILEGX_OPC_LDNT4U_ADD, - TILEGX_OPC_LDNT_ADD, - TILEGX_OPC_LNK, - TILEGX_OPC_MF, - TILEGX_OPC_MFSPR, - TILEGX_OPC_MM, - TILEGX_OPC_MNZ, - TILEGX_OPC_MTSPR, - TILEGX_OPC_MUL_HS_HS, - TILEGX_OPC_MUL_HS_HU, - TILEGX_OPC_MUL_HS_LS, - TILEGX_OPC_MUL_HS_LU, - TILEGX_OPC_MUL_HU_HU, - TILEGX_OPC_MUL_HU_LS, - TILEGX_OPC_MUL_HU_LU, - TILEGX_OPC_MUL_LS_LS, - TILEGX_OPC_MUL_LS_LU, - TILEGX_OPC_MUL_LU_LU, - TILEGX_OPC_MULA_HS_HS, - TILEGX_OPC_MULA_HS_HU, - TILEGX_OPC_MULA_HS_LS, - TILEGX_OPC_MULA_HS_LU, - TILEGX_OPC_MULA_HU_HU, - TILEGX_OPC_MULA_HU_LS, - TILEGX_OPC_MULA_HU_LU, - TILEGX_OPC_MULA_LS_LS, - TILEGX_OPC_MULA_LS_LU, - TILEGX_OPC_MULA_LU_LU, - TILEGX_OPC_MULAX, - TILEGX_OPC_MULX, - TILEGX_OPC_MZ, - TILEGX_OPC_NAP, - TILEGX_OPC_NOP, - TILEGX_OPC_NOR, - TILEGX_OPC_OR, - TILEGX_OPC_ORI, - TILEGX_OPC_PCNT, - TILEGX_OPC_REVBITS, - TILEGX_OPC_REVBYTES, - TILEGX_OPC_ROTL, - TILEGX_OPC_ROTLI, - TILEGX_OPC_SHL, - TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADDX, - TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADDX, - TILEGX_OPC_SHLI, - TILEGX_OPC_SHLX, - TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRS, - TILEGX_OPC_SHRSI, - TILEGX_OPC_SHRU, - TILEGX_OPC_SHRUI, - TILEGX_OPC_SHRUX, - TILEGX_OPC_SHRUXI, - TILEGX_OPC_SHUFFLEBYTES, - TILEGX_OPC_ST, - TILEGX_OPC_ST1, - TILEGX_OPC_ST1_ADD, - TILEGX_OPC_ST2, - TILEGX_OPC_ST2_ADD, - TILEGX_OPC_ST4, - TILEGX_OPC_ST4_ADD, - TILEGX_OPC_ST_ADD, - TILEGX_OPC_STNT, - TILEGX_OPC_STNT1, - TILEGX_OPC_STNT1_ADD, - TILEGX_OPC_STNT2, - TILEGX_OPC_STNT2_ADD, - TILEGX_OPC_STNT4, - TILEGX_OPC_STNT4_ADD, - TILEGX_OPC_STNT_ADD, - TILEGX_OPC_SUB, - TILEGX_OPC_SUBX, - TILEGX_OPC_SUBXSC, - TILEGX_OPC_SWINT0, - TILEGX_OPC_SWINT1, - TILEGX_OPC_SWINT2, - TILEGX_OPC_SWINT3, - TILEGX_OPC_TBLIDXB0, - TILEGX_OPC_TBLIDXB1, - TILEGX_OPC_TBLIDXB2, - TILEGX_OPC_TBLIDXB3, - TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADDI, - TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADIFFU, - TILEGX_OPC_V1AVGU, - TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQI, - TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTSI, - TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTUI, - TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1DDOTPU, - TILEGX_OPC_V1DDOTPUA, - TILEGX_OPC_V1DDOTPUS, - TILEGX_OPC_V1DDOTPUSA, - TILEGX_OPC_V1DOTP, - TILEGX_OPC_V1DOTPA, - TILEGX_OPC_V1DOTPU, - TILEGX_OPC_V1DOTPUA, - TILEGX_OPC_V1DOTPUS, - TILEGX_OPC_V1DOTPUSA, - TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1MAXU, - TILEGX_OPC_V1MAXUI, - TILEGX_OPC_V1MINU, - TILEGX_OPC_V1MINUI, - TILEGX_OPC_V1MNZ, - TILEGX_OPC_V1MULTU, - TILEGX_OPC_V1MULU, - TILEGX_OPC_V1MULUS, - TILEGX_OPC_V1MZ, - TILEGX_OPC_V1SADAU, - TILEGX_OPC_V1SADU, - TILEGX_OPC_V1SHL, - TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRS, - TILEGX_OPC_V1SHRSI, - TILEGX_OPC_V1SHRU, - TILEGX_OPC_V1SHRUI, - TILEGX_OPC_V1SUB, - TILEGX_OPC_V1SUBUC, - TILEGX_OPC_V2ADD, - TILEGX_OPC_V2ADDI, - TILEGX_OPC_V2ADDSC, - TILEGX_OPC_V2ADIFFS, - TILEGX_OPC_V2AVGS, - TILEGX_OPC_V2CMPEQ, - TILEGX_OPC_V2CMPEQI, - TILEGX_OPC_V2CMPLES, - TILEGX_OPC_V2CMPLEU, - TILEGX_OPC_V2CMPLTS, - TILEGX_OPC_V2CMPLTSI, - TILEGX_OPC_V2CMPLTU, - TILEGX_OPC_V2CMPLTUI, - TILEGX_OPC_V2CMPNE, - TILEGX_OPC_V2DOTP, - TILEGX_OPC_V2DOTPA, - TILEGX_OPC_V2INT_H, - TILEGX_OPC_V2INT_L, - TILEGX_OPC_V2MAXS, - TILEGX_OPC_V2MAXSI, - TILEGX_OPC_V2MINS, - TILEGX_OPC_V2MINSI, - TILEGX_OPC_V2MNZ, - TILEGX_OPC_V2MULFSC, - TILEGX_OPC_V2MULS, - TILEGX_OPC_V2MULTS, - TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, - TILEGX_OPC_V2PACKL, - TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SADAS, - TILEGX_OPC_V2SADAU, - TILEGX_OPC_V2SADS, - TILEGX_OPC_V2SADU, - TILEGX_OPC_V2SHL, - TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHLSC, - TILEGX_OPC_V2SHRS, - TILEGX_OPC_V2SHRSI, - TILEGX_OPC_V2SHRU, - TILEGX_OPC_V2SHRUI, - TILEGX_OPC_V2SUB, - TILEGX_OPC_V2SUBSC, - TILEGX_OPC_V4ADD, - TILEGX_OPC_V4ADDSC, - TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, - TILEGX_OPC_V4PACKSC, - TILEGX_OPC_V4SHL, - TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHRS, - TILEGX_OPC_V4SHRU, - TILEGX_OPC_V4SUB, - TILEGX_OPC_V4SUBSC, - TILEGX_OPC_WH64, - TILEGX_OPC_XOR, - TILEGX_OPC_XORI, - TILEGX_OPC_NONE -} tilegx_mnemonic; - -enum -{ - TILEGX_MAX_OPERANDS = 4 /* bfexts */ -}; - -struct tilegx_opcode -{ - /* The opcode mnemonic, e.g. "add" */ - const char *name; - - /* The enum value for this mnemonic. */ - tilegx_mnemonic mnemonic; - - /* A bit mask of which of the five pipes this instruction - is compatible with: - X0 0x01 - X1 0x02 - Y0 0x04 - Y1 0x08 - Y2 0x10 */ - unsigned char pipes; - - /* How many operands are there? */ - unsigned char num_operands; - - /* Which register does this write implicitly, or TREG_ZERO if none? */ - unsigned char implicitly_written_register; - - /* Can this be bundled with other instructions (almost always true). */ - unsigned char can_bundle; - - /* The description of the operands. Each of these is an - * index into the tilegx_operands[] table. */ - unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS]; - - /* A mask of which bits have predefined values for each pipeline. - * This is useful for disassembly. */ - tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS]; - - /* For each bit set in fixed_bit_masks, what the value is for this - * instruction. */ - tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS]; -}; - -/* Used for non-textual disassembly into structs. */ -struct tilegx_decoded_instruction -{ - const struct tilegx_opcode *opcode; - const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS]; - long long operand_values[TILEGX_MAX_OPERANDS]; -}; - -enum -{ - ADDI_IMM8_OPCODE_X0 = 1, - ADDI_IMM8_OPCODE_X1 = 1, - ADDI_OPCODE_Y0 = 0, - ADDI_OPCODE_Y1 = 1, - ADDLI_OPCODE_X0 = 1, - ADDLI_OPCODE_X1 = 0, - ADDXI_IMM8_OPCODE_X0 = 2, - ADDXI_IMM8_OPCODE_X1 = 2, - ADDXI_OPCODE_Y0 = 1, - ADDXI_OPCODE_Y1 = 2, - ADDXLI_OPCODE_X0 = 2, - ADDXLI_OPCODE_X1 = 1, - ADDXSC_RRR_0_OPCODE_X0 = 1, - ADDXSC_RRR_0_OPCODE_X1 = 1, - ADDX_RRR_0_OPCODE_X0 = 2, - ADDX_RRR_0_OPCODE_X1 = 2, - ADDX_RRR_0_OPCODE_Y0 = 0, - ADDX_SPECIAL_0_OPCODE_Y1 = 0, - ADD_RRR_0_OPCODE_X0 = 3, - ADD_RRR_0_OPCODE_X1 = 3, - ADD_RRR_0_OPCODE_Y0 = 1, - ADD_SPECIAL_0_OPCODE_Y1 = 1, - ANDI_IMM8_OPCODE_X0 = 3, - ANDI_IMM8_OPCODE_X1 = 3, - ANDI_OPCODE_Y0 = 2, - ANDI_OPCODE_Y1 = 3, - AND_RRR_0_OPCODE_X0 = 4, - AND_RRR_0_OPCODE_X1 = 4, - AND_RRR_5_OPCODE_Y0 = 0, - AND_RRR_5_OPCODE_Y1 = 0, - BEQZT_BRANCH_OPCODE_X1 = 16, - BEQZ_BRANCH_OPCODE_X1 = 17, - BFEXTS_BF_OPCODE_X0 = 4, - BFEXTU_BF_OPCODE_X0 = 5, - BFINS_BF_OPCODE_X0 = 6, - BF_OPCODE_X0 = 3, - BGEZT_BRANCH_OPCODE_X1 = 18, - BGEZ_BRANCH_OPCODE_X1 = 19, - BGTZT_BRANCH_OPCODE_X1 = 20, - BGTZ_BRANCH_OPCODE_X1 = 21, - BLBCT_BRANCH_OPCODE_X1 = 22, - BLBC_BRANCH_OPCODE_X1 = 23, - BLBST_BRANCH_OPCODE_X1 = 24, - BLBS_BRANCH_OPCODE_X1 = 25, - BLEZT_BRANCH_OPCODE_X1 = 26, - BLEZ_BRANCH_OPCODE_X1 = 27, - BLTZT_BRANCH_OPCODE_X1 = 28, - BLTZ_BRANCH_OPCODE_X1 = 29, - BNEZT_BRANCH_OPCODE_X1 = 30, - BNEZ_BRANCH_OPCODE_X1 = 31, - BRANCH_OPCODE_X1 = 2, - CMOVEQZ_RRR_0_OPCODE_X0 = 5, - CMOVEQZ_RRR_4_OPCODE_Y0 = 0, - CMOVNEZ_RRR_0_OPCODE_X0 = 6, - CMOVNEZ_RRR_4_OPCODE_Y0 = 1, - CMPEQI_IMM8_OPCODE_X0 = 4, - CMPEQI_IMM8_OPCODE_X1 = 4, - CMPEQI_OPCODE_Y0 = 3, - CMPEQI_OPCODE_Y1 = 4, - CMPEQ_RRR_0_OPCODE_X0 = 7, - CMPEQ_RRR_0_OPCODE_X1 = 5, - CMPEQ_RRR_3_OPCODE_Y0 = 0, - CMPEQ_RRR_3_OPCODE_Y1 = 2, - CMPEXCH4_RRR_0_OPCODE_X1 = 6, - CMPEXCH_RRR_0_OPCODE_X1 = 7, - CMPLES_RRR_0_OPCODE_X0 = 8, - CMPLES_RRR_0_OPCODE_X1 = 8, - CMPLES_RRR_2_OPCODE_Y0 = 0, - CMPLES_RRR_2_OPCODE_Y1 = 0, - CMPLEU_RRR_0_OPCODE_X0 = 9, - CMPLEU_RRR_0_OPCODE_X1 = 9, - CMPLEU_RRR_2_OPCODE_Y0 = 1, - CMPLEU_RRR_2_OPCODE_Y1 = 1, - CMPLTSI_IMM8_OPCODE_X0 = 5, - CMPLTSI_IMM8_OPCODE_X1 = 5, - CMPLTSI_OPCODE_Y0 = 4, - CMPLTSI_OPCODE_Y1 = 5, - CMPLTS_RRR_0_OPCODE_X0 = 10, - CMPLTS_RRR_0_OPCODE_X1 = 10, - CMPLTS_RRR_2_OPCODE_Y0 = 2, - CMPLTS_RRR_2_OPCODE_Y1 = 2, - CMPLTUI_IMM8_OPCODE_X0 = 6, - CMPLTUI_IMM8_OPCODE_X1 = 6, - CMPLTU_RRR_0_OPCODE_X0 = 11, - CMPLTU_RRR_0_OPCODE_X1 = 11, - CMPLTU_RRR_2_OPCODE_Y0 = 3, - CMPLTU_RRR_2_OPCODE_Y1 = 3, - CMPNE_RRR_0_OPCODE_X0 = 12, - CMPNE_RRR_0_OPCODE_X1 = 12, - CMPNE_RRR_3_OPCODE_Y0 = 1, - CMPNE_RRR_3_OPCODE_Y1 = 3, - CMULAF_RRR_0_OPCODE_X0 = 13, - CMULA_RRR_0_OPCODE_X0 = 14, - CMULFR_RRR_0_OPCODE_X0 = 15, - CMULF_RRR_0_OPCODE_X0 = 16, - CMULHR_RRR_0_OPCODE_X0 = 17, - CMULH_RRR_0_OPCODE_X0 = 18, - CMUL_RRR_0_OPCODE_X0 = 19, - CNTLZ_UNARY_OPCODE_X0 = 1, - CNTLZ_UNARY_OPCODE_Y0 = 1, - CNTTZ_UNARY_OPCODE_X0 = 2, - CNTTZ_UNARY_OPCODE_Y0 = 2, - CRC32_32_RRR_0_OPCODE_X0 = 20, - CRC32_8_RRR_0_OPCODE_X0 = 21, - DBLALIGN2_RRR_0_OPCODE_X0 = 22, - DBLALIGN2_RRR_0_OPCODE_X1 = 13, - DBLALIGN4_RRR_0_OPCODE_X0 = 23, - DBLALIGN4_RRR_0_OPCODE_X1 = 14, - DBLALIGN6_RRR_0_OPCODE_X0 = 24, - DBLALIGN6_RRR_0_OPCODE_X1 = 15, - DBLALIGN_RRR_0_OPCODE_X0 = 25, - DRAIN_UNARY_OPCODE_X1 = 1, - DTLBPR_UNARY_OPCODE_X1 = 2, - EXCH4_RRR_0_OPCODE_X1 = 16, - EXCH_RRR_0_OPCODE_X1 = 17, - FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26, - FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27, - FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28, - FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29, - FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30, - FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31, - FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32, - FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33, - FETCHADD4_RRR_0_OPCODE_X1 = 18, - FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19, - FETCHADDGEZ_RRR_0_OPCODE_X1 = 20, - FETCHADD_RRR_0_OPCODE_X1 = 21, - FETCHAND4_RRR_0_OPCODE_X1 = 22, - FETCHAND_RRR_0_OPCODE_X1 = 23, - FETCHOR4_RRR_0_OPCODE_X1 = 24, - FETCHOR_RRR_0_OPCODE_X1 = 25, - FINV_UNARY_OPCODE_X1 = 3, - FLUSHWB_UNARY_OPCODE_X1 = 4, - FLUSH_UNARY_OPCODE_X1 = 5, - FNOP_UNARY_OPCODE_X0 = 3, - FNOP_UNARY_OPCODE_X1 = 6, - FNOP_UNARY_OPCODE_Y0 = 3, - FNOP_UNARY_OPCODE_Y1 = 8, - FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34, - FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35, - FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36, - FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37, - FSINGLE_PACK1_UNARY_OPCODE_X0 = 4, - FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4, - FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38, - FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39, - ICOH_UNARY_OPCODE_X1 = 7, - ILL_UNARY_OPCODE_X1 = 8, - ILL_UNARY_OPCODE_Y1 = 9, - IMM8_OPCODE_X0 = 4, - IMM8_OPCODE_X1 = 3, - INV_UNARY_OPCODE_X1 = 9, - IRET_UNARY_OPCODE_X1 = 10, - JALRP_UNARY_OPCODE_X1 = 11, - JALRP_UNARY_OPCODE_Y1 = 10, - JALR_UNARY_OPCODE_X1 = 12, - JALR_UNARY_OPCODE_Y1 = 11, - JAL_JUMP_OPCODE_X1 = 0, - JRP_UNARY_OPCODE_X1 = 13, - JRP_UNARY_OPCODE_Y1 = 12, - JR_UNARY_OPCODE_X1 = 14, - JR_UNARY_OPCODE_Y1 = 13, - JUMP_OPCODE_X1 = 4, - J_JUMP_OPCODE_X1 = 1, - LD1S_ADD_IMM8_OPCODE_X1 = 7, - LD1S_OPCODE_Y2 = 0, - LD1S_UNARY_OPCODE_X1 = 15, - LD1U_ADD_IMM8_OPCODE_X1 = 8, - LD1U_OPCODE_Y2 = 1, - LD1U_UNARY_OPCODE_X1 = 16, - LD2S_ADD_IMM8_OPCODE_X1 = 9, - LD2S_OPCODE_Y2 = 2, - LD2S_UNARY_OPCODE_X1 = 17, - LD2U_ADD_IMM8_OPCODE_X1 = 10, - LD2U_OPCODE_Y2 = 3, - LD2U_UNARY_OPCODE_X1 = 18, - LD4S_ADD_IMM8_OPCODE_X1 = 11, - LD4S_OPCODE_Y2 = 1, - LD4S_UNARY_OPCODE_X1 = 19, - LD4U_ADD_IMM8_OPCODE_X1 = 12, - LD4U_OPCODE_Y2 = 2, - LD4U_UNARY_OPCODE_X1 = 20, - LDNA_UNARY_OPCODE_X1 = 21, - LDNT1S_ADD_IMM8_OPCODE_X1 = 13, - LDNT1S_UNARY_OPCODE_X1 = 22, - LDNT1U_ADD_IMM8_OPCODE_X1 = 14, - LDNT1U_UNARY_OPCODE_X1 = 23, - LDNT2S_ADD_IMM8_OPCODE_X1 = 15, - LDNT2S_UNARY_OPCODE_X1 = 24, - LDNT2U_ADD_IMM8_OPCODE_X1 = 16, - LDNT2U_UNARY_OPCODE_X1 = 25, - LDNT4S_ADD_IMM8_OPCODE_X1 = 17, - LDNT4S_UNARY_OPCODE_X1 = 26, - LDNT4U_ADD_IMM8_OPCODE_X1 = 18, - LDNT4U_UNARY_OPCODE_X1 = 27, - LDNT_ADD_IMM8_OPCODE_X1 = 19, - LDNT_UNARY_OPCODE_X1 = 28, - LD_ADD_IMM8_OPCODE_X1 = 20, - LD_OPCODE_Y2 = 3, - LD_UNARY_OPCODE_X1 = 29, - LNK_UNARY_OPCODE_X1 = 30, - LNK_UNARY_OPCODE_Y1 = 14, - LWNA_ADD_IMM8_OPCODE_X1 = 21, - MFSPR_IMM8_OPCODE_X1 = 22, - MF_UNARY_OPCODE_X1 = 31, - MM_BF_OPCODE_X0 = 7, - MNZ_RRR_0_OPCODE_X0 = 40, - MNZ_RRR_0_OPCODE_X1 = 26, - MNZ_RRR_4_OPCODE_Y0 = 2, - MNZ_RRR_4_OPCODE_Y1 = 2, - MODE_OPCODE_YA2 = 1, - MODE_OPCODE_YB2 = 2, - MODE_OPCODE_YC2 = 3, - MTSPR_IMM8_OPCODE_X1 = 23, - MULAX_RRR_0_OPCODE_X0 = 41, - MULAX_RRR_3_OPCODE_Y0 = 2, - MULA_HS_HS_RRR_0_OPCODE_X0 = 42, - MULA_HS_HS_RRR_9_OPCODE_Y0 = 0, - MULA_HS_HU_RRR_0_OPCODE_X0 = 43, - MULA_HS_LS_RRR_0_OPCODE_X0 = 44, - MULA_HS_LU_RRR_0_OPCODE_X0 = 45, - MULA_HU_HU_RRR_0_OPCODE_X0 = 46, - MULA_HU_HU_RRR_9_OPCODE_Y0 = 1, - MULA_HU_LS_RRR_0_OPCODE_X0 = 47, - MULA_HU_LU_RRR_0_OPCODE_X0 = 48, - MULA_LS_LS_RRR_0_OPCODE_X0 = 49, - MULA_LS_LS_RRR_9_OPCODE_Y0 = 2, - MULA_LS_LU_RRR_0_OPCODE_X0 = 50, - MULA_LU_LU_RRR_0_OPCODE_X0 = 51, - MULA_LU_LU_RRR_9_OPCODE_Y0 = 3, - MULX_RRR_0_OPCODE_X0 = 52, - MULX_RRR_3_OPCODE_Y0 = 3, - MUL_HS_HS_RRR_0_OPCODE_X0 = 53, - MUL_HS_HS_RRR_8_OPCODE_Y0 = 0, - MUL_HS_HU_RRR_0_OPCODE_X0 = 54, - MUL_HS_LS_RRR_0_OPCODE_X0 = 55, - MUL_HS_LU_RRR_0_OPCODE_X0 = 56, - MUL_HU_HU_RRR_0_OPCODE_X0 = 57, - MUL_HU_HU_RRR_8_OPCODE_Y0 = 1, - MUL_HU_LS_RRR_0_OPCODE_X0 = 58, - MUL_HU_LU_RRR_0_OPCODE_X0 = 59, - MUL_LS_LS_RRR_0_OPCODE_X0 = 60, - MUL_LS_LS_RRR_8_OPCODE_Y0 = 2, - MUL_LS_LU_RRR_0_OPCODE_X0 = 61, - MUL_LU_LU_RRR_0_OPCODE_X0 = 62, - MUL_LU_LU_RRR_8_OPCODE_Y0 = 3, - MZ_RRR_0_OPCODE_X0 = 63, - MZ_RRR_0_OPCODE_X1 = 27, - MZ_RRR_4_OPCODE_Y0 = 3, - MZ_RRR_4_OPCODE_Y1 = 3, - NAP_UNARY_OPCODE_X1 = 32, - NOP_UNARY_OPCODE_X0 = 5, - NOP_UNARY_OPCODE_X1 = 33, - NOP_UNARY_OPCODE_Y0 = 5, - NOP_UNARY_OPCODE_Y1 = 15, - NOR_RRR_0_OPCODE_X0 = 64, - NOR_RRR_0_OPCODE_X1 = 28, - NOR_RRR_5_OPCODE_Y0 = 1, - NOR_RRR_5_OPCODE_Y1 = 1, - ORI_IMM8_OPCODE_X0 = 7, - ORI_IMM8_OPCODE_X1 = 24, - OR_RRR_0_OPCODE_X0 = 65, - OR_RRR_0_OPCODE_X1 = 29, - OR_RRR_5_OPCODE_Y0 = 2, - OR_RRR_5_OPCODE_Y1 = 2, - PCNT_UNARY_OPCODE_X0 = 6, - PCNT_UNARY_OPCODE_Y0 = 6, - REVBITS_UNARY_OPCODE_X0 = 7, - REVBITS_UNARY_OPCODE_Y0 = 7, - REVBYTES_UNARY_OPCODE_X0 = 8, - REVBYTES_UNARY_OPCODE_Y0 = 8, - ROTLI_SHIFT_OPCODE_X0 = 1, - ROTLI_SHIFT_OPCODE_X1 = 1, - ROTLI_SHIFT_OPCODE_Y0 = 0, - ROTLI_SHIFT_OPCODE_Y1 = 0, - ROTL_RRR_0_OPCODE_X0 = 66, - ROTL_RRR_0_OPCODE_X1 = 30, - ROTL_RRR_6_OPCODE_Y0 = 0, - ROTL_RRR_6_OPCODE_Y1 = 0, - RRR_0_OPCODE_X0 = 5, - RRR_0_OPCODE_X1 = 5, - RRR_0_OPCODE_Y0 = 5, - RRR_0_OPCODE_Y1 = 6, - RRR_1_OPCODE_Y0 = 6, - RRR_1_OPCODE_Y1 = 7, - RRR_2_OPCODE_Y0 = 7, - RRR_2_OPCODE_Y1 = 8, - RRR_3_OPCODE_Y0 = 8, - RRR_3_OPCODE_Y1 = 9, - RRR_4_OPCODE_Y0 = 9, - RRR_4_OPCODE_Y1 = 10, - RRR_5_OPCODE_Y0 = 10, - RRR_5_OPCODE_Y1 = 11, - RRR_6_OPCODE_Y0 = 11, - RRR_6_OPCODE_Y1 = 12, - RRR_7_OPCODE_Y0 = 12, - RRR_7_OPCODE_Y1 = 13, - RRR_8_OPCODE_Y0 = 13, - RRR_9_OPCODE_Y0 = 14, - SHIFT_OPCODE_X0 = 6, - SHIFT_OPCODE_X1 = 6, - SHIFT_OPCODE_Y0 = 15, - SHIFT_OPCODE_Y1 = 14, - SHL16INSLI_OPCODE_X0 = 7, - SHL16INSLI_OPCODE_X1 = 7, - SHL1ADDX_RRR_0_OPCODE_X0 = 67, - SHL1ADDX_RRR_0_OPCODE_X1 = 31, - SHL1ADDX_RRR_7_OPCODE_Y0 = 1, - SHL1ADDX_RRR_7_OPCODE_Y1 = 1, - SHL1ADD_RRR_0_OPCODE_X0 = 68, - SHL1ADD_RRR_0_OPCODE_X1 = 32, - SHL1ADD_RRR_1_OPCODE_Y0 = 0, - SHL1ADD_RRR_1_OPCODE_Y1 = 0, - SHL2ADDX_RRR_0_OPCODE_X0 = 69, - SHL2ADDX_RRR_0_OPCODE_X1 = 33, - SHL2ADDX_RRR_7_OPCODE_Y0 = 2, - SHL2ADDX_RRR_7_OPCODE_Y1 = 2, - SHL2ADD_RRR_0_OPCODE_X0 = 70, - SHL2ADD_RRR_0_OPCODE_X1 = 34, - SHL2ADD_RRR_1_OPCODE_Y0 = 1, - SHL2ADD_RRR_1_OPCODE_Y1 = 1, - SHL3ADDX_RRR_0_OPCODE_X0 = 71, - SHL3ADDX_RRR_0_OPCODE_X1 = 35, - SHL3ADDX_RRR_7_OPCODE_Y0 = 3, - SHL3ADDX_RRR_7_OPCODE_Y1 = 3, - SHL3ADD_RRR_0_OPCODE_X0 = 72, - SHL3ADD_RRR_0_OPCODE_X1 = 36, - SHL3ADD_RRR_1_OPCODE_Y0 = 2, - SHL3ADD_RRR_1_OPCODE_Y1 = 2, - SHLI_SHIFT_OPCODE_X0 = 2, - SHLI_SHIFT_OPCODE_X1 = 2, - SHLI_SHIFT_OPCODE_Y0 = 1, - SHLI_SHIFT_OPCODE_Y1 = 1, - SHLXI_SHIFT_OPCODE_X0 = 3, - SHLXI_SHIFT_OPCODE_X1 = 3, - SHLX_RRR_0_OPCODE_X0 = 73, - SHLX_RRR_0_OPCODE_X1 = 37, - SHL_RRR_0_OPCODE_X0 = 74, - SHL_RRR_0_OPCODE_X1 = 38, - SHL_RRR_6_OPCODE_Y0 = 1, - SHL_RRR_6_OPCODE_Y1 = 1, - SHRSI_SHIFT_OPCODE_X0 = 4, - SHRSI_SHIFT_OPCODE_X1 = 4, - SHRSI_SHIFT_OPCODE_Y0 = 2, - SHRSI_SHIFT_OPCODE_Y1 = 2, - SHRS_RRR_0_OPCODE_X0 = 75, - SHRS_RRR_0_OPCODE_X1 = 39, - SHRS_RRR_6_OPCODE_Y0 = 2, - SHRS_RRR_6_OPCODE_Y1 = 2, - SHRUI_SHIFT_OPCODE_X0 = 5, - SHRUI_SHIFT_OPCODE_X1 = 5, - SHRUI_SHIFT_OPCODE_Y0 = 3, - SHRUI_SHIFT_OPCODE_Y1 = 3, - SHRUXI_SHIFT_OPCODE_X0 = 6, - SHRUXI_SHIFT_OPCODE_X1 = 6, - SHRUX_RRR_0_OPCODE_X0 = 76, - SHRUX_RRR_0_OPCODE_X1 = 40, - SHRU_RRR_0_OPCODE_X0 = 77, - SHRU_RRR_0_OPCODE_X1 = 41, - SHRU_RRR_6_OPCODE_Y0 = 3, - SHRU_RRR_6_OPCODE_Y1 = 3, - SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78, - ST1_ADD_IMM8_OPCODE_X1 = 25, - ST1_OPCODE_Y2 = 0, - ST1_RRR_0_OPCODE_X1 = 42, - ST2_ADD_IMM8_OPCODE_X1 = 26, - ST2_OPCODE_Y2 = 1, - ST2_RRR_0_OPCODE_X1 = 43, - ST4_ADD_IMM8_OPCODE_X1 = 27, - ST4_OPCODE_Y2 = 2, - ST4_RRR_0_OPCODE_X1 = 44, - STNT1_ADD_IMM8_OPCODE_X1 = 28, - STNT1_RRR_0_OPCODE_X1 = 45, - STNT2_ADD_IMM8_OPCODE_X1 = 29, - STNT2_RRR_0_OPCODE_X1 = 46, - STNT4_ADD_IMM8_OPCODE_X1 = 30, - STNT4_RRR_0_OPCODE_X1 = 47, - STNT_ADD_IMM8_OPCODE_X1 = 31, - STNT_RRR_0_OPCODE_X1 = 48, - ST_ADD_IMM8_OPCODE_X1 = 32, - ST_OPCODE_Y2 = 3, - ST_RRR_0_OPCODE_X1 = 49, - SUBXSC_RRR_0_OPCODE_X0 = 79, - SUBXSC_RRR_0_OPCODE_X1 = 50, - SUBX_RRR_0_OPCODE_X0 = 80, - SUBX_RRR_0_OPCODE_X1 = 51, - SUBX_RRR_0_OPCODE_Y0 = 2, - SUBX_RRR_0_OPCODE_Y1 = 2, - SUB_RRR_0_OPCODE_X0 = 81, - SUB_RRR_0_OPCODE_X1 = 52, - SUB_RRR_0_OPCODE_Y0 = 3, - SUB_RRR_0_OPCODE_Y1 = 3, - SWINT0_UNARY_OPCODE_X1 = 34, - SWINT1_UNARY_OPCODE_X1 = 35, - SWINT2_UNARY_OPCODE_X1 = 36, - SWINT3_UNARY_OPCODE_X1 = 37, - TBLIDXB0_UNARY_OPCODE_X0 = 9, - TBLIDXB0_UNARY_OPCODE_Y0 = 9, - TBLIDXB1_UNARY_OPCODE_X0 = 10, - TBLIDXB1_UNARY_OPCODE_Y0 = 10, - TBLIDXB2_UNARY_OPCODE_X0 = 11, - TBLIDXB2_UNARY_OPCODE_Y0 = 11, - TBLIDXB3_UNARY_OPCODE_X0 = 12, - TBLIDXB3_UNARY_OPCODE_Y0 = 12, - UNARY_RRR_0_OPCODE_X0 = 82, - UNARY_RRR_0_OPCODE_X1 = 53, - UNARY_RRR_1_OPCODE_Y0 = 3, - UNARY_RRR_1_OPCODE_Y1 = 3, - V1ADDI_IMM8_OPCODE_X0 = 8, - V1ADDI_IMM8_OPCODE_X1 = 33, - V1ADDUC_RRR_0_OPCODE_X0 = 83, - V1ADDUC_RRR_0_OPCODE_X1 = 54, - V1ADD_RRR_0_OPCODE_X0 = 84, - V1ADD_RRR_0_OPCODE_X1 = 55, - V1ADIFFU_RRR_0_OPCODE_X0 = 85, - V1AVGU_RRR_0_OPCODE_X0 = 86, - V1CMPEQI_IMM8_OPCODE_X0 = 9, - V1CMPEQI_IMM8_OPCODE_X1 = 34, - V1CMPEQ_RRR_0_OPCODE_X0 = 87, - V1CMPEQ_RRR_0_OPCODE_X1 = 56, - V1CMPLES_RRR_0_OPCODE_X0 = 88, - V1CMPLES_RRR_0_OPCODE_X1 = 57, - V1CMPLEU_RRR_0_OPCODE_X0 = 89, - V1CMPLEU_RRR_0_OPCODE_X1 = 58, - V1CMPLTSI_IMM8_OPCODE_X0 = 10, - V1CMPLTSI_IMM8_OPCODE_X1 = 35, - V1CMPLTS_RRR_0_OPCODE_X0 = 90, - V1CMPLTS_RRR_0_OPCODE_X1 = 59, - V1CMPLTUI_IMM8_OPCODE_X0 = 11, - V1CMPLTUI_IMM8_OPCODE_X1 = 36, - V1CMPLTU_RRR_0_OPCODE_X0 = 91, - V1CMPLTU_RRR_0_OPCODE_X1 = 60, - V1CMPNE_RRR_0_OPCODE_X0 = 92, - V1CMPNE_RRR_0_OPCODE_X1 = 61, - V1DDOTPUA_RRR_0_OPCODE_X0 = 161, - V1DDOTPUSA_RRR_0_OPCODE_X0 = 93, - V1DDOTPUS_RRR_0_OPCODE_X0 = 94, - V1DDOTPU_RRR_0_OPCODE_X0 = 162, - V1DOTPA_RRR_0_OPCODE_X0 = 95, - V1DOTPUA_RRR_0_OPCODE_X0 = 163, - V1DOTPUSA_RRR_0_OPCODE_X0 = 96, - V1DOTPUS_RRR_0_OPCODE_X0 = 97, - V1DOTPU_RRR_0_OPCODE_X0 = 164, - V1DOTP_RRR_0_OPCODE_X0 = 98, - V1INT_H_RRR_0_OPCODE_X0 = 99, - V1INT_H_RRR_0_OPCODE_X1 = 62, - V1INT_L_RRR_0_OPCODE_X0 = 100, - V1INT_L_RRR_0_OPCODE_X1 = 63, - V1MAXUI_IMM8_OPCODE_X0 = 12, - V1MAXUI_IMM8_OPCODE_X1 = 37, - V1MAXU_RRR_0_OPCODE_X0 = 101, - V1MAXU_RRR_0_OPCODE_X1 = 64, - V1MINUI_IMM8_OPCODE_X0 = 13, - V1MINUI_IMM8_OPCODE_X1 = 38, - V1MINU_RRR_0_OPCODE_X0 = 102, - V1MINU_RRR_0_OPCODE_X1 = 65, - V1MNZ_RRR_0_OPCODE_X0 = 103, - V1MNZ_RRR_0_OPCODE_X1 = 66, - V1MULTU_RRR_0_OPCODE_X0 = 104, - V1MULUS_RRR_0_OPCODE_X0 = 105, - V1MULU_RRR_0_OPCODE_X0 = 106, - V1MZ_RRR_0_OPCODE_X0 = 107, - V1MZ_RRR_0_OPCODE_X1 = 67, - V1SADAU_RRR_0_OPCODE_X0 = 108, - V1SADU_RRR_0_OPCODE_X0 = 109, - V1SHLI_SHIFT_OPCODE_X0 = 7, - V1SHLI_SHIFT_OPCODE_X1 = 7, - V1SHL_RRR_0_OPCODE_X0 = 110, - V1SHL_RRR_0_OPCODE_X1 = 68, - V1SHRSI_SHIFT_OPCODE_X0 = 8, - V1SHRSI_SHIFT_OPCODE_X1 = 8, - V1SHRS_RRR_0_OPCODE_X0 = 111, - V1SHRS_RRR_0_OPCODE_X1 = 69, - V1SHRUI_SHIFT_OPCODE_X0 = 9, - V1SHRUI_SHIFT_OPCODE_X1 = 9, - V1SHRU_RRR_0_OPCODE_X0 = 112, - V1SHRU_RRR_0_OPCODE_X1 = 70, - V1SUBUC_RRR_0_OPCODE_X0 = 113, - V1SUBUC_RRR_0_OPCODE_X1 = 71, - V1SUB_RRR_0_OPCODE_X0 = 114, - V1SUB_RRR_0_OPCODE_X1 = 72, - V2ADDI_IMM8_OPCODE_X0 = 14, - V2ADDI_IMM8_OPCODE_X1 = 39, - V2ADDSC_RRR_0_OPCODE_X0 = 115, - V2ADDSC_RRR_0_OPCODE_X1 = 73, - V2ADD_RRR_0_OPCODE_X0 = 116, - V2ADD_RRR_0_OPCODE_X1 = 74, - V2ADIFFS_RRR_0_OPCODE_X0 = 117, - V2AVGS_RRR_0_OPCODE_X0 = 118, - V2CMPEQI_IMM8_OPCODE_X0 = 15, - V2CMPEQI_IMM8_OPCODE_X1 = 40, - V2CMPEQ_RRR_0_OPCODE_X0 = 119, - V2CMPEQ_RRR_0_OPCODE_X1 = 75, - V2CMPLES_RRR_0_OPCODE_X0 = 120, - V2CMPLES_RRR_0_OPCODE_X1 = 76, - V2CMPLEU_RRR_0_OPCODE_X0 = 121, - V2CMPLEU_RRR_0_OPCODE_X1 = 77, - V2CMPLTSI_IMM8_OPCODE_X0 = 16, - V2CMPLTSI_IMM8_OPCODE_X1 = 41, - V2CMPLTS_RRR_0_OPCODE_X0 = 122, - V2CMPLTS_RRR_0_OPCODE_X1 = 78, - V2CMPLTUI_IMM8_OPCODE_X0 = 17, - V2CMPLTUI_IMM8_OPCODE_X1 = 42, - V2CMPLTU_RRR_0_OPCODE_X0 = 123, - V2CMPLTU_RRR_0_OPCODE_X1 = 79, - V2CMPNE_RRR_0_OPCODE_X0 = 124, - V2CMPNE_RRR_0_OPCODE_X1 = 80, - V2DOTPA_RRR_0_OPCODE_X0 = 125, - V2DOTP_RRR_0_OPCODE_X0 = 126, - V2INT_H_RRR_0_OPCODE_X0 = 127, - V2INT_H_RRR_0_OPCODE_X1 = 81, - V2INT_L_RRR_0_OPCODE_X0 = 128, - V2INT_L_RRR_0_OPCODE_X1 = 82, - V2MAXSI_IMM8_OPCODE_X0 = 18, - V2MAXSI_IMM8_OPCODE_X1 = 43, - V2MAXS_RRR_0_OPCODE_X0 = 129, - V2MAXS_RRR_0_OPCODE_X1 = 83, - V2MINSI_IMM8_OPCODE_X0 = 19, - V2MINSI_IMM8_OPCODE_X1 = 44, - V2MINS_RRR_0_OPCODE_X0 = 130, - V2MINS_RRR_0_OPCODE_X1 = 84, - V2MNZ_RRR_0_OPCODE_X0 = 131, - V2MNZ_RRR_0_OPCODE_X1 = 85, - V2MULFSC_RRR_0_OPCODE_X0 = 132, - V2MULS_RRR_0_OPCODE_X0 = 133, - V2MULTS_RRR_0_OPCODE_X0 = 134, - V2MZ_RRR_0_OPCODE_X0 = 135, - V2MZ_RRR_0_OPCODE_X1 = 86, - V2PACKH_RRR_0_OPCODE_X0 = 136, - V2PACKH_RRR_0_OPCODE_X1 = 87, - V2PACKL_RRR_0_OPCODE_X0 = 137, - V2PACKL_RRR_0_OPCODE_X1 = 88, - V2PACKUC_RRR_0_OPCODE_X0 = 138, - V2PACKUC_RRR_0_OPCODE_X1 = 89, - V2SADAS_RRR_0_OPCODE_X0 = 139, - V2SADAU_RRR_0_OPCODE_X0 = 140, - V2SADS_RRR_0_OPCODE_X0 = 141, - V2SADU_RRR_0_OPCODE_X0 = 142, - V2SHLI_SHIFT_OPCODE_X0 = 10, - V2SHLI_SHIFT_OPCODE_X1 = 10, - V2SHLSC_RRR_0_OPCODE_X0 = 143, - V2SHLSC_RRR_0_OPCODE_X1 = 90, - V2SHL_RRR_0_OPCODE_X0 = 144, - V2SHL_RRR_0_OPCODE_X1 = 91, - V2SHRSI_SHIFT_OPCODE_X0 = 11, - V2SHRSI_SHIFT_OPCODE_X1 = 11, - V2SHRS_RRR_0_OPCODE_X0 = 145, - V2SHRS_RRR_0_OPCODE_X1 = 92, - V2SHRUI_SHIFT_OPCODE_X0 = 12, - V2SHRUI_SHIFT_OPCODE_X1 = 12, - V2SHRU_RRR_0_OPCODE_X0 = 146, - V2SHRU_RRR_0_OPCODE_X1 = 93, - V2SUBSC_RRR_0_OPCODE_X0 = 147, - V2SUBSC_RRR_0_OPCODE_X1 = 94, - V2SUB_RRR_0_OPCODE_X0 = 148, - V2SUB_RRR_0_OPCODE_X1 = 95, - V4ADDSC_RRR_0_OPCODE_X0 = 149, - V4ADDSC_RRR_0_OPCODE_X1 = 96, - V4ADD_RRR_0_OPCODE_X0 = 150, - V4ADD_RRR_0_OPCODE_X1 = 97, - V4INT_H_RRR_0_OPCODE_X0 = 151, - V4INT_H_RRR_0_OPCODE_X1 = 98, - V4INT_L_RRR_0_OPCODE_X0 = 152, - V4INT_L_RRR_0_OPCODE_X1 = 99, - V4PACKSC_RRR_0_OPCODE_X0 = 153, - V4PACKSC_RRR_0_OPCODE_X1 = 100, - V4SHLSC_RRR_0_OPCODE_X0 = 154, - V4SHLSC_RRR_0_OPCODE_X1 = 101, - V4SHL_RRR_0_OPCODE_X0 = 155, - V4SHL_RRR_0_OPCODE_X1 = 102, - V4SHRS_RRR_0_OPCODE_X0 = 156, - V4SHRS_RRR_0_OPCODE_X1 = 103, - V4SHRU_RRR_0_OPCODE_X0 = 157, - V4SHRU_RRR_0_OPCODE_X1 = 104, - V4SUBSC_RRR_0_OPCODE_X0 = 158, - V4SUBSC_RRR_0_OPCODE_X1 = 105, - V4SUB_RRR_0_OPCODE_X0 = 159, - V4SUB_RRR_0_OPCODE_X1 = 106, - WH64_UNARY_OPCODE_X1 = 38, - XORI_IMM8_OPCODE_X0 = 20, - XORI_IMM8_OPCODE_X1 = 45, - XOR_RRR_0_OPCODE_X0 = 160, - XOR_RRR_0_OPCODE_X1 = 107, - XOR_RRR_5_OPCODE_Y0 = 3, - XOR_RRR_5_OPCODE_Y1 = 3 -}; - -static __inline unsigned int -get_BFEnd_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_BFOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 24)) & 0xf); -} - -static __inline unsigned int -get_BFStart_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3f); -} - -static __inline unsigned int -get_BrOff_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 37)) & 0x0001ffc0); -} - -static __inline unsigned int -get_BrType_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 54)) & 0x1f); -} - -static __inline unsigned int -get_Dest_Imm8_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 43)) & 0x000000c0); -} - -static __inline unsigned int -get_Dest_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 0)) & 0x3f); -} - -static __inline unsigned int -get_Dest_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x3f); -} - -static __inline unsigned int -get_Dest_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 0)) & 0x3f); -} - -static __inline unsigned int -get_Dest_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x3f); -} - -static __inline unsigned int -get_Imm16_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xffff); -} - -static __inline unsigned int -get_Imm16_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xffff); -} - -static __inline unsigned int -get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 20)) & 0xff); -} - -static __inline unsigned int -get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 51)) & 0xff); -} - -static __inline unsigned int -get_Imm8_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xff); -} - -static __inline unsigned int -get_Imm8_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xff); -} - -static __inline unsigned int -get_Imm8_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xff); -} - -static __inline unsigned int -get_Imm8_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xff); -} - -static __inline unsigned int -get_JumpOff_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x7ffffff); -} - -static __inline unsigned int -get_JumpOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 58)) & 0x1); -} - -static __inline unsigned int -get_MF_Imm14_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3fff); -} - -static __inline unsigned int -get_MT_Imm14_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 37)) & 0x00003fc0); -} - -static __inline unsigned int -get_Mode(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 62)) & 0x3); -} - -static __inline unsigned int -get_Opcode_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 28)) & 0x7); -} - -static __inline unsigned int -get_Opcode_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 59)) & 0x7); -} - -static __inline unsigned int -get_Opcode_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 27)) & 0xf); -} - -static __inline unsigned int -get_Opcode_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 58)) & 0xf); -} - -static __inline unsigned int -get_Opcode_Y2(tilegx_bundle_bits n) -{ - return (((n >> 26)) & 0x00000001) | - (((unsigned int)(n >> 56)) & 0x00000002); -} - -static __inline unsigned int -get_RRROpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3ff); -} - -static __inline unsigned int -get_RRROpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3ff); -} - -static __inline unsigned int -get_RRROpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3); -} - -static __inline unsigned int -get_RRROpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3); -} - -static __inline unsigned int -get_ShAmt_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3ff); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3ff); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3); -} - -static __inline unsigned int -get_SrcA_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 6)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 6)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y2(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 20)) & 0x3f); -} - -static __inline unsigned int -get_SrcBDest_Y2(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 51)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline int -sign_extend(int n, int num_bits) -{ - int shift = (int)(sizeof(int) * 8 - num_bits); - return (n << shift) >> shift; -} - -static __inline tilegx_bundle_bits -create_BFEnd_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_BFOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xf) << 24); -} - -static __inline tilegx_bundle_bits -create_BFStart_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 18); -} - -static __inline tilegx_bundle_bits -create_BrOff_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37); -} - -static __inline tilegx_bundle_bits -create_BrType_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x1f)) << 54); -} - -static __inline tilegx_bundle_bits -create_Dest_Imm8_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x000000c0)) << 43); -} - -static __inline tilegx_bundle_bits -create_Dest_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 0); -} - -static __inline tilegx_bundle_bits -create_Dest_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 31); -} - -static __inline tilegx_bundle_bits -create_Dest_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 0); -} - -static __inline tilegx_bundle_bits -create_Dest_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 31); -} - -static __inline tilegx_bundle_bits -create_Imm16_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xffff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm16_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xffff)) << 43); -} - -static __inline tilegx_bundle_bits -create_Imm8OpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 20); -} - -static __inline tilegx_bundle_bits -create_Imm8OpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 51); -} - -static __inline tilegx_bundle_bits -create_Imm8_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm8_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 43); -} - -static __inline tilegx_bundle_bits -create_Imm8_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm8_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 43); -} - -static __inline tilegx_bundle_bits -create_JumpOff_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31); -} - -static __inline tilegx_bundle_bits -create_JumpOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x1)) << 58); -} - -static __inline tilegx_bundle_bits -create_MF_Imm14_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3fff)) << 37); -} - -static __inline tilegx_bundle_bits -create_MT_Imm14_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37); -} - -static __inline tilegx_bundle_bits -create_Mode(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 62); -} - -static __inline tilegx_bundle_bits -create_Opcode_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x7) << 28); -} - -static __inline tilegx_bundle_bits -create_Opcode_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x7)) << 59); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xf) << 27); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xf)) << 58); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x00000001) << 26) | - (((tilegx_bundle_bits)(n & 0x00000002)) << 56); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3ff) << 18); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3) << 18); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 49); -} - -static __inline tilegx_bundle_bits -create_ShAmt_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_ShAmt_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_ShAmt_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_ShAmt_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3ff) << 18); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3) << 18); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 49); -} - -static __inline tilegx_bundle_bits -create_SrcA_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 6); -} - -static __inline tilegx_bundle_bits -create_SrcA_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 37); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 6); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 37); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 20); -} - -static __inline tilegx_bundle_bits -create_SrcBDest_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 51); -} - -static __inline tilegx_bundle_bits -create_SrcB_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_SrcB_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_SrcB_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_SrcB_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -const struct tilegx_opcode tilegx_opcodes[336] = -{ - { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffffffff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a44ae00000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1, - { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00fffULL, - 0xfff807ff80000000ULL, - 0x0000000078000fffULL, - 0x3c0007ff80000000ULL, - 0ULL - }, - { - 0x0000000040300fffULL, - 0x181807ff80000000ULL, - 0x0000000010000fffULL, - 0x0c0007ff80000000ULL, - -1ULL - } -#endif - }, - { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1, - { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000fffULL, - 0xf80007ff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000070000fffULL, - 0x380007ff80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1, - { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x000000005107f000ULL, - 0x283bf80000000000ULL, - 0x00000000500bf000ULL, - 0x2c05f80000000000ULL, - -1ULL - } -#endif - }, - { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1, - { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00fc0ULL, - 0xfff807e000000000ULL, - 0x0000000078000fc0ULL, - 0x3c0007e000000000ULL, - 0ULL - }, - { - 0x0000000040100fc0ULL, - 0x180807e000000000ULL, - 0x0000000000000fc0ULL, - 0x040007e000000000ULL, - -1ULL - } -#endif - }, - { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1, - { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000fc0ULL, - 0xf80007e000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000010000fc0ULL, - 0x000007e000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a801f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000004000000ULL - } -#endif - }, - { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1840001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1838001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1850001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1848001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1860001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a801f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000004000000ULL - } -#endif - }, - { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a781f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000000000000ULL - } -#endif - }, - { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a901f80000000ULL, - -1ULL, - -1ULL, - 0x43f8000004000000ULL - } -#endif - }, - { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a881f80000000ULL, - -1ULL, - -1ULL, - 0x43f8000000000000ULL - } -#endif - }, - { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286aa01f80000000ULL, - -1ULL, - -1ULL, - 0x83f8000000000000ULL - } -#endif - }, - { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a981f80000000ULL, - -1ULL, - -1ULL, - 0x81f8000004000000ULL - } -#endif - }, - { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffffffff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a44ae80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000500c0000ULL, - 0x2806000000000000ULL, - 0x0000000028040000ULL, - 0x1802000000000000ULL, - -1ULL - } -#endif - }, - { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040100000ULL, - 0x1808000000000000ULL, - 0ULL, - 0x0400000000000000ULL, - -1ULL - } -#endif - }, - { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000010000000ULL, - 0ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050080000ULL, - 0x2804000000000000ULL, - 0x0000000028000000ULL, - 0x1800000000000000ULL, - -1ULL - } -#endif - }, - { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040200000ULL, - 0x1810000000000000ULL, - 0x0000000008000000ULL, - 0x0800000000000000ULL, - -1ULL - } -#endif - }, - { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000020000000ULL, - 0x0800000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050040000ULL, - 0x2802000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050100000ULL, - 0x2808000000000000ULL, - 0x0000000050000000ULL, - 0x2c00000000000000ULL, - -1ULL - } -#endif - }, - { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040300000ULL, - 0x1818000000000000ULL, - 0x0000000010000000ULL, - 0x0c00000000000000ULL, - -1ULL - } -#endif - }, - { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1440000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1400000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1, - { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000034000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1, - { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000035000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1, - { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000036000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x14c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1480000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1540000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1500000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x15c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1580000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1640000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1600000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x16c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1680000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1740000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1700000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x17c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1780000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051481000ULL, - -1ULL, - 0x00000000300c1000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050140000ULL, - -1ULL, - 0x0000000048000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050180000ULL, - -1ULL, - 0x0000000048040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000501c0000ULL, - 0x280a000000000000ULL, - 0x0000000040000000ULL, - 0x2404000000000000ULL, - -1ULL - } -#endif - }, - { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040400000ULL, - 0x1820000000000000ULL, - 0x0000000018000000ULL, - 0x1000000000000000ULL, - -1ULL - } -#endif - }, - { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x280e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x280c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050200000ULL, - 0x2810000000000000ULL, - 0x0000000038000000ULL, - 0x2000000000000000ULL, - -1ULL - } -#endif - }, - { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050240000ULL, - 0x2812000000000000ULL, - 0x0000000038040000ULL, - 0x2002000000000000ULL, - -1ULL - } -#endif - }, - { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050280000ULL, - 0x2814000000000000ULL, - 0x0000000038080000ULL, - 0x2004000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040500000ULL, - 0x1828000000000000ULL, - 0x0000000020000000ULL, - 0x1400000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000502c0000ULL, - 0x2816000000000000ULL, - 0x00000000380c0000ULL, - 0x2006000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040600000ULL, - 0x1830000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050300000ULL, - 0x2818000000000000ULL, - 0x0000000040040000ULL, - 0x2406000000000000ULL, - -1ULL - } -#endif - }, - { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000504c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050340000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050400000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000503c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050480000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050440000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050500000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050540000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051482000ULL, - -1ULL, - 0x00000000300c2000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050640000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050580000ULL, - 0x281a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000505c0000ULL, - 0x281c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050600000ULL, - 0x281e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a080000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a100000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2822000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2820000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000506c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050680000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050700000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050740000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050780000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000507c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050800000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2824000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2828000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2826000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2832000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2830000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a180000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a280000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a200000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1, - { { }, { }, { }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x0000000051483000ULL, - 0x286a300000000000ULL, - 0x00000000300c3000ULL, - 0x1c06400000000000ULL, - -1ULL - } -#endif - }, - { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000508c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050900000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050940000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051484000ULL, - -1ULL, - 0x00000000300c4000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050980000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000509c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a380000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a400000000000ULL, - -1ULL, - 0x1c06480000000000ULL, - -1ULL - } -#endif - }, - { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a480000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a500000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfc00000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2400000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1, - { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfc00000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2000000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a600000000000ULL, - -1ULL, - 0x1c06580000000000ULL, - -1ULL - } -#endif - }, - { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a580000000000ULL, - -1ULL, - 0x1c06500000000000ULL, - -1ULL - } -#endif - }, - { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a700000000000ULL, - -1ULL, - 0x1c06680000000000ULL, - -1ULL - } -#endif - }, - { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a680000000000ULL, - -1ULL, - 0x1c06600000000000ULL, - -1ULL - } -#endif - }, - { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286ae80000000000ULL, - -1ULL, - -1ULL, - 0x8200000004000000ULL - } -#endif - }, - { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a780000000000ULL, - -1ULL, - -1ULL, - 0x4000000000000000ULL - } -#endif - }, - { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1838000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a800000000000ULL, - -1ULL, - -1ULL, - 0x4000000004000000ULL - } -#endif - }, - { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1840000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a880000000000ULL, - -1ULL, - -1ULL, - 0x4200000000000000ULL - } -#endif - }, - { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1848000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a900000000000ULL, - -1ULL, - -1ULL, - 0x4200000004000000ULL - } -#endif - }, - { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1850000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a980000000000ULL, - -1ULL, - -1ULL, - 0x8000000004000000ULL - } -#endif - }, - { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286aa00000000000ULL, - -1ULL, - -1ULL, - 0x8200000000000000ULL - } -#endif - }, - { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1860000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286aa80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ae00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ab00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1868000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ab80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1870000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ac00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1878000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ac80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1880000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ad00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1888000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ad80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1890000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1898000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286af00000000000ULL, - -1ULL, - 0x1c06700000000000ULL, - -1ULL - } -#endif - }, - { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286af80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18b0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1, - { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000037000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050a00000ULL, - 0x2834000000000000ULL, - 0x0000000048080000ULL, - 0x2804000000000000ULL, - -1ULL - } -#endif - }, - { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18b8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d40000ULL, - -1ULL, - 0x0000000068000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050dc0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e40000ULL, - -1ULL, - 0x0000000068040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050ec0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f00000ULL, - -1ULL, - 0x0000000068080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f80000ULL, - -1ULL, - 0x00000000680c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050a80000ULL, - -1ULL, - 0x0000000070000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050ac0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b80000ULL, - -1ULL, - 0x0000000070040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050bc0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c40000ULL, - -1ULL, - 0x0000000070080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050cc0000ULL, - -1ULL, - 0x00000000700c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050a40000ULL, - -1ULL, - 0x0000000040080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d00000ULL, - -1ULL, - 0x00000000400c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050fc0000ULL, - 0x2836000000000000ULL, - 0x00000000480c0000ULL, - 0x2806000000000000ULL, - -1ULL - } -#endif - }, - { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1, - { { }, { }, { }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x0000000051485000ULL, - 0x286b080000000000ULL, - 0x00000000300c5000ULL, - 0x1c06780000000000ULL, - -1ULL - } -#endif - }, - { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051000000ULL, - 0x2838000000000000ULL, - 0x0000000050040000ULL, - 0x2c02000000000000ULL, - -1ULL - } -#endif - }, - { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051040000ULL, - 0x283a000000000000ULL, - 0x0000000050080000ULL, - 0x2c04000000000000ULL, - -1ULL - } -#endif - }, - { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040700000ULL, - 0x18c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051486000ULL, - -1ULL, - 0x00000000300c6000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051487000ULL, - -1ULL, - 0x00000000300c7000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051488000ULL, - -1ULL, - 0x00000000300c8000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051080000ULL, - 0x283c000000000000ULL, - 0x0000000058000000ULL, - 0x3000000000000000ULL, - -1ULL - } -#endif - }, - { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060040000ULL, - 0x3002000000000000ULL, - 0x0000000078000000ULL, - 0x3800000000000000ULL, - -1ULL - } -#endif - }, - { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051280000ULL, - 0x284c000000000000ULL, - 0x0000000058040000ULL, - 0x3002000000000000ULL, - -1ULL - } -#endif - }, - { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000070000000ULL, - 0x3800000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051100000ULL, - 0x2840000000000000ULL, - 0x0000000030000000ULL, - 0x1c00000000000000ULL, - -1ULL - } -#endif - }, - { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000510c0000ULL, - 0x283e000000000000ULL, - 0x0000000060040000ULL, - 0x3402000000000000ULL, - -1ULL - } -#endif - }, - { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051180000ULL, - 0x2844000000000000ULL, - 0x0000000030040000ULL, - 0x1c02000000000000ULL, - -1ULL - } -#endif - }, - { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051140000ULL, - 0x2842000000000000ULL, - 0x0000000060080000ULL, - 0x3404000000000000ULL, - -1ULL - } -#endif - }, - { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051200000ULL, - 0x2848000000000000ULL, - 0x0000000030080000ULL, - 0x1c04000000000000ULL, - -1ULL - } -#endif - }, - { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000511c0000ULL, - 0x2846000000000000ULL, - 0x00000000600c0000ULL, - 0x3406000000000000ULL, - -1ULL - } -#endif - }, - { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060080000ULL, - 0x3004000000000000ULL, - 0x0000000078040000ULL, - 0x3802000000000000ULL, - -1ULL - } -#endif - }, - { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051240000ULL, - 0x284a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000600c0000ULL, - 0x3006000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000512c0000ULL, - 0x284e000000000000ULL, - 0x0000000058080000ULL, - 0x3004000000000000ULL, - -1ULL - } -#endif - }, - { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060100000ULL, - 0x3008000000000000ULL, - 0x0000000078080000ULL, - 0x3804000000000000ULL, - -1ULL - } -#endif - }, - { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051340000ULL, - 0x2852000000000000ULL, - 0x00000000580c0000ULL, - 0x3006000000000000ULL, - -1ULL - } -#endif - }, - { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060140000ULL, - 0x300a000000000000ULL, - 0x00000000780c0000ULL, - 0x3806000000000000ULL, - -1ULL - } -#endif - }, - { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051300000ULL, - 0x2850000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060180000ULL, - 0x300c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2862000000000000ULL, - -1ULL, - -1ULL, - 0xc200000004000000ULL - } -#endif - }, - { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2854000000000000ULL, - -1ULL, - -1ULL, - 0xc000000000000000ULL - } -#endif - }, - { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18c8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2856000000000000ULL, - -1ULL, - -1ULL, - 0xc000000004000000ULL - } -#endif - }, - { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18d0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2858000000000000ULL, - -1ULL, - -1ULL, - 0xc200000000000000ULL - } -#endif - }, - { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18d8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1900000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2860000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18e0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18e8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18f0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18f8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051440000ULL, - 0x2868000000000000ULL, - 0x00000000280c0000ULL, - 0x1806000000000000ULL, - -1ULL - } -#endif - }, - { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051400000ULL, - 0x2866000000000000ULL, - 0x0000000028080000ULL, - 0x1804000000000000ULL, - -1ULL - } -#endif - }, - { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000513c0000ULL, - 0x2864000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b100000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b180000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b200000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b280000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051489000ULL, - -1ULL, - 0x00000000300c9000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148a000ULL, - -1ULL, - 0x00000000300ca000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148b000ULL, - -1ULL, - 0x00000000300cb000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148c000ULL, - -1ULL, - 0x00000000300cc000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051500000ULL, - 0x286e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040800000ULL, - 0x1908000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000514c0000ULL, - 0x286c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051540000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051580000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000515c0000ULL, - 0x2870000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040900000ULL, - 0x1910000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051600000ULL, - 0x2872000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051640000ULL, - 0x2874000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051680000ULL, - 0x2876000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040a00000ULL, - 0x1918000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000516c0000ULL, - 0x2878000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040b00000ULL, - 0x1920000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051700000ULL, - 0x287a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051780000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051740000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000517c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052900000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000528c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051800000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000518c0000ULL, - 0x287c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051900000ULL, - 0x287e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051940000ULL, - 0x2880000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040c00000ULL, - 0x1928000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051980000ULL, - 0x2882000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040d00000ULL, - 0x1930000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000519c0000ULL, - 0x2884000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051ac0000ULL, - 0x2886000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b80000ULL, - 0x2888000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000601c0000ULL, - 0x300e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051bc0000ULL, - 0x288a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060200000ULL, - 0x3010000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c00000ULL, - 0x288c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060240000ULL, - 0x3012000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c80000ULL, - 0x2890000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c40000ULL, - 0x288e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d00000ULL, - 0x2894000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040e00000ULL, - 0x1938000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051cc0000ULL, - 0x2892000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051dc0000ULL, - 0x2896000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040f00000ULL, - 0x1940000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e00000ULL, - 0x2898000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e40000ULL, - 0x289a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e80000ULL, - 0x289c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041000000ULL, - 0x1948000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051ec0000ULL, - 0x289e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041100000ULL, - 0x1950000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f00000ULL, - 0x28a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051fc0000ULL, - 0x28a2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052000000ULL, - 0x28a4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052040000ULL, - 0x28a6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041200000ULL, - 0x1958000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052080000ULL, - 0x28a8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041300000ULL, - 0x1960000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000520c0000ULL, - 0x28aa000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052100000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052140000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052180000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000521c0000ULL, - 0x28ac000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052200000ULL, - 0x28ae000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052240000ULL, - 0x28b0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052280000ULL, - 0x28b2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000522c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052300000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052340000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052400000ULL, - 0x28b6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060280000ULL, - 0x3014000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000523c0000ULL, - 0x28b4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052440000ULL, - 0x28b8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000602c0000ULL, - 0x3016000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052480000ULL, - 0x28ba000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060300000ULL, - 0x3018000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052500000ULL, - 0x28be000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000524c0000ULL, - 0x28bc000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052580000ULL, - 0x28c2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052540000ULL, - 0x28c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000525c0000ULL, - 0x28c4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052600000ULL, - 0x28c6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052640000ULL, - 0x28c8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000526c0000ULL, - 0x28cc000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052680000ULL, - 0x28ca000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052700000ULL, - 0x28ce000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052740000ULL, - 0x28d0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000527c0000ULL, - 0x28d4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052780000ULL, - 0x28d2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b300000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000052800000ULL, - 0x28d6000000000000ULL, - 0x00000000500c0000ULL, - 0x2c06000000000000ULL, - -1ULL - } -#endif - }, - { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041400000ULL, - 0x1968000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } }, -#ifndef DISASM_ONLY - { 0, }, { 0, } -#endif - } -}; - -#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6)) -#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index)) - -static const unsigned short decode_X0_fsm[936] = -{ - BITFIELD(22, 9) /* index 0 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS, - TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU, - TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS, - TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM, - TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578), - CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671), - CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865), - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - BITFIELD(6, 2) /* index 513 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), - BITFIELD(8, 2) /* index 518 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), - BITFIELD(10, 2) /* index 523 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, - BITFIELD(20, 2) /* index 528 */, - TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), - BITFIELD(6, 2) /* index 533 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), - BITFIELD(8, 2) /* index 538 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), - BITFIELD(10, 2) /* index 543 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(0, 2) /* index 548 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), - BITFIELD(2, 2) /* index 553 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), - BITFIELD(4, 2) /* index 558 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), - BITFIELD(6, 2) /* index 563 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), - BITFIELD(8, 2) /* index 568 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), - BITFIELD(10, 2) /* index 573 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(20, 2) /* index 578 */, - TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI, - BITFIELD(20, 2) /* index 583 */, - TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI, - TILEGX_OPC_V1CMPLTUI, - BITFIELD(20, 2) /* index 588 */, - TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI, - TILEGX_OPC_V2CMPEQI, - BITFIELD(20, 2) /* index 593 */, - TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI, - TILEGX_OPC_V2MINSI, - BITFIELD(20, 2) /* index 598 */, - TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 603 */, - TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, - TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR, - BITFIELD(18, 4) /* index 620 */, - TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL, - TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2, - TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN, - TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS, - TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1, - TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS, - BITFIELD(18, 4) /* index 637 */, - TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN, - TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2, - TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2, - TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX, - TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS, - TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS, - BITFIELD(18, 4) /* index 654 */, - TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU, - TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS, - TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU, - TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU, - TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU, - TILEGX_OPC_MZ, - BITFIELD(18, 4) /* index 671 */, - TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, - TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES, - TILEGX_OPC_SUBXSC, - BITFIELD(12, 2) /* index 688 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693), - BITFIELD(14, 2) /* index 693 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698), - BITFIELD(16, 2) /* index 698 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(18, 4) /* index 703 */, - TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA, - BITFIELD(12, 4) /* index 720 */, - TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757), - CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787), - CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 737 */, - TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 742 */, - TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 747 */, - TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 752 */, - TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 757 */, - TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 762 */, - TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 767 */, - TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 772 */, - TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 777 */, - TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 782 */, - TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 787 */, - TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 792 */, - TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 797 */, - TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU, - TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS, - TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU, - TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, - BITFIELD(18, 4) /* index 814 */, - TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, - TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS, - TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, - TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE, - TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H, - BITFIELD(18, 4) /* index 831 */, - TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, - TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS, - TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC, - BITFIELD(18, 4) /* index 848 */, - TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC, - TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, - TILEGX_OPC_V4SUB, - BITFIELD(18, 3) /* index 865 */, - CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 874 */, - TILEGX_OPC_XOR, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 877 */, - TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 880 */, - TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 883 */, - TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 886 */, - TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 889 */, - TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(0, 2) /* index 906 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(911), - BITFIELD(2, 2) /* index 911 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(916), - BITFIELD(4, 2) /* index 916 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(921), - BITFIELD(6, 2) /* index 921 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(926), - BITFIELD(8, 2) /* index 926 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(931), - BITFIELD(10, 2) /* index 931 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_INFOL, -}; - -static const unsigned short decode_X1_fsm[1266] = -{ - BITFIELD(53, 9) /* index 0 */, - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT, - TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT, - TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT, - TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT, - TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST, - TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT, - TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT, - TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT, - TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578), - CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758), - CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185), - CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), - BITFIELD(37, 2) /* index 513 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), - BITFIELD(39, 2) /* index 518 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), - BITFIELD(41, 2) /* index 523 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, - BITFIELD(51, 2) /* index 528 */, - TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), - BITFIELD(37, 2) /* index 533 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), - BITFIELD(39, 2) /* index 538 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), - BITFIELD(41, 2) /* index 543 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(31, 2) /* index 548 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), - BITFIELD(33, 2) /* index 553 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), - BITFIELD(35, 2) /* index 558 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), - BITFIELD(37, 2) /* index 563 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), - BITFIELD(39, 2) /* index 568 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), - BITFIELD(41, 2) /* index 573 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(51, 2) /* index 578 */, - TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583), - BITFIELD(31, 2) /* index 583 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588), - BITFIELD(33, 2) /* index 588 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593), - BITFIELD(35, 2) /* index 593 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, - TILEGX_OPC_PREFETCH_ADD_L1_FAULT, - BITFIELD(51, 2) /* index 598 */, - CHILD(603), CHILD(618), CHILD(633), CHILD(648), - BITFIELD(31, 2) /* index 603 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608), - BITFIELD(33, 2) /* index 608 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613), - BITFIELD(35, 2) /* index 613 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, - TILEGX_OPC_PREFETCH_ADD_L1, - BITFIELD(31, 2) /* index 618 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623), - BITFIELD(33, 2) /* index 623 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628), - BITFIELD(35, 2) /* index 628 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, - TILEGX_OPC_PREFETCH_ADD_L2_FAULT, - BITFIELD(31, 2) /* index 633 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638), - BITFIELD(33, 2) /* index 638 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643), - BITFIELD(35, 2) /* index 643 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, - TILEGX_OPC_PREFETCH_ADD_L2, - BITFIELD(31, 2) /* index 648 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(673), - BITFIELD(43, 2) /* index 653 */, - CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(45, 2) /* index 658 */, - CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(47, 2) /* index 663 */, - CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(49, 2) /* index 668 */, - TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - TILEGX_OPC_LD4S_ADD, - BITFIELD(33, 2) /* index 673 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(678), - BITFIELD(35, 2) /* index 678 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(683), - BITFIELD(43, 2) /* index 683 */, - CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(45, 2) /* index 688 */, - CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(47, 2) /* index 693 */, - CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(49, 2) /* index 698 */, - TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(51, 2) /* index 703 */, - CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD, - TILEGX_OPC_LDNT2S_ADD, - BITFIELD(31, 2) /* index 708 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713), - BITFIELD(33, 2) /* index 713 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718), - BITFIELD(35, 2) /* index 718 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, - TILEGX_OPC_PREFETCH_ADD_L3, - BITFIELD(51, 2) /* index 723 */, - TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD, - TILEGX_OPC_LDNT_ADD, - BITFIELD(51, 2) /* index 728 */, - CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR, - BITFIELD(43, 2) /* index 733 */, - CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(45, 2) /* index 738 */, - CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(47, 2) /* index 743 */, - CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(49, 2) /* index 748 */, - TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(51, 2) /* index 753 */, - TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD, - BITFIELD(51, 2) /* index 758 */, - TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD, - TILEGX_OPC_STNT_ADD, - BITFIELD(51, 2) /* index 763 */, - TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, - TILEGX_OPC_V1CMPLTSI, - BITFIELD(51, 2) /* index 768 */, - TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, - TILEGX_OPC_V2ADDI, - BITFIELD(51, 2) /* index 773 */, - TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, - TILEGX_OPC_V2MAXSI, - BITFIELD(51, 2) /* index 778 */, - TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 783 */, - TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, - TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4, - TILEGX_OPC_DBLALIGN6, - BITFIELD(49, 4) /* index 800 */, - TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4, - TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD, - TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4, - TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR, - CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, - BITFIELD(43, 2) /* index 817 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822), - BITFIELD(45, 2) /* index 822 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827), - BITFIELD(47, 2) /* index 827 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(49, 4) /* index 832 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, - TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1, - TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2, - TILEGX_OPC_STNT4, - BITFIELD(46, 7) /* index 849 */, - TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, - TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, - TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, - TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC, - TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, - TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX, - TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, - TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, - TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987), - CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - BITFIELD(43, 3) /* index 978 */, - TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV, - TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH, - BITFIELD(43, 3) /* index 987 */, - CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP, - TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051), - BITFIELD(31, 2) /* index 996 */, - CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(33, 2) /* index 1001 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006), - BITFIELD(35, 2) /* index 1006 */, - TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(37, 2) /* index 1011 */, - TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(39, 2) /* index 1016 */, - TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(41, 2) /* index 1021 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL, - BITFIELD(33, 2) /* index 1026 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031), - BITFIELD(35, 2) /* index 1031 */, - TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(37, 2) /* index 1036 */, - TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(39, 2) /* index 1041 */, - TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(41, 2) /* index 1046 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL, - BITFIELD(31, 2) /* index 1051 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056), - BITFIELD(33, 2) /* index 1056 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061), - BITFIELD(35, 2) /* index 1061 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, - TILEGX_OPC_PREFETCH_L1_FAULT, - BITFIELD(43, 3) /* index 1066 */, - CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135), - TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U, - BITFIELD(31, 2) /* index 1075 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080), - BITFIELD(33, 2) /* index 1080 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085), - BITFIELD(35, 2) /* index 1085 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, - BITFIELD(31, 2) /* index 1090 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095), - BITFIELD(33, 2) /* index 1095 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100), - BITFIELD(35, 2) /* index 1100 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, - TILEGX_OPC_PREFETCH_L2_FAULT, - BITFIELD(31, 2) /* index 1105 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110), - BITFIELD(33, 2) /* index 1110 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115), - BITFIELD(35, 2) /* index 1115 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, - BITFIELD(31, 2) /* index 1120 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125), - BITFIELD(33, 2) /* index 1125 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130), - BITFIELD(35, 2) /* index 1130 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, - TILEGX_OPC_PREFETCH_L3_FAULT, - BITFIELD(31, 2) /* index 1135 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140), - BITFIELD(33, 2) /* index 1140 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145), - BITFIELD(35, 2) /* index 1145 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, - BITFIELD(43, 3) /* index 1150 */, - TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U, - TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF, - BITFIELD(43, 3) /* index 1159 */, - TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1, - TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 1168 */, - TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ, - TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, - TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ, - TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS, - TILEGX_OPC_V2CMPLTU, - BITFIELD(49, 4) /* index 1185 */, - TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L, - TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, - TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB, - BITFIELD(49, 4) /* index 1202 */, - TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, - TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 1219 */, - TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(31, 2) /* index 1236 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1241), - BITFIELD(33, 2) /* index 1241 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1246), - BITFIELD(35, 2) /* index 1246 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1251), - BITFIELD(37, 2) /* index 1251 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1256), - BITFIELD(39, 2) /* index 1256 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1261), - BITFIELD(41, 2) /* index 1261 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_INFOL, -}; - -static const unsigned short decode_Y0_fsm[178] = -{ - BITFIELD(27, 4) /* index 0 */, - CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123), - CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168), - CHILD(173), - BITFIELD(6, 2) /* index 17 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), - BITFIELD(8, 2) /* index 22 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), - BITFIELD(10, 2) /* index 27 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(0, 2) /* index 32 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), - BITFIELD(2, 2) /* index 37 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), - BITFIELD(4, 2) /* index 42 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), - BITFIELD(6, 2) /* index 47 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), - BITFIELD(8, 2) /* index 52 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), - BITFIELD(10, 2) /* index 57 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(18, 2) /* index 62 */, - TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - BITFIELD(15, 5) /* index 67 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100), - CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(12, 3) /* index 100 */, - TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP, - TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT, - TILEGX_OPC_REVBITS, - BITFIELD(12, 3) /* index 109 */, - TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1, - TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(18, 2) /* index 118 */, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - BITFIELD(18, 2) /* index 123 */, - TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX, - BITFIELD(18, 2) /* index 128 */, - TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, - BITFIELD(18, 2) /* index 133 */, - TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR, - BITFIELD(12, 2) /* index 138 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143), - BITFIELD(14, 2) /* index 143 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148), - BITFIELD(16, 2) /* index 148 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(18, 2) /* index 153 */, - TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, - BITFIELD(18, 2) /* index 158 */, - TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADDX, - BITFIELD(18, 2) /* index 163 */, - TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS, - TILEGX_OPC_MUL_LU_LU, - BITFIELD(18, 2) /* index 168 */, - TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS, - TILEGX_OPC_MULA_LU_LU, - BITFIELD(18, 2) /* index 173 */, - TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, -}; - -static const unsigned short decode_Y1_fsm[167] = -{ - BITFIELD(58, 4) /* index 0 */, - TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122), - CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE, - BITFIELD(37, 2) /* index 17 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), - BITFIELD(39, 2) /* index 22 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), - BITFIELD(41, 2) /* index 27 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(31, 2) /* index 32 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), - BITFIELD(33, 2) /* index 37 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), - BITFIELD(35, 2) /* index 42 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), - BITFIELD(37, 2) /* index 47 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), - BITFIELD(39, 2) /* index 52 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), - BITFIELD(41, 2) /* index 57 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(49, 2) /* index 62 */, - TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - BITFIELD(47, 4) /* index 67 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84), - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(43, 3) /* index 84 */, - CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108), - CHILD(111), CHILD(114), - BITFIELD(46, 1) /* index 93 */, - TILEGX_OPC_NONE, TILEGX_OPC_FNOP, - BITFIELD(46, 1) /* index 96 */, - TILEGX_OPC_NONE, TILEGX_OPC_ILL, - BITFIELD(46, 1) /* index 99 */, - TILEGX_OPC_NONE, TILEGX_OPC_JALRP, - BITFIELD(46, 1) /* index 102 */, - TILEGX_OPC_NONE, TILEGX_OPC_JALR, - BITFIELD(46, 1) /* index 105 */, - TILEGX_OPC_NONE, TILEGX_OPC_JRP, - BITFIELD(46, 1) /* index 108 */, - TILEGX_OPC_NONE, TILEGX_OPC_JR, - BITFIELD(46, 1) /* index 111 */, - TILEGX_OPC_NONE, TILEGX_OPC_LNK, - BITFIELD(46, 1) /* index 114 */, - TILEGX_OPC_NONE, TILEGX_OPC_NOP, - BITFIELD(49, 2) /* index 117 */, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - BITFIELD(49, 2) /* index 122 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, - BITFIELD(49, 2) /* index 127 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, - BITFIELD(49, 2) /* index 132 */, - TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR, - BITFIELD(43, 2) /* index 137 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142), - BITFIELD(45, 2) /* index 142 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147), - BITFIELD(47, 2) /* index 147 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(49, 2) /* index 152 */, - TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, - BITFIELD(49, 2) /* index 157 */, - TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADDX, - BITFIELD(49, 2) /* index 162 */, - TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, -}; - -static const unsigned short decode_Y2_fsm[118] = -{ - BITFIELD(62, 2) /* index 0 */, - TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109), - BITFIELD(55, 3) /* index 5 */, - CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40), - CHILD(43), - BITFIELD(26, 1) /* index 14 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1U, - BITFIELD(26, 1) /* index 17 */, - CHILD(20), CHILD(30), - BITFIELD(51, 2) /* index 20 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25), - BITFIELD(53, 2) /* index 25 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, - TILEGX_OPC_PREFETCH_L1_FAULT, - BITFIELD(51, 2) /* index 30 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35), - BITFIELD(53, 2) /* index 35 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, - BITFIELD(26, 1) /* index 40 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2U, - BITFIELD(26, 1) /* index 43 */, - CHILD(46), CHILD(56), - BITFIELD(51, 2) /* index 46 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51), - BITFIELD(53, 2) /* index 51 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, - TILEGX_OPC_PREFETCH_L2_FAULT, - BITFIELD(51, 2) /* index 56 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61), - BITFIELD(53, 2) /* index 61 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, - BITFIELD(56, 2) /* index 66 */, - CHILD(71), CHILD(74), CHILD(90), CHILD(93), - BITFIELD(26, 1) /* index 71 */, - TILEGX_OPC_NONE, TILEGX_OPC_LD4S, - BITFIELD(26, 1) /* index 74 */, - TILEGX_OPC_NONE, CHILD(77), - BITFIELD(51, 2) /* index 77 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82), - BITFIELD(53, 2) /* index 82 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87), - BITFIELD(55, 1) /* index 87 */, - TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT, - BITFIELD(26, 1) /* index 90 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD, - BITFIELD(26, 1) /* index 93 */, - CHILD(96), TILEGX_OPC_LD, - BITFIELD(51, 2) /* index 96 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101), - BITFIELD(53, 2) /* index 101 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106), - BITFIELD(55, 1) /* index 106 */, - TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, - BITFIELD(26, 1) /* index 109 */, - CHILD(112), CHILD(115), - BITFIELD(57, 1) /* index 112 */, - TILEGX_OPC_ST1, TILEGX_OPC_ST4, - BITFIELD(57, 1) /* index 115 */, - TILEGX_OPC_ST2, TILEGX_OPC_ST, -}; - -#undef BITFIELD -#undef CHILD - -const unsigned short * const -tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] = -{ - decode_X0_fsm, - decode_X1_fsm, - decode_Y0_fsm, - decode_Y1_fsm, - decode_Y2_fsm -}; - -const struct tilegx_operand tilegx_operands[35] = -{ - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0), - 8, 1, 0, 0, 0, 0, - create_Imm8_X0, get_Imm8_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1), - 8, 1, 0, 0, 0, 0, - create_Imm8_X1, get_Imm8_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0), - 8, 1, 0, 0, 0, 0, - create_Imm8_Y0, get_Imm8_Y0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1), - 8, 1, 0, 0, 0, 0, - create_Imm8_Y1, get_Imm8_Y1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST), - 16, 1, 0, 0, 0, 0, - create_Imm16_X0, get_Imm16_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST), - 16, 1, 0, 0, 0, 0, - create_Imm16_X1, get_Imm16_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_X1, get_Dest_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_X1, get_SrcA_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_X0, get_Dest_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_X0, get_SrcA_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_Y0, get_Dest_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y0, get_SrcA_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_Y1, get_Dest_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y1, get_SrcA_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y2, get_SrcA_Y2 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_SrcA_X1, get_SrcA_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_X0, get_SrcB_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_X1, get_SrcB_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_Y0, get_SrcB_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_Y1, get_SrcB_Y1 - }, - { - TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1), - 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, - create_BrOff_X1, get_BrOff_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0), - 6, 0, 0, 0, 0, 0, - create_BFStart_X0, get_BFStart_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0), - 6, 0, 0, 0, 0, 0, - create_BFEnd_X0, get_BFEnd_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_Dest_X0, get_Dest_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_Dest_Y0, get_Dest_Y0 - }, - { - TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1), - 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, - create_JumpOff_X1, get_JumpOff_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_SrcBDest_Y2, get_SrcBDest_Y2 - }, - { - TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1), - 14, 0, 0, 0, 0, 0, - create_MF_Imm14_X1, get_MF_Imm14_X1 - }, - { - TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1), - 14, 0, 0, 0, 0, 0, - create_MT_Imm14_X1, get_MT_Imm14_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0), - 6, 0, 0, 0, 0, 0, - create_ShAmt_X0, get_ShAmt_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1), - 6, 0, 0, 0, 0, 0, - create_ShAmt_X1, get_ShAmt_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0), - 6, 0, 0, 0, 0, 0, - create_ShAmt_Y0, get_ShAmt_Y0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1), - 6, 0, 0, 0, 0, 0, - create_ShAmt_Y1, get_ShAmt_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcBDest_Y2, get_SrcBDest_Y2 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1), - 8, 1, 0, 0, 0, 0, - create_Dest_Imm8_X1, get_Dest_Imm8_X1 - } -}; - -/* Given a set of bundle bits and a specific pipe, returns which - * instruction the bundle contains in that pipe. - */ -const struct tilegx_opcode * -find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe) -{ - const unsigned short *table = tilegx_bundle_decoder_fsms[pipe]; - int index = 0; - - while (1) - { - unsigned short bitspec = table[index]; - unsigned int bitfield = - ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6); - - unsigned short next = table[index + 1 + bitfield]; - if (next <= TILEGX_OPC_NONE) - return &tilegx_opcodes[next]; - - index = next - TILEGX_OPC_NONE; - } -} - -int -parse_insn_tilegx(tilegx_bundle_bits bits, - unsigned long long pc, - struct tilegx_decoded_instruction - decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]) -{ - int num_instructions = 0; - int pipe; - - int min_pipe, max_pipe; - if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0) - { - min_pipe = TILEGX_PIPELINE_X0; - max_pipe = TILEGX_PIPELINE_X1; - } - else - { - min_pipe = TILEGX_PIPELINE_Y0; - max_pipe = TILEGX_PIPELINE_Y2; - } - - /* For each pipe, find an instruction that fits. */ - for (pipe = min_pipe; pipe <= max_pipe; pipe++) - { - const struct tilegx_opcode *opc; - struct tilegx_decoded_instruction *d; - int i; - - d = &decoded[num_instructions++]; - opc = find_opcode (bits, (tilegx_pipeline)pipe); - d->opcode = opc; - - /* Decode each operand, sign extending, etc. as appropriate. */ - for (i = 0; i < opc->num_operands; i++) - { - const struct tilegx_operand *op = - &tilegx_operands[opc->operands[pipe][i]]; - int raw_opval = op->extract (bits); - long long opval; - - if (op->is_signed) - { - /* Sign-extend the operand. */ - int shift = (int)((sizeof(int) * 8) - op->num_bits); - raw_opval = (raw_opval << shift) >> shift; - } - - /* Adjust PC-relative scaled branch offsets. */ - if (op->type == TILEGX_OP_TYPE_ADDRESS) - opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc; - else - opval = raw_opval; - - /* Record the final value. */ - d->operands[i] = op; - d->operand_values[i] = opval; - } - } - - return num_instructions; -} - -struct tilegx_spr -{ - /* The number */ - int number; - - /* The name */ - const char *name; -}; - -static int -tilegx_spr_compare (const void *a_ptr, const void *b_ptr) -{ - const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr; - const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr; - return (a->number - b->number); -} - -const struct tilegx_spr tilegx_sprs[] = { - { 0, "MPL_MEM_ERROR_SET_0" }, - { 1, "MPL_MEM_ERROR_SET_1" }, - { 2, "MPL_MEM_ERROR_SET_2" }, - { 3, "MPL_MEM_ERROR_SET_3" }, - { 4, "MPL_MEM_ERROR" }, - { 5, "MEM_ERROR_CBOX_ADDR" }, - { 6, "MEM_ERROR_CBOX_STATUS" }, - { 7, "MEM_ERROR_ENABLE" }, - { 8, "MEM_ERROR_MBOX_ADDR" }, - { 9, "MEM_ERROR_MBOX_STATUS" }, - { 10, "SBOX_ERROR" }, - { 11, "XDN_DEMUX_ERROR" }, - { 256, "MPL_SINGLE_STEP_3_SET_0" }, - { 257, "MPL_SINGLE_STEP_3_SET_1" }, - { 258, "MPL_SINGLE_STEP_3_SET_2" }, - { 259, "MPL_SINGLE_STEP_3_SET_3" }, - { 260, "MPL_SINGLE_STEP_3" }, - { 261, "SINGLE_STEP_CONTROL_3" }, - { 512, "MPL_SINGLE_STEP_2_SET_0" }, - { 513, "MPL_SINGLE_STEP_2_SET_1" }, - { 514, "MPL_SINGLE_STEP_2_SET_2" }, - { 515, "MPL_SINGLE_STEP_2_SET_3" }, - { 516, "MPL_SINGLE_STEP_2" }, - { 517, "SINGLE_STEP_CONTROL_2" }, - { 768, "MPL_SINGLE_STEP_1_SET_0" }, - { 769, "MPL_SINGLE_STEP_1_SET_1" }, - { 770, "MPL_SINGLE_STEP_1_SET_2" }, - { 771, "MPL_SINGLE_STEP_1_SET_3" }, - { 772, "MPL_SINGLE_STEP_1" }, - { 773, "SINGLE_STEP_CONTROL_1" }, - { 1024, "MPL_SINGLE_STEP_0_SET_0" }, - { 1025, "MPL_SINGLE_STEP_0_SET_1" }, - { 1026, "MPL_SINGLE_STEP_0_SET_2" }, - { 1027, "MPL_SINGLE_STEP_0_SET_3" }, - { 1028, "MPL_SINGLE_STEP_0" }, - { 1029, "SINGLE_STEP_CONTROL_0" }, - { 1280, "MPL_IDN_COMPLETE_SET_0" }, - { 1281, "MPL_IDN_COMPLETE_SET_1" }, - { 1282, "MPL_IDN_COMPLETE_SET_2" }, - { 1283, "MPL_IDN_COMPLETE_SET_3" }, - { 1284, "MPL_IDN_COMPLETE" }, - { 1285, "IDN_COMPLETE_PENDING" }, - { 1536, "MPL_UDN_COMPLETE_SET_0" }, - { 1537, "MPL_UDN_COMPLETE_SET_1" }, - { 1538, "MPL_UDN_COMPLETE_SET_2" }, - { 1539, "MPL_UDN_COMPLETE_SET_3" }, - { 1540, "MPL_UDN_COMPLETE" }, - { 1541, "UDN_COMPLETE_PENDING" }, - { 1792, "MPL_ITLB_MISS_SET_0" }, - { 1793, "MPL_ITLB_MISS_SET_1" }, - { 1794, "MPL_ITLB_MISS_SET_2" }, - { 1795, "MPL_ITLB_MISS_SET_3" }, - { 1796, "MPL_ITLB_MISS" }, - { 1797, "ITLB_TSB_BASE_ADDR_0" }, - { 1798, "ITLB_TSB_BASE_ADDR_1" }, - { 1920, "ITLB_CURRENT_ATTR" }, - { 1921, "ITLB_CURRENT_PA" }, - { 1922, "ITLB_CURRENT_VA" }, - { 1923, "ITLB_INDEX" }, - { 1924, "ITLB_MATCH_0" }, - { 1925, "ITLB_PERF" }, - { 1926, "ITLB_PR" }, - { 1927, "ITLB_TSB_ADDR_0" }, - { 1928, "ITLB_TSB_ADDR_1" }, - { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" }, - { 1930, "ITLB_TSB_FILL_MATCH" }, - { 1931, "NUMBER_ITLB" }, - { 1932, "REPLACEMENT_ITLB" }, - { 1933, "WIRED_ITLB" }, - { 2048, "MPL_ILL_SET_0" }, - { 2049, "MPL_ILL_SET_1" }, - { 2050, "MPL_ILL_SET_2" }, - { 2051, "MPL_ILL_SET_3" }, - { 2052, "MPL_ILL" }, - { 2304, "MPL_GPV_SET_0" }, - { 2305, "MPL_GPV_SET_1" }, - { 2306, "MPL_GPV_SET_2" }, - { 2307, "MPL_GPV_SET_3" }, - { 2308, "MPL_GPV" }, - { 2309, "GPV_REASON" }, - { 2560, "MPL_IDN_ACCESS_SET_0" }, - { 2561, "MPL_IDN_ACCESS_SET_1" }, - { 2562, "MPL_IDN_ACCESS_SET_2" }, - { 2563, "MPL_IDN_ACCESS_SET_3" }, - { 2564, "MPL_IDN_ACCESS" }, - { 2565, "IDN_DEMUX_COUNT_0" }, - { 2566, "IDN_DEMUX_COUNT_1" }, - { 2567, "IDN_FLUSH_EGRESS" }, - { 2568, "IDN_PENDING" }, - { 2569, "IDN_ROUTE_ORDER" }, - { 2570, "IDN_SP_FIFO_CNT" }, - { 2688, "IDN_DATA_AVAIL" }, - { 2816, "MPL_UDN_ACCESS_SET_0" }, - { 2817, "MPL_UDN_ACCESS_SET_1" }, - { 2818, "MPL_UDN_ACCESS_SET_2" }, - { 2819, "MPL_UDN_ACCESS_SET_3" }, - { 2820, "MPL_UDN_ACCESS" }, - { 2821, "UDN_DEMUX_COUNT_0" }, - { 2822, "UDN_DEMUX_COUNT_1" }, - { 2823, "UDN_DEMUX_COUNT_2" }, - { 2824, "UDN_DEMUX_COUNT_3" }, - { 2825, "UDN_FLUSH_EGRESS" }, - { 2826, "UDN_PENDING" }, - { 2827, "UDN_ROUTE_ORDER" }, - { 2828, "UDN_SP_FIFO_CNT" }, - { 2944, "UDN_DATA_AVAIL" }, - { 3072, "MPL_SWINT_3_SET_0" }, - { 3073, "MPL_SWINT_3_SET_1" }, - { 3074, "MPL_SWINT_3_SET_2" }, - { 3075, "MPL_SWINT_3_SET_3" }, - { 3076, "MPL_SWINT_3" }, - { 3328, "MPL_SWINT_2_SET_0" }, - { 3329, "MPL_SWINT_2_SET_1" }, - { 3330, "MPL_SWINT_2_SET_2" }, - { 3331, "MPL_SWINT_2_SET_3" }, - { 3332, "MPL_SWINT_2" }, - { 3584, "MPL_SWINT_1_SET_0" }, - { 3585, "MPL_SWINT_1_SET_1" }, - { 3586, "MPL_SWINT_1_SET_2" }, - { 3587, "MPL_SWINT_1_SET_3" }, - { 3588, "MPL_SWINT_1" }, - { 3840, "MPL_SWINT_0_SET_0" }, - { 3841, "MPL_SWINT_0_SET_1" }, - { 3842, "MPL_SWINT_0_SET_2" }, - { 3843, "MPL_SWINT_0_SET_3" }, - { 3844, "MPL_SWINT_0" }, - { 4096, "MPL_ILL_TRANS_SET_0" }, - { 4097, "MPL_ILL_TRANS_SET_1" }, - { 4098, "MPL_ILL_TRANS_SET_2" }, - { 4099, "MPL_ILL_TRANS_SET_3" }, - { 4100, "MPL_ILL_TRANS" }, - { 4101, "ILL_TRANS_REASON" }, - { 4102, "ILL_VA_PC" }, - { 4352, "MPL_UNALIGN_DATA_SET_0" }, - { 4353, "MPL_UNALIGN_DATA_SET_1" }, - { 4354, "MPL_UNALIGN_DATA_SET_2" }, - { 4355, "MPL_UNALIGN_DATA_SET_3" }, - { 4356, "MPL_UNALIGN_DATA" }, - { 4608, "MPL_DTLB_MISS_SET_0" }, - { 4609, "MPL_DTLB_MISS_SET_1" }, - { 4610, "MPL_DTLB_MISS_SET_2" }, - { 4611, "MPL_DTLB_MISS_SET_3" }, - { 4612, "MPL_DTLB_MISS" }, - { 4613, "DTLB_TSB_BASE_ADDR_0" }, - { 4614, "DTLB_TSB_BASE_ADDR_1" }, - { 4736, "AAR" }, - { 4737, "CACHE_PINNED_WAYS" }, - { 4738, "DTLB_BAD_ADDR" }, - { 4739, "DTLB_BAD_ADDR_REASON" }, - { 4740, "DTLB_CURRENT_ATTR" }, - { 4741, "DTLB_CURRENT_PA" }, - { 4742, "DTLB_CURRENT_VA" }, - { 4743, "DTLB_INDEX" }, - { 4744, "DTLB_MATCH_0" }, - { 4745, "DTLB_PERF" }, - { 4746, "DTLB_TSB_ADDR_0" }, - { 4747, "DTLB_TSB_ADDR_1" }, - { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" }, - { 4749, "DTLB_TSB_FILL_MATCH" }, - { 4750, "NUMBER_DTLB" }, - { 4751, "REPLACEMENT_DTLB" }, - { 4752, "WIRED_DTLB" }, - { 4864, "MPL_DTLB_ACCESS_SET_0" }, - { 4865, "MPL_DTLB_ACCESS_SET_1" }, - { 4866, "MPL_DTLB_ACCESS_SET_2" }, - { 4867, "MPL_DTLB_ACCESS_SET_3" }, - { 4868, "MPL_DTLB_ACCESS" }, - { 5120, "MPL_IDN_FIREWALL_SET_0" }, - { 5121, "MPL_IDN_FIREWALL_SET_1" }, - { 5122, "MPL_IDN_FIREWALL_SET_2" }, - { 5123, "MPL_IDN_FIREWALL_SET_3" }, - { 5124, "MPL_IDN_FIREWALL" }, - { 5125, "IDN_DIRECTION_PROTECT" }, - { 5376, "MPL_UDN_FIREWALL_SET_0" }, - { 5377, "MPL_UDN_FIREWALL_SET_1" }, - { 5378, "MPL_UDN_FIREWALL_SET_2" }, - { 5379, "MPL_UDN_FIREWALL_SET_3" }, - { 5380, "MPL_UDN_FIREWALL" }, - { 5381, "UDN_DIRECTION_PROTECT" }, - { 5632, "MPL_TILE_TIMER_SET_0" }, - { 5633, "MPL_TILE_TIMER_SET_1" }, - { 5634, "MPL_TILE_TIMER_SET_2" }, - { 5635, "MPL_TILE_TIMER_SET_3" }, - { 5636, "MPL_TILE_TIMER" }, - { 5637, "TILE_TIMER_CONTROL" }, - { 5888, "MPL_AUX_TILE_TIMER_SET_0" }, - { 5889, "MPL_AUX_TILE_TIMER_SET_1" }, - { 5890, "MPL_AUX_TILE_TIMER_SET_2" }, - { 5891, "MPL_AUX_TILE_TIMER_SET_3" }, - { 5892, "MPL_AUX_TILE_TIMER" }, - { 5893, "AUX_TILE_TIMER_CONTROL" }, - { 6144, "MPL_IDN_TIMER_SET_0" }, - { 6145, "MPL_IDN_TIMER_SET_1" }, - { 6146, "MPL_IDN_TIMER_SET_2" }, - { 6147, "MPL_IDN_TIMER_SET_3" }, - { 6148, "MPL_IDN_TIMER" }, - { 6149, "IDN_DEADLOCK_COUNT" }, - { 6150, "IDN_DEADLOCK_TIMEOUT" }, - { 6400, "MPL_UDN_TIMER_SET_0" }, - { 6401, "MPL_UDN_TIMER_SET_1" }, - { 6402, "MPL_UDN_TIMER_SET_2" }, - { 6403, "MPL_UDN_TIMER_SET_3" }, - { 6404, "MPL_UDN_TIMER" }, - { 6405, "UDN_DEADLOCK_COUNT" }, - { 6406, "UDN_DEADLOCK_TIMEOUT" }, - { 6656, "MPL_IDN_AVAIL_SET_0" }, - { 6657, "MPL_IDN_AVAIL_SET_1" }, - { 6658, "MPL_IDN_AVAIL_SET_2" }, - { 6659, "MPL_IDN_AVAIL_SET_3" }, - { 6660, "MPL_IDN_AVAIL" }, - { 6661, "IDN_AVAIL_EN" }, - { 6912, "MPL_UDN_AVAIL_SET_0" }, - { 6913, "MPL_UDN_AVAIL_SET_1" }, - { 6914, "MPL_UDN_AVAIL_SET_2" }, - { 6915, "MPL_UDN_AVAIL_SET_3" }, - { 6916, "MPL_UDN_AVAIL" }, - { 6917, "UDN_AVAIL_EN" }, - { 7168, "MPL_IPI_3_SET_0" }, - { 7169, "MPL_IPI_3_SET_1" }, - { 7170, "MPL_IPI_3_SET_2" }, - { 7171, "MPL_IPI_3_SET_3" }, - { 7172, "MPL_IPI_3" }, - { 7173, "IPI_EVENT_3" }, - { 7174, "IPI_EVENT_RESET_3" }, - { 7175, "IPI_EVENT_SET_3" }, - { 7176, "IPI_MASK_3" }, - { 7177, "IPI_MASK_RESET_3" }, - { 7178, "IPI_MASK_SET_3" }, - { 7424, "MPL_IPI_2_SET_0" }, - { 7425, "MPL_IPI_2_SET_1" }, - { 7426, "MPL_IPI_2_SET_2" }, - { 7427, "MPL_IPI_2_SET_3" }, - { 7428, "MPL_IPI_2" }, - { 7429, "IPI_EVENT_2" }, - { 7430, "IPI_EVENT_RESET_2" }, - { 7431, "IPI_EVENT_SET_2" }, - { 7432, "IPI_MASK_2" }, - { 7433, "IPI_MASK_RESET_2" }, - { 7434, "IPI_MASK_SET_2" }, - { 7680, "MPL_IPI_1_SET_0" }, - { 7681, "MPL_IPI_1_SET_1" }, - { 7682, "MPL_IPI_1_SET_2" }, - { 7683, "MPL_IPI_1_SET_3" }, - { 7684, "MPL_IPI_1" }, - { 7685, "IPI_EVENT_1" }, - { 7686, "IPI_EVENT_RESET_1" }, - { 7687, "IPI_EVENT_SET_1" }, - { 7688, "IPI_MASK_1" }, - { 7689, "IPI_MASK_RESET_1" }, - { 7690, "IPI_MASK_SET_1" }, - { 7936, "MPL_IPI_0_SET_0" }, - { 7937, "MPL_IPI_0_SET_1" }, - { 7938, "MPL_IPI_0_SET_2" }, - { 7939, "MPL_IPI_0_SET_3" }, - { 7940, "MPL_IPI_0" }, - { 7941, "IPI_EVENT_0" }, - { 7942, "IPI_EVENT_RESET_0" }, - { 7943, "IPI_EVENT_SET_0" }, - { 7944, "IPI_MASK_0" }, - { 7945, "IPI_MASK_RESET_0" }, - { 7946, "IPI_MASK_SET_0" }, - { 8192, "MPL_PERF_COUNT_SET_0" }, - { 8193, "MPL_PERF_COUNT_SET_1" }, - { 8194, "MPL_PERF_COUNT_SET_2" }, - { 8195, "MPL_PERF_COUNT_SET_3" }, - { 8196, "MPL_PERF_COUNT" }, - { 8197, "PERF_COUNT_0" }, - { 8198, "PERF_COUNT_1" }, - { 8199, "PERF_COUNT_CTL" }, - { 8200, "PERF_COUNT_DN_CTL" }, - { 8201, "PERF_COUNT_STS" }, - { 8202, "WATCH_MASK" }, - { 8203, "WATCH_VAL" }, - { 8448, "MPL_AUX_PERF_COUNT_SET_0" }, - { 8449, "MPL_AUX_PERF_COUNT_SET_1" }, - { 8450, "MPL_AUX_PERF_COUNT_SET_2" }, - { 8451, "MPL_AUX_PERF_COUNT_SET_3" }, - { 8452, "MPL_AUX_PERF_COUNT" }, - { 8453, "AUX_PERF_COUNT_0" }, - { 8454, "AUX_PERF_COUNT_1" }, - { 8455, "AUX_PERF_COUNT_CTL" }, - { 8456, "AUX_PERF_COUNT_STS" }, - { 8704, "MPL_INTCTRL_3_SET_0" }, - { 8705, "MPL_INTCTRL_3_SET_1" }, - { 8706, "MPL_INTCTRL_3_SET_2" }, - { 8707, "MPL_INTCTRL_3_SET_3" }, - { 8708, "MPL_INTCTRL_3" }, - { 8709, "INTCTRL_3_STATUS" }, - { 8710, "INTERRUPT_MASK_3" }, - { 8711, "INTERRUPT_MASK_RESET_3" }, - { 8712, "INTERRUPT_MASK_SET_3" }, - { 8713, "INTERRUPT_VECTOR_BASE_3" }, - { 8714, "SINGLE_STEP_EN_0_3" }, - { 8715, "SINGLE_STEP_EN_1_3" }, - { 8716, "SINGLE_STEP_EN_2_3" }, - { 8717, "SINGLE_STEP_EN_3_3" }, - { 8832, "EX_CONTEXT_3_0" }, - { 8833, "EX_CONTEXT_3_1" }, - { 8834, "SYSTEM_SAVE_3_0" }, - { 8835, "SYSTEM_SAVE_3_1" }, - { 8836, "SYSTEM_SAVE_3_2" }, - { 8837, "SYSTEM_SAVE_3_3" }, - { 8960, "MPL_INTCTRL_2_SET_0" }, - { 8961, "MPL_INTCTRL_2_SET_1" }, - { 8962, "MPL_INTCTRL_2_SET_2" }, - { 8963, "MPL_INTCTRL_2_SET_3" }, - { 8964, "MPL_INTCTRL_2" }, - { 8965, "INTCTRL_2_STATUS" }, - { 8966, "INTERRUPT_MASK_2" }, - { 8967, "INTERRUPT_MASK_RESET_2" }, - { 8968, "INTERRUPT_MASK_SET_2" }, - { 8969, "INTERRUPT_VECTOR_BASE_2" }, - { 8970, "SINGLE_STEP_EN_0_2" }, - { 8971, "SINGLE_STEP_EN_1_2" }, - { 8972, "SINGLE_STEP_EN_2_2" }, - { 8973, "SINGLE_STEP_EN_3_2" }, - { 9088, "EX_CONTEXT_2_0" }, - { 9089, "EX_CONTEXT_2_1" }, - { 9090, "SYSTEM_SAVE_2_0" }, - { 9091, "SYSTEM_SAVE_2_1" }, - { 9092, "SYSTEM_SAVE_2_2" }, - { 9093, "SYSTEM_SAVE_2_3" }, - { 9216, "MPL_INTCTRL_1_SET_0" }, - { 9217, "MPL_INTCTRL_1_SET_1" }, - { 9218, "MPL_INTCTRL_1_SET_2" }, - { 9219, "MPL_INTCTRL_1_SET_3" }, - { 9220, "MPL_INTCTRL_1" }, - { 9221, "INTCTRL_1_STATUS" }, - { 9222, "INTERRUPT_MASK_1" }, - { 9223, "INTERRUPT_MASK_RESET_1" }, - { 9224, "INTERRUPT_MASK_SET_1" }, - { 9225, "INTERRUPT_VECTOR_BASE_1" }, - { 9226, "SINGLE_STEP_EN_0_1" }, - { 9227, "SINGLE_STEP_EN_1_1" }, - { 9228, "SINGLE_STEP_EN_2_1" }, - { 9229, "SINGLE_STEP_EN_3_1" }, - { 9344, "EX_CONTEXT_1_0" }, - { 9345, "EX_CONTEXT_1_1" }, - { 9346, "SYSTEM_SAVE_1_0" }, - { 9347, "SYSTEM_SAVE_1_1" }, - { 9348, "SYSTEM_SAVE_1_2" }, - { 9349, "SYSTEM_SAVE_1_3" }, - { 9472, "MPL_INTCTRL_0_SET_0" }, - { 9473, "MPL_INTCTRL_0_SET_1" }, - { 9474, "MPL_INTCTRL_0_SET_2" }, - { 9475, "MPL_INTCTRL_0_SET_3" }, - { 9476, "MPL_INTCTRL_0" }, - { 9477, "INTCTRL_0_STATUS" }, - { 9478, "INTERRUPT_MASK_0" }, - { 9479, "INTERRUPT_MASK_RESET_0" }, - { 9480, "INTERRUPT_MASK_SET_0" }, - { 9481, "INTERRUPT_VECTOR_BASE_0" }, - { 9482, "SINGLE_STEP_EN_0_0" }, - { 9483, "SINGLE_STEP_EN_1_0" }, - { 9484, "SINGLE_STEP_EN_2_0" }, - { 9485, "SINGLE_STEP_EN_3_0" }, - { 9600, "EX_CONTEXT_0_0" }, - { 9601, "EX_CONTEXT_0_1" }, - { 9602, "SYSTEM_SAVE_0_0" }, - { 9603, "SYSTEM_SAVE_0_1" }, - { 9604, "SYSTEM_SAVE_0_2" }, - { 9605, "SYSTEM_SAVE_0_3" }, - { 9728, "MPL_BOOT_ACCESS_SET_0" }, - { 9729, "MPL_BOOT_ACCESS_SET_1" }, - { 9730, "MPL_BOOT_ACCESS_SET_2" }, - { 9731, "MPL_BOOT_ACCESS_SET_3" }, - { 9732, "MPL_BOOT_ACCESS" }, - { 9733, "BIG_ENDIAN_CONFIG" }, - { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" }, - { 9735, "CACHE_INVALIDATION_MASK_0" }, - { 9736, "CACHE_INVALIDATION_MASK_1" }, - { 9737, "CACHE_INVALIDATION_MASK_2" }, - { 9738, "CBOX_CACHEASRAM_CONFIG" }, - { 9739, "CBOX_CACHE_CONFIG" }, - { 9740, "CBOX_HOME_MAP_ADDR" }, - { 9741, "CBOX_HOME_MAP_DATA" }, - { 9742, "CBOX_MMAP_0" }, - { 9743, "CBOX_MMAP_1" }, - { 9744, "CBOX_MMAP_2" }, - { 9745, "CBOX_MMAP_3" }, - { 9746, "CBOX_MSR" }, - { 9747, "DIAG_BCST_CTL" }, - { 9748, "DIAG_BCST_MASK" }, - { 9749, "DIAG_BCST_TRIGGER" }, - { 9750, "DIAG_MUX_CTL" }, - { 9751, "DIAG_TRACE_CTL" }, - { 9752, "DIAG_TRACE_DATA" }, - { 9753, "DIAG_TRACE_STS" }, - { 9754, "IDN_DEMUX_BUF_THRESH" }, - { 9755, "L1_I_PIN_WAY_0" }, - { 9756, "MEM_ROUTE_ORDER" }, - { 9757, "MEM_STRIPE_CONFIG" }, - { 9758, "PERF_COUNT_PLS" }, - { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" }, - { 9760, "QUIESCE_CTL" }, - { 9761, "RSHIM_COORD" }, - { 9762, "SBOX_CONFIG" }, - { 9763, "UDN_DEMUX_BUF_THRESH" }, - { 9764, "XDN_CORE_STARVATION_COUNT" }, - { 9765, "XDN_ROUND_ROBIN_ARB_CTL" }, - { 9856, "CYCLE_MODIFY" }, - { 9857, "I_AAR" }, - { 9984, "MPL_WORLD_ACCESS_SET_0" }, - { 9985, "MPL_WORLD_ACCESS_SET_1" }, - { 9986, "MPL_WORLD_ACCESS_SET_2" }, - { 9987, "MPL_WORLD_ACCESS_SET_3" }, - { 9988, "MPL_WORLD_ACCESS" }, - { 9989, "DONE" }, - { 9990, "DSTREAM_PF" }, - { 9991, "FAIL" }, - { 9992, "INTERRUPT_CRITICAL_SECTION" }, - { 9993, "PASS" }, - { 9994, "PSEUDO_RANDOM_NUMBER" }, - { 9995, "TILE_COORD" }, - { 9996, "TILE_RTF_HWM" }, - { 10112, "CMPEXCH_VALUE" }, - { 10113, "CYCLE" }, - { 10114, "EVENT_BEGIN" }, - { 10115, "EVENT_END" }, - { 10116, "PROC_STATUS" }, - { 10117, "SIM_CONTROL" }, - { 10118, "SIM_SOCKET" }, - { 10119, "STATUS_SATURATE" }, - { 10240, "MPL_I_ASID_SET_0" }, - { 10241, "MPL_I_ASID_SET_1" }, - { 10242, "MPL_I_ASID_SET_2" }, - { 10243, "MPL_I_ASID_SET_3" }, - { 10244, "MPL_I_ASID" }, - { 10245, "I_ASID" }, - { 10496, "MPL_D_ASID_SET_0" }, - { 10497, "MPL_D_ASID_SET_1" }, - { 10498, "MPL_D_ASID_SET_2" }, - { 10499, "MPL_D_ASID_SET_3" }, - { 10500, "MPL_D_ASID" }, - { 10501, "D_ASID" }, - { 10752, "MPL_DOUBLE_FAULT_SET_0" }, - { 10753, "MPL_DOUBLE_FAULT_SET_1" }, - { 10754, "MPL_DOUBLE_FAULT_SET_2" }, - { 10755, "MPL_DOUBLE_FAULT_SET_3" }, - { 10756, "MPL_DOUBLE_FAULT" }, - { 10757, "LAST_INTERRUPT_REASON" }, -}; - -const int tilegx_num_sprs = 441; - -const char * -get_tilegx_spr_name (int num) -{ - void *result; - struct tilegx_spr key; - - key.number = num; - result = bsearch((const void *) &key, (const void *) tilegx_sprs, - tilegx_num_sprs, sizeof (struct tilegx_spr), - tilegx_spr_compare); - - if (result == NULL) - { - return (NULL); - } - else - { - struct tilegx_spr *result_ptr = (struct tilegx_spr *) result; - return (result_ptr->name); - } -} - -int -print_insn_tilegx (unsigned char * memaddr) -{ - struct tilegx_decoded_instruction - decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; - unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES]; - int i, num_instructions, num_printed; - tilegx_mnemonic padding_mnemonic; - - memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES); - - /* Parse the instructions in the bundle. */ - num_instructions = - parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded); - - /* Print the instructions in the bundle. */ - printf("{ "); - num_printed = 0; - - /* Determine which nop opcode is used for padding and should be skipped. */ - padding_mnemonic = TILEGX_OPC_FNOP; - for (i = 0; i < num_instructions; i++) - { - if (!decoded[i].opcode->can_bundle) - { - /* Instructions that cannot be bundled are padded out with nops, - rather than fnops. Displaying them is always clutter. */ - padding_mnemonic = TILEGX_OPC_NOP; - break; - } - } - - for (i = 0; i < num_instructions; i++) - { - const struct tilegx_opcode *opcode = decoded[i].opcode; - const char *name; - int j; - - /* Do not print out fnops, unless everything is an fnop, in - which case we will print out just the last one. */ - if (opcode->mnemonic == padding_mnemonic - && (num_printed > 0 || i + 1 < num_instructions)) - continue; - - if (num_printed > 0) - printf(" ; "); - ++num_printed; - - name = opcode->name; - if (name == NULL) - name = ""; - printf("%s", name); - - for (j = 0; j < opcode->num_operands; j++) - { - unsigned long long num; - const struct tilegx_operand *op; - const char *spr_name; - - if (j > 0) - printf (","); - printf (" "); - - num = decoded[i].operand_values[j]; - - op = decoded[i].operands[j]; - switch (op->type) - { - case TILEGX_OP_TYPE_REGISTER: - printf ("%s", tilegx_register_names[(int)num]); - break; - case TILEGX_OP_TYPE_SPR: - spr_name = get_tilegx_spr_name(num); - if (spr_name != NULL) - printf ("%s", spr_name); - else - printf ("%d", (int)num); - break; - case TILEGX_OP_TYPE_IMMEDIATE: - printf ("%d", (int)num); - break; - case TILEGX_OP_TYPE_ADDRESS: - printf ("0x%016llx", num); - break; - default: - abort (); - } - } - } - printf (" }\n"); - - return TILEGX_BUNDLE_SIZE_IN_BYTES; -} diff --git a/pcre2/src/sljit/sljitNativeTILEGX_64.c b/pcre2/src/sljit/sljitNativeTILEGX_64.c deleted file mode 100644 index 4d40392fa..000000000 --- a/pcre2/src/sljit/sljitNativeTILEGX_64.c +++ /dev/null @@ -1,2561 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* TileGX architecture. */ -/* Contributed by Tilera Corporation. */ -#include "sljitNativeTILEGX-encoder.c" - -#define SIMM_8BIT_MAX (0x7f) -#define SIMM_8BIT_MIN (-0x80) -#define SIMM_16BIT_MAX (0x7fff) -#define SIMM_16BIT_MIN (-0x8000) -#define SIMM_17BIT_MAX (0xffff) -#define SIMM_17BIT_MIN (-0x10000) -#define SIMM_32BIT_MAX (0x7fffffff) -#define SIMM_32BIT_MIN (-0x7fffffff - 1) -#define SIMM_48BIT_MAX (0x7fffffff0000L) -#define SIMM_48BIT_MIN (-0x800000000000L) -#define IMM16(imm) ((imm) & 0xffff) - -#define UIMM_16BIT_MAX (0xffff) - -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5) -#define PIC_ADDR_REG TMP_REG2 - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { - 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 -}; - -#define SLJIT_LOCALS_REG_mapped 54 -#define TMP_REG1_mapped 5 -#define TMP_REG2_mapped 16 -#define TMP_REG3_mapped 6 -#define ADDR_TMP_mapped 7 - -/* Flags are keept in volatile registers. */ -#define EQUAL_FLAG 8 -/* And carry flag as well. */ -#define ULESS_FLAG 9 -#define UGREATER_FLAG 10 -#define LESS_FLAG 11 -#define GREATER_FLAG 12 -#define OVERFLOW_FLAG 13 - -#define ZERO 63 -#define RA 55 -#define TMP_EREG1 14 -#define TMP_EREG2 15 - -#define LOAD_DATA 0x01 -#define WORD_DATA 0x00 -#define BYTE_DATA 0x02 -#define HALF_DATA 0x04 -#define INT_DATA 0x06 -#define SIGNED_DATA 0x08 -#define DOUBLE_DATA 0x10 - -/* Separates integer and floating point registers */ -#define GPR_REG 0xf - -#define MEM_MASK 0x1f - -#define WRITE_BACK 0x00020 -#define ARG_TEST 0x00040 -#define ALT_KEEP_CACHE 0x00080 -#define CUMULATIVE_OP 0x00100 -#define LOGICAL_OP 0x00200 -#define IMM_OP 0x00400 -#define SRC2_IMM 0x00800 - -#define UNUSED_DEST 0x01000 -#define REG_DEST 0x02000 -#define REG1_SOURCE 0x04000 -#define REG2_SOURCE 0x08000 -#define SLOW_SRC1 0x10000 -#define SLOW_SRC2 0x20000 -#define SLOW_DEST 0x40000 - -/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. - */ -#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void) -{ - return "TileGX" SLJIT_CPUINFO; -} - -/* Length of an instruction word */ -typedef sljit_uw sljit_ins; - -struct jit_instr { - const struct tilegx_opcode* opcode; - tilegx_pipeline pipe; - unsigned long input_registers; - unsigned long output_registers; - int operand_value[4]; - int line; -}; - -/* Opcode Helper Macros */ -#define TILEGX_X_MODE 0 - -#define X_MODE create_Mode(TILEGX_X_MODE) - -#define FNOP_X0 \ - create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) - -#define FNOP_X1 \ - create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1) - -#define NOP \ - create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1 - -#define ANOP_X0 \ - create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0) - -#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \ - create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0 - -#define ADD_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0 - -#define ADDI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0 - -#define SUB_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0 - -#define NOR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define OR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define AND_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0 - -#define XOR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define CMOVNEZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1 - -#define CMOVEQZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1 - -#define ADDLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0 - -#define V4INT_L_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0 - -#define BFEXTU_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ - create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1 - -#define BFEXTS_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ - create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1 - -#define SHL16INSLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0 - -#define ST_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0 - -#define LD_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0 - -#define JR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0 - -#define JALR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0 - -#define CLZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1 - -#define CMPLTUI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0 - -#define CMPLTU_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0 - -#define CMPLTS_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0 - -#define XORI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0 - -#define ORI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0 - -#define ANDI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0 - -#define SHLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHL_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0 - -#define SHRSI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHRS_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0 - -#define SHRUI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHRU_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0 - -#define BEQZ_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ - create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0 - -#define BNEZ_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ - create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0 - -#define J_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ - create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0 - -#define JAL_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ - create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0 - -#define DEST_X0(x) create_Dest_X0(x) -#define SRCA_X0(x) create_SrcA_X0(x) -#define SRCB_X0(x) create_SrcB_X0(x) -#define DEST_X1(x) create_Dest_X1(x) -#define SRCA_X1(x) create_SrcA_X1(x) -#define SRCB_X1(x) create_SrcB_X1(x) -#define IMM16_X1(x) create_Imm16_X1(x) -#define IMM8_X1(x) create_Imm8_X1(x) -#define BFSTART_X0(x) create_BFStart_X0(x) -#define BFEND_X0(x) create_BFEnd_X0(x) -#define SHIFTIMM_X1(x) create_ShAmt_X1(x) -#define JOFF_X1(x) create_JumpOff_X1(x) -#define BOFF_X1(x) create_BrOff_X1(x) - -static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { - /* u w s */ TILEGX_OPC_ST /* st */, - /* u w l */ TILEGX_OPC_LD /* ld */, - /* u b s */ TILEGX_OPC_ST1 /* st1 */, - /* u b l */ TILEGX_OPC_LD1U /* ld1u */, - /* u h s */ TILEGX_OPC_ST2 /* st2 */, - /* u h l */ TILEGX_OPC_LD2U /* ld2u */, - /* u i s */ TILEGX_OPC_ST4 /* st4 */, - /* u i l */ TILEGX_OPC_LD4U /* ld4u */, - /* s w s */ TILEGX_OPC_ST /* st */, - /* s w l */ TILEGX_OPC_LD /* ld */, - /* s b s */ TILEGX_OPC_ST1 /* st1 */, - /* s b l */ TILEGX_OPC_LD1S /* ld1s */, - /* s h s */ TILEGX_OPC_ST2 /* st2 */, - /* s h l */ TILEGX_OPC_LD2S /* ld2s */, - /* s i s */ TILEGX_OPC_ST4 /* st4 */, - /* s i l */ TILEGX_OPC_LD4S /* ld4s */, -}; - -#ifdef TILEGX_JIT_DEBUG -static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - printf("|%04d|S0|:\t\t", line); - print_insn_tilegx(ptr); - return SLJIT_SUCCESS; -} - -static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} - -#define push_inst(a, b) push_inst_debug(a, b, __LINE__) -#else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} -#endif - -#define BUNDLE_FORMAT_MASK(p0, p1, p2) \ - ((p0) | ((p1) << 8) | ((p2) << 16)) - -#define BUNDLE_FORMAT(p0, p1, p2) \ - { \ - { \ - (tilegx_pipeline)(p0), \ - (tilegx_pipeline)(p1), \ - (tilegx_pipeline)(p2) \ - }, \ - BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \ - } - -#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS - -#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1) - -#define PI(encoding) \ - push_inst(compiler, encoding) - -#define PB3(opcode, dst, srca, srcb) \ - push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__) - -#define PB2(opcode, dst, src) \ - push_2_buffer(compiler, opcode, dst, src, __LINE__) - -#define JR(reg) \ - push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__) - -#define ADD(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__) - -#define SUB(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__) - -#define MUL(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__) - -#define NOR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__) - -#define OR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__) - -#define XOR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__) - -#define AND(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__) - -#define CLZ(dst, src) \ - push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__) - -#define SHLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__) - -#define SHRUI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__) - -#define XORI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__) - -#define ORI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__) - -#define CMPLTU(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__) - -#define CMPLTS(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__) - -#define CMPLTUI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__) - -#define CMOVNEZ(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__) - -#define CMOVEQZ(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__) - -#define ADDLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__) - -#define SHL16INSLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__) - -#define LD_ADD(dst, addr, adjust) \ - push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__) - -#define ST_ADD(src, addr, adjust) \ - push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__) - -#define LD(dst, addr) \ - push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__) - -#define BFEXTU(dst, src, start, end) \ - push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__) - -#define BFEXTS(dst, src, start, end) \ - push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__) - -#define ADD_SOLO(dest, srca, srcb) \ - push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb)) - -#define ADDI_SOLO(dest, srca, imm) \ - push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm)) - -#define ADDLI_SOLO(dest, srca, imm) \ - push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) - -#define SHL16INSLI_SOLO(dest, srca, imm) \ - push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) - -#define JALR_SOLO(reg) \ - push_inst(compiler, JALR_X1 | SRCA_X1(reg)) - -#define JR_SOLO(reg) \ - push_inst(compiler, JR_X1 | SRCA_X1(reg)) - -struct Format { - /* Mapping of bundle issue slot to assigned pipe. */ - tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; - - /* Mask of pipes used by this bundle. */ - unsigned int pipe_mask; -}; - -const struct Format formats[] = -{ - /* In Y format we must always have something in Y2, since it has - * no fnop, so this conveys that Y2 must always be used. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE), - - /* Y format has three instructions. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0), - - /* X format has only two instructions. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE) -}; - - -struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; -unsigned long inst_buf_index; - -tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode) -{ - /* FIXME: tile: we could pregenerate this. */ - int pipe; - for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++) - ; - return (tilegx_pipeline)(pipe); -} - -void insert_nop(tilegx_mnemonic opc, int line) -{ - const struct tilegx_opcode* opcode = NULL; - - memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]); - - opcode = &tilegx_opcodes[opc]; - inst_buf[0].opcode = opcode; - inst_buf[0].pipe = get_any_valid_pipe(opcode); - inst_buf[0].input_registers = 0; - inst_buf[0].output_registers = 0; - inst_buf[0].line = line; - ++inst_buf_index; -} - -const struct Format* compute_format() -{ - unsigned int compatible_pipes = BUNDLE_FORMAT_MASK( - inst_buf[0].opcode->pipes, - inst_buf[1].opcode->pipes, - (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE))); - - const struct Format* match = NULL; - const struct Format *b = NULL; - unsigned int i; - for (i = 0; i < sizeof formats / sizeof formats[0]; i++) { - b = &formats[i]; - if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) { - match = b; - break; - } - } - - return match; -} - -sljit_si assign_pipes() -{ - unsigned long output_registers = 0; - unsigned int i = 0; - - if (inst_buf_index == 1) { - tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle - ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP; - insert_nop(opc, __LINE__); - } - - const struct Format* match = compute_format(); - - if (match == NULL) - return -1; - - for (i = 0; i < inst_buf_index; i++) { - - if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0)) - return -1; - - if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0)) - return -1; - - /* Don't include Rzero in the match set, to avoid triggering - needlessly on 'prefetch' instrs. */ - - output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL; - - inst_buf[i].pipe = match->pipe[i]; - } - - /* If only 2 instrs, and in Y-mode, insert a nop. */ - if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) { - insert_nop(TILEGX_OPC_FNOP, __LINE__); - - /* Select the yet unassigned pipe. */ - tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0 - + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2) - - (inst_buf[1].pipe + inst_buf[2].pipe))); - - inst_buf[0].pipe = pipe; - } - - return 0; -} - -tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) -{ - int i, val; - const struct tilegx_opcode* opcode = inst->opcode; - tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe]; - - const struct tilegx_operand* operand = NULL; - for (i = 0; i < opcode->num_operands; i++) { - operand = &tilegx_operands[opcode->operands[inst->pipe][i]]; - val = inst->operand_value[i]; - - bits |= operand->insert(val); - } - - return bits; -} - -static sljit_si update_buffer(struct sljit_compiler *compiler) -{ - int i; - int orig_index = inst_buf_index; - struct jit_instr inst0 = inst_buf[0]; - struct jit_instr inst1 = inst_buf[1]; - struct jit_instr inst2 = inst_buf[2]; - tilegx_bundle_bits bits = 0; - - /* If the bundle is valid as is, perform the encoding and return 1. */ - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M0|:\t"); - else - printf("|M0|:\t\t"); - print_insn_tilegx(&bits); -#endif - - inst_buf_index = 0; - -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } - - /* If the bundle is invalid, split it in two. First encode the first two - (or possibly 1) instructions, and then the last, separately. Note that - assign_pipes may have re-ordered the instrs (by inserting no-ops in - lower slots) so we need to reset them. */ - - inst_buf_index = orig_index - 1; - inst_buf[0] = inst0; - inst_buf[1] = inst1; - inst_buf[2] = inst2; - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } - -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M1|:\t"); - else - printf("|M1|:\t\t"); - print_insn_tilegx(&bits); -#endif - - if ((orig_index - 1) == 2) { - inst_buf[0] = inst2; - inst_buf_index = 1; - } else if ((orig_index - 1) == 1) { - inst_buf[0] = inst1; - inst_buf_index = 1; - } else - SLJIT_ASSERT_STOP(); - -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } else { - /* We had 3 instrs of which the first 2 can't live in the same bundle. - Split those two. Note that we don't try to then combine the second - and third instr into a single bundle. First instruction: */ - inst_buf_index = 1; - inst_buf[0] = inst0; - inst_buf[1] = inst1; - inst_buf[2] = inst2; - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } - -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M2|:\t"); - else - printf("|M2|:\t\t"); - print_insn_tilegx(&bits); -#endif - - inst_buf[0] = inst1; - inst_buf[1] = inst2; - inst_buf_index = orig_index - 1; -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } else - SLJIT_ASSERT_STOP(); - } - - SLJIT_ASSERT_STOP(); -} - -static sljit_si flush_buffer(struct sljit_compiler *compiler) -{ - while (inst_buf_index != 0) { - FAIL_IF(update_buffer(compiler)); - } - return SLJIT_SUCCESS; -} - -static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].operand_value[2] = op2; - inst_buf[inst_buf_index].operand_value[3] = op3; - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].operand_value[2] = op2; - inst_buf[inst_buf_index].line = line; - - switch (opc) { - case TILEGX_OPC_ST_ADD: - inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - case TILEGX_OPC_LD_ADD: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1); - break; - case TILEGX_OPC_ADD: - case TILEGX_OPC_AND: - case TILEGX_OPC_SUB: - case TILEGX_OPC_MULX: - case TILEGX_OPC_OR: - case TILEGX_OPC_XOR: - case TILEGX_OPC_NOR: - case TILEGX_OPC_SHL: - case TILEGX_OPC_SHRU: - case TILEGX_OPC_SHRS: - case TILEGX_OPC_CMPLTU: - case TILEGX_OPC_CMPLTS: - case TILEGX_OPC_CMOVEQZ: - case TILEGX_OPC_CMOVNEZ: - inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2); - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - case TILEGX_OPC_ADDLI: - case TILEGX_OPC_XORI: - case TILEGX_OPC_ORI: - case TILEGX_OPC_SHLI: - case TILEGX_OPC_SHRUI: - case TILEGX_OPC_SHRSI: - case TILEGX_OPC_SHL16INSLI: - case TILEGX_OPC_CMPLTUI: - case TILEGX_OPC_CMPLTSI: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - default: - printf("unrecoginzed opc: %s\n", opcode->name); - SLJIT_ASSERT_STOP(); - } - - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].line = line; - - switch (opc) { - case TILEGX_OPC_BEQZ: - case TILEGX_OPC_BNEZ: - inst_buf[inst_buf_index].input_registers = 1L << op0; - break; - case TILEGX_OPC_ST: - case TILEGX_OPC_ST1: - case TILEGX_OPC_ST2: - case TILEGX_OPC_ST4: - inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); - inst_buf[inst_buf_index].output_registers = 0; - break; - case TILEGX_OPC_CLZ: - case TILEGX_OPC_LD: - case TILEGX_OPC_LD1U: - case TILEGX_OPC_LD1S: - case TILEGX_OPC_LD2U: - case TILEGX_OPC_LD2S: - case TILEGX_OPC_LD4U: - case TILEGX_OPC_LD4S: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - default: - printf("unrecoginzed opc: %s\n", opcode->name); - SLJIT_ASSERT_STOP(); - } - - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].input_registers = 0; - inst_buf[inst_buf_index].output_registers = 0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].input_registers = 1L << op0; - inst_buf[inst_buf_index].output_registers = 0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return flush_buffer(compiler); -} - -static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - sljit_ins *inst; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return code_ptr; - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - - inst = (sljit_ins *)jump->addr; - if (jump->flags & IS_COND) - inst--; - - diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3; - if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) { - jump->flags |= PATCH_B; - - if (!(jump->flags & IS_COND)) { - if (jump->flags & IS_JAL) { - jump->flags &= ~(PATCH_B); - jump->flags |= PATCH_J; - inst[0] = JAL_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } else { - inst[0] = BEQZ_X1 | SRCA_X1(ZERO); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } - - return inst; - } - - inst[0] = inst[0] ^ (0x7L << 55); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - jump->addr -= sizeof(sljit_ins); - return inst; - } - - if (jump->flags & IS_COND) { - if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { - jump->flags |= PATCH_J; - inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2); - inst[1] = J_X1; - return inst + 1; - } - - return code_ptr; - } - - if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { - jump->flags |= PATCH_J; - - if (jump->flags & IS_JAL) { - inst[0] = JAL_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - - } else { - inst[0] = J_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } - - return inst; - } - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = (sljit_ins *)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 3); - do { - *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw) code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - if (jump && jump->addr == word_count) { - if (jump->flags & IS_JAL) - jump->addr = (sljit_uw)(code_ptr - 4); - else - jump->addr = (sljit_uw)(code_ptr - 3); - - code_ptr = detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw) code_ptr; - const_ = const_->next; - } - - code_ptr++; - word_count++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw) code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins *)jump->addr; - - if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - (jump->addr)) >> 3; - SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN); - buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(buf_ptr); -#endif - break; - } - - if (jump->flags & PATCH_J) { - SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)); - addr = (sljit_sw)(addr - (jump->addr)) >> 3; - buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(buf_ptr); -#endif - break; - } - - SLJIT_ASSERT(!(jump->flags & IS_JAL)); - - /* Set the fields of immediate loads. */ - buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43); - buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43); - buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43); - } while (0); - - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); - return code; -} - -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) -{ - - if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) - return ADDLI(dst_ar, ZERO, imm); - - if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) { - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); - } - - if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) { - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); - } - - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); -} - -static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) -{ - /* Should *not* be optimized as load_immediate, as pcre relocation - mechanism will match this fixed 4-instruction pattern. */ - if (flush) { - FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI_SOLO(dst_ar, dst_ar, imm); - } - - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); -} - -static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) -{ - /* Should *not* be optimized as load_immediate, as pcre relocation - mechanism will match this fixed 4-instruction pattern. */ - if (flush) { - FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); - FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); - return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm); - } - - FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); - FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); - return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_ins base; - sljit_si i, tmp; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - local_size = (local_size + 7) & ~7; - compiler->local_size = local_size; - - if (local_size <= SIMM_16BIT_MAX) { - /* Frequent case. */ - FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size)); - base = SLJIT_LOCALS_REG_mapped; - } else { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); - FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO)); - FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); - base = TMP_REG2_mapped; - local_size = 0; - } - - /* Save the return address. */ - FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); - FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8)); - - /* Save the S registers. */ - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); - } - - /* Save the R registers that need to be reserved. */ - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); - } - - /* Move the arguments to S registers. */ - for (i = 0; i < args; i++) { - FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO)); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - compiler->local_size = (local_size + 7) & ~7; - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si local_size; - sljit_ins base; - sljit_si i, tmp; - sljit_si saveds; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - local_size = compiler->local_size; - if (local_size <= SIMM_16BIT_MAX) - base = SLJIT_LOCALS_REG_mapped; - else { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); - FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); - base = TMP_REG1_mapped; - local_size = 0; - } - - /* Restore the return address. */ - FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); - FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8)); - - /* Restore the S registers. */ - saveds = compiler->saveds; - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); - } - - /* Restore the R registers that need to be reserved. */ - for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); - } - - if (compiler->local_size <= SIMM_16BIT_MAX) - FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size)); - else - FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO)); - - return JR(RA); -} - -/* reg_ar is an absoulute register! */ - -/* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) -{ - SLJIT_ASSERT(arg & SLJIT_MEM); - - if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) - && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - /* Works for both absoulte and relative addresses. */ - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw)); - - if (flags & LOAD_DATA) - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); - else - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); - - return -1; - } - - return 0; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - - /* Simple operation except for updates. */ - if (arg & OFFS_REG_MASK) { - argw &= 0x3; - next_argw &= 0x3; - if (argw && argw == next_argw - && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) - return 1; - return 0; - } - - if (arg == next_arg) { - if (((next_argw - argw) <= SIMM_16BIT_MAX - && (next_argw - argw) >= SIMM_16BIT_MIN)) - return 1; - - return 0; - } - - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) -{ - sljit_si tmp_ar, base; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) - tmp_ar = reg_ar; - else - tmp_ar = TMP_REG1_mapped; - - base = arg & REG_MASK; - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - - if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar); - FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); - reg_ar = TMP_REG1_mapped; - } - - /* Using the cache. */ - if (argw == compiler->cache_argw) { - if (!(flags & WRITE_BACK)) { - if (arg == compiler->cache_arg) { - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); - } - } else { - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - } - } - - if (SLJIT_UNLIKELY(argw)) { - compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); - compiler->cache_argw = argw; - FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw)); - } - - if (!(flags & WRITE_BACK)) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - tmp_ar = TMP_REG3_mapped; - } else - FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); - } - - FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - - if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { - /* Update only applies if a base register exists. */ - if (reg_ar == reg_map[base]) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar); - if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw)); - if (flags & LOAD_DATA) - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); - else - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); - - if (argw) - return ADDLI(reg_map[base], reg_map[base], argw); - - return SLJIT_SUCCESS; - } - - FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); - reg_ar = TMP_REG1_mapped; - } - - if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - if (argw) - FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw)); - } else { - if (compiler->cache_arg == SLJIT_MEM - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - compiler->cache_argw = argw; - } - - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - } else { - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - } - } - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - - if (compiler->cache_arg == arg - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - compiler->cache_argw = argw; - } - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if (compiler->cache_arg == SLJIT_MEM - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) - FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - } else { - compiler->cache_arg = SLJIT_MEM; - FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); - } - - compiler->cache_argw = argw; - - if (!base) { - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if (arg == next_arg - && next_argw - argw <= SIMM_16BIT_MAX - && next_argw - argw >= SIMM_16BIT_MIN) { - compiler->cache_arg = arg; - FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base])); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); -} - -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) - return compiler->error; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return ADD(reg_map[dst], RA, ZERO); - - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(ADD(RA, reg_map[src], ZERO)); - - else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw)); - - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, RA, srcw)); - - return JR(RA); -} - -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) -{ - sljit_si overflow_ra = 0; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return ADD(reg_map[dst], reg_map[src2], ZERO); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2])); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2])); - - return SLJIT_SUCCESS; - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2])); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(CLZ(reg_map[dst], reg_map[src2])); - - return SLJIT_SUCCESS; - - case SLJIT_ADD: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63)); - if (src2 < 0) - FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2)); - - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2)); - else { - FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2)); - FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG)); - } - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); - - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63)); - - if (src2 < 0) - FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1)); - } - } else { - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); - FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else if (src2 != dst) - overflow_ra = reg_map[src2]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_C) - FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2])); - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra)); - FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); - } - } - - /* a + b >= a | b (otherwise, the carry should be set to 1). */ - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG)); - - if (op & SLJIT_SET_O) - return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); - - return SLJIT_SUCCESS; - - case SLJIT_ADDC: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2)); - else { - FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2)); - FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1)); - } - } - - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); - - } else { - if (op & SLJIT_SET_C) - FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2])); - - /* dst may be the same as src1 or src2. */ - FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1)); - - FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG)); - - if (!(op & SLJIT_SET_C)) - return SLJIT_SUCCESS; - - /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ - FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1)); - FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG)); - /* Set carry flag. */ - return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1); - - case SLJIT_SUB: - if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) { - FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63)); - - if (src2 < 0) - FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2)); - - if (op & SLJIT_SET_C) { - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); - FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped)); - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); - - } else { - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); - FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2])); - - if (op & (SLJIT_SET_U | SLJIT_SET_C)) - FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_U) - FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1])); - - if (op & SLJIT_SET_S) { - FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2])); - FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1])); - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) - FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra)); - FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); - return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_SUBC: - if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) { - FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2)); - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped)); - } - - /* dst may be the same as src1 or src2. */ - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); - - } else { - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2])); - /* dst may be the same as src1 or src2. */ - FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_C) - FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG)); - - FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG)); - - if (op & SLJIT_SET_C) - FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO)); - - return SLJIT_SUCCESS; - - case SLJIT_MUL: - if (flags & SRC2_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2])); - - return SLJIT_SUCCESS; - -#define EMIT_LOGICAL(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - ADDR_TMP_mapped, __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - ADDR_TMP_mapped, __LINE__)); \ - } else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - reg_map[src2], __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - reg_map[src2], __LINE__)); \ - } - - case SLJIT_AND: - EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND); - return SLJIT_SUCCESS; - - case SLJIT_OR: - EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR); - return SLJIT_SUCCESS; - - case SLJIT_XOR: - EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR); - return SLJIT_SUCCESS; - -#define EMIT_SHIFT(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_imm, EQUAL_FLAG, reg_map[src1], \ - src2 & 0x3F, __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_imm, reg_map[dst], reg_map[src1], \ - src2 & 0x3F, __LINE__)); \ - } else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - reg_map[src2], __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - reg_map[src2], __LINE__)); \ - } - - case SLJIT_SHL: - EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL); - return SLJIT_SUCCESS; - - case SLJIT_LSHR: - EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU); - return SLJIT_SUCCESS; - - case SLJIT_ASHR: - EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS); - return SLJIT_SUCCESS; - } - - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg. - arg2 goes to TMP_REG2, imm or src reg. - TMP_REG3 can be used for caching. - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; - sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - - if (!(flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } - - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - if (GET_FLAGS(op)) - flags |= UNUSED_DEST; - } else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) - flags |= SLOW_DEST; - - if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w) { - if ((!(flags & LOGICAL_OP) - && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN)) - || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) { - flags |= SRC2_IMM; - src2_r = src2w; - } - } - - if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { - if ((!(flags & LOGICAL_OP) - && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN)) - || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) { - flags |= SRC2_IMM; - src2_r = src1w; - - /* And swap arguments. */ - src1 = src2; - src1w = src2w; - src2 = SLJIT_IMM; - /* src2w = src2_r unneeded. */ - } - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) { - src1_r = src1; - flags |= REG1_SOURCE; - } else if (src1 & SLJIT_IMM) { - if (src1w) { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w)); - src1_r = TMP_REG1; - } else - src1_r = 0; - } else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - src1_r = TMP_REG1; - } - - /* Source 2. */ - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - dst_r = src2_r; - } else if (src2 & SLJIT_IMM) { - if (!(flags & SRC2_IMM)) { - if (src2w) { - FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w)); - src2_r = sugg_src2_r; - } else { - src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) - dst_r = 0; - } - } - } else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - src2_r = sugg_src2_r; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - SLJIT_ASSERT(src2_r == TMP_REG2); - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); - } else { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw)); - } - } else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw)); - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw); - return compiler->error; - } - - return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type) -{ - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - op = GET_OPCODE(op); - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) - mem_type = INT_DATA | SIGNED_DATA; - sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } - - switch (type & 0xff) { - case SLJIT_EQUAL: - case SLJIT_NOT_EQUAL: - FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1)); - dst_ar = sugg_dst_ar; - break; - case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: - dst_ar = ULESS_FLAG; - break; - case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: - dst_ar = UGREATER_FLAG; - break; - case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: - dst_ar = LESS_FLAG; - break; - case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: - dst_ar = GREATER_FLAG; - break; - case SLJIT_OVERFLOW: - case SLJIT_NOT_OVERFLOW: - dst_ar = OVERFLOW_FLAG; - break; - case SLJIT_MUL_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1)); - dst_ar = sugg_dst_ar; - type ^= 0x1; /* Flip type bit for the XORI below. */ - break; - - default: - SLJIT_ASSERT_STOP(); - dst_ar = sugg_dst_ar; - break; - } - - if (type & 0x1) { - FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1)); - dst_ar = sugg_dst_ar; - } - - if (op >= SLJIT_ADD) { - if (TMP_REG2_mapped != dst_ar) - FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO)); - return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); - } - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw); - - if (sugg_dst_ar != dst_ar) - return ADD(sugg_dst_ar, dst_ar, ZERO); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_NOP: - return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__); - - case SLJIT_BREAKPOINT: - return PI(BPT); - - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_ASSERT_STOP(); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); - - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); - - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); - - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); - - case SLJIT_MOVU: - case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); - - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); - - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); - - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: - return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); - - case SLJIT_CLZ: - return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - case SLJIT_ADDC: - return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUB: - case SLJIT_SUBC: - return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_MUL: - return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_AND: - case SLJIT_OR: - case SLJIT_XOR: - return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: - if (src2 & SLJIT_IMM) - src2w &= 0x3f; - if (op & SLJIT_INT_OP) - src2w &= 0x1f; - - return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - sljit_si src_r = TMP_REG2; - struct sljit_jump *jump = NULL; - - flush_buffer(compiler); - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) { - if (reg_map[src] != 0) - src_r = src; - else - FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO)); - } - - if (type >= SLJIT_CALL0) { - SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); - if (src & (SLJIT_IMM | SLJIT_MEM)) { - if (src & SLJIT_IMM) - FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1)); - else { - SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - } - - FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - - FAIL_IF(ADDI_SOLO(54, 54, -16)); - - FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG])); - - return ADDI_SOLO(54, 54, 16); - } - - /* Register input. */ - if (type >= SLJIT_CALL1) - FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - - FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO)); - - FAIL_IF(ADDI_SOLO(54, 54, -16)); - - FAIL_IF(JALR_SOLO(reg_map[src_r])); - - return ADDI_SOLO(54, 54, 16); - } - - if (src & SLJIT_IMM) { - jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); - jump->u.target = srcw; - FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); - - if (type >= SLJIT_FAST_CALL) { - FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO)); - jump->addr = compiler->size; - FAIL_IF(JR_SOLO(reg_map[src_r])); - } else { - jump->addr = compiler->size; - FAIL_IF(JR_SOLO(reg_map[src_r])); - } - - return SLJIT_SUCCESS; - - } else if (src & SLJIT_MEM) { - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - flush_buffer(compiler); - } - - FAIL_IF(JR_SOLO(reg_map[src_r])); - - if (jump) - jump->addr = compiler->size; - - return SLJIT_SUCCESS; -} - -#define BR_Z(src) \ - inst = BEQZ_X1 | SRCA_X1(src); \ - flags = IS_COND; - -#define BR_NZ(src) \ - inst = BNEZ_X1 | SRCA_X1(src); \ - flags = IS_COND; - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - struct sljit_jump *jump; - sljit_ins inst; - sljit_si flags = 0; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - switch (type) { - case SLJIT_EQUAL: - BR_NZ(EQUAL_FLAG); - break; - case SLJIT_NOT_EQUAL: - BR_Z(EQUAL_FLAG); - break; - case SLJIT_LESS: - BR_Z(ULESS_FLAG); - break; - case SLJIT_GREATER_EQUAL: - BR_NZ(ULESS_FLAG); - break; - case SLJIT_GREATER: - BR_Z(UGREATER_FLAG); - break; - case SLJIT_LESS_EQUAL: - BR_NZ(UGREATER_FLAG); - break; - case SLJIT_SIG_LESS: - BR_Z(LESS_FLAG); - break; - case SLJIT_SIG_GREATER_EQUAL: - BR_NZ(LESS_FLAG); - break; - case SLJIT_SIG_GREATER: - BR_Z(GREATER_FLAG); - break; - case SLJIT_SIG_LESS_EQUAL: - BR_NZ(GREATER_FLAG); - break; - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - BR_Z(OVERFLOW_FLAG); - break; - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - BR_NZ(OVERFLOW_FLAG); - break; - default: - /* Not conditional branch. */ - inst = 0; - break; - } - - jump->flags |= flags; - - if (inst) { - inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6)); - PTR_FAIL_IF(PI(inst)); - } - - PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); - if (type <= SLJIT_JUMP) { - jump->addr = compiler->size; - PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped)); - } else { - SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); - /* Cannot be optimized out if type is >= CALL0. */ - jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); - PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - jump->addr = compiler->size; - PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped)); - } - - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) -{ - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) -{ - SLJIT_ASSERT_STOP(); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_si reg; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ - sljit_ins *inst = (sljit_ins *)addr; - - inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43); - inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43); - inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43); - SLJIT_CACHE_FLUSH(inst, inst + 3); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins *)addr; - - inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43); - inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43); - inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43); - inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - return SLJIT_ERR_UNSUPPORTED; -} - diff --git a/pcre2/src/sljit/sljitNativeX86_32.c b/pcre2/src/sljit/sljitNativeX86_32.c deleted file mode 100644 index d7129c8e2..000000000 --- a/pcre2/src/sljit/sljitNativeX86_32.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* x86 32-bit arch dependent functions. */ - -static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) -{ - sljit_ub *inst; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); - FAIL_IF(!inst); - INC_SIZE(1 + sizeof(sljit_sw)); - *inst++ = opcode; - *(sljit_sw*)inst = imm; - return SLJIT_SUCCESS; -} - -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) -{ - if (type == SLJIT_JUMP) { - *code_ptr++ = JMP_i32; - jump->addr++; - } - else if (type >= SLJIT_FAST_CALL) { - *code_ptr++ = CALL_i32; - jump->addr++; - } - else { - *code_ptr++ = GROUP_0F; - *code_ptr++ = get_jump_code(type); - jump->addr += 2; - } - - if (jump->flags & JUMP_LABEL) - jump->flags |= PATCH_MW; - else - *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4); - code_ptr += 4; - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si size; - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - compiler->args = args; - compiler->flags_saved = 0; - - size = 1 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3); -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0); -#else - size += (args > 0 ? (2 + args * 3) : 0); -#endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - - INC_SIZE(size); - PUSH_REG(reg_map[TMP_REG1]); -#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */; - } -#endif - if (saveds > 2 || scratches > 7) - PUSH_REG(reg_map[SLJIT_S2]); - if (saveds > 1 || scratches > 8) - PUSH_REG(reg_map[SLJIT_S1]); - if (saveds > 0 || scratches > 9) - PUSH_REG(reg_map[SLJIT_S0]); - -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2]; - } - if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1]; - } - if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */; - *inst++ = 0x24; - *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ - } -#else - if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 2; - } - if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 3; - } - if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 4; - } -#endif - - SLJIT_COMPILE_ASSERT(SLJIT_LOCALS_OFFSET >= (2 + 4) * sizeof(sljit_uw), require_at_least_two_words); -#if defined(__APPLE__) - /* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */ - saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); - local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds; -#else - if (options & SLJIT_DOUBLE_ALIGNMENT) { - local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 17); - FAIL_IF(!inst); - - INC_SIZE(17); - inst[0] = MOV_r_rm; - inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP]; - inst[2] = GROUP_F7; - inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP]; - *(sljit_sw*)(inst + 4) = 0x4; - inst[8] = JNE_i8; - inst[9] = 6; - inst[10] = GROUP_BINARY_81; - inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP]; - *(sljit_sw*)(inst + 12) = 0x4; - inst[16] = PUSH_r + reg_map[TMP_REG1]; - } - else - local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3); -#endif - - compiler->local_size = local_size; -#ifdef _WIN32 - if (local_size > 1024) { -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); -#else - local_size -= SLJIT_LOCALS_OFFSET; - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); - FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, - SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, SLJIT_LOCALS_OFFSET)); -#endif - FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); - } -#endif - - SLJIT_ASSERT(local_size > 0); - return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, - SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - compiler->args = args; - -#if defined(__APPLE__) - saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); - compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds; -#else - if (options & SLJIT_DOUBLE_ALIGNMENT) - compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); - else - compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3); -#endif - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si size; - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - SLJIT_ASSERT(compiler->args >= 0); - - compiler->flags_saved = 0; - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - SLJIT_ASSERT(compiler->local_size > 0); - FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, - SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size)); - -#if !defined(__APPLE__) - if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - - INC_SIZE(3); - inst[0] = MOV_r_rm; - inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */; - inst[2] = (4 << 3) | reg_map[SLJIT_SP]; - } -#endif - - size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) + - (compiler->saveds <= 3 ? compiler->saveds : 3); -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (compiler->args > 2) - size += 2; -#else - if (compiler->args > 0) - size += 2; -#endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - - INC_SIZE(size); - - if (compiler->saveds > 0 || compiler->scratches > 9) - POP_REG(reg_map[SLJIT_S0]); - if (compiler->saveds > 1 || compiler->scratches > 8) - POP_REG(reg_map[SLJIT_S1]); - if (compiler->saveds > 2 || compiler->scratches > 7) - POP_REG(reg_map[SLJIT_S2]); - POP_REG(reg_map[TMP_REG1]); -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (compiler->args > 2) - RET_I16(sizeof(sljit_sw)); - else - RET(); -#else - RET(); -#endif - - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -/* Size contains the flags as well. */ -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, - /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, - /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) -{ - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_si flags = size & ~0xf; - sljit_si inst_size; - - /* Both cannot be switched on. */ - SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); - /* Size flags not allowed for typed instructions. */ - SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); - /* Both size flags cannot be switched on. */ - SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); - /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); - - size &= 0xf; - inst_size = size; - - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) - inst_size++; - - /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ - if (b & SLJIT_MEM) { - if ((b & REG_MASK) == SLJIT_UNUSED) - inst_size += sizeof(sljit_sw); - else if (immb != 0 && !(b & OFFS_REG_MASK)) { - /* Immediate operand. */ - if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); - else - inst_size += sizeof(sljit_sw); - } - - if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK)) - b |= TO_OFFS_REG(SLJIT_SP); - - if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) - inst_size += 1; /* SIB byte. */ - } - - /* Calculate size of a. */ - if (a & SLJIT_IMM) { - if (flags & EX86_BIN_INS) { - if (imma <= 127 && imma >= -128) { - inst_size += 1; - flags |= EX86_BYTE_ARG; - } else - inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { - imma &= 0x1f; - if (imma != 1) { - inst_size ++; - flags |= EX86_BYTE_ARG; - } - } else if (flags & EX86_BYTE_ARG) - inst_size++; - else if (flags & EX86_HALF_ARG) - inst_size += sizeof(short); - else - inst_size += sizeof(sljit_sw); - } - else - SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); - PTR_FAIL_IF(!inst); - - /* Encoding the byte. */ - INC_SIZE(inst_size); - if (flags & EX86_PREF_F2) - *inst++ = 0xf2; - if (flags & EX86_PREF_F3) - *inst++ = 0xf3; - if (flags & EX86_PREF_66) - *inst++ = 0x66; - - buf_ptr = inst + size; - - /* Encode mod/rm byte. */ - if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) - *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - - if ((a & SLJIT_IMM) || (a == 0)) - *buf_ptr = 0; - else if (!(flags & EX86_SSE2_OP1)) - *buf_ptr = reg_map[a] << 3; - else - *buf_ptr = a << 3; - } - else { - if (a & SLJIT_IMM) { - if (imma == 1) - *inst = GROUP_SHIFT_1; - else - *inst = GROUP_SHIFT_N; - } else - *inst = GROUP_SHIFT_CL; - *buf_ptr = 0; - } - - if (!(b & SLJIT_MEM)) - *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : b); - else if ((b & REG_MASK) != SLJIT_UNUSED) { - if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) { - if (immb != 0) { - if (immb <= 127 && immb >= -128) - *buf_ptr |= 0x40; - else - *buf_ptr |= 0x80; - } - - if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) - *buf_ptr++ |= reg_map[b & REG_MASK]; - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3); - } - - if (immb != 0) { - if (immb <= 127 && immb >= -128) - *buf_ptr++ = immb; /* 8 bit displacement. */ - else { - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_sw); - } - } - } - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6); - } - } - else { - *buf_ptr++ |= 0x05; - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_sw); - } - - if (a & SLJIT_IMM) { - if (flags & EX86_BYTE_ARG) - *buf_ptr = imma; - else if (flags & EX86_HALF_ARG) - *(short*)buf_ptr = imma; - else if (!(flags & EX86_SHIFT_INS)) - *(sljit_sw*)buf_ptr = imma; - } - - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); -} - -/* --------------------------------------------------------------------- */ -/* Call / return instructions */ -/* --------------------------------------------------------------------- */ - -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) -{ - sljit_ub *inst; - -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); - FAIL_IF(!inst); - INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); - - if (type >= SLJIT_CALL3) - PUSH_REG(reg_map[SLJIT_R2]); - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0]; -#else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); - FAIL_IF(!inst); - INC_SIZE(4 * (type - SLJIT_CALL0)); - - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; - *inst++ = 0; - if (type >= SLJIT_CALL2) { - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; - *inst++ = sizeof(sljit_sw); - } - if (type >= SLJIT_CALL3) { - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP]; - *inst++ = 2 * sizeof(sljit_sw); - } -#endif - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - CHECK_EXTRA_REGS(dst, dstw, (void)0); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - dst = TMP_REG1; - - if (FAST_IS_REG(dst)) { - /* Unused dest is possible here. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - - INC_SIZE(1); - POP_REG(reg_map[dst]); - return SLJIT_SUCCESS; - } - - /* Memory. */ - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = POP_rm; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - CHECK_EXTRA_REGS(src, srcw, (void)0); - - if (FAST_IS_REG(src)) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); - FAIL_IF(!inst); - - INC_SIZE(1 + 1); - PUSH_REG(reg_map[src]); - } - else if (src & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - } - else { - /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); - FAIL_IF(!inst); - - INC_SIZE(5 + 1); - *inst++ = PUSH_i32; - *(sljit_sw*)inst = srcw; - inst += sizeof(sljit_sw); - } - - RET(); - return SLJIT_SUCCESS; -} diff --git a/pcre2/src/sljit/sljitNativeX86_64.c b/pcre2/src/sljit/sljitNativeX86_64.c deleted file mode 100644 index 1790d8a4d..000000000 --- a/pcre2/src/sljit/sljitNativeX86_64.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* x86 64-bit arch dependent functions. */ - -static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) -{ - sljit_ub *inst; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); - FAIL_IF(!inst); - INC_SIZE(2 + sizeof(sljit_sw)); - *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); - *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7); - *(sljit_sw*)inst = imm; - return SLJIT_SUCCESS; -} - -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) -{ - if (type < SLJIT_JUMP) { - /* Invert type. */ - *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10; - *code_ptr++ = 10 + 3; - } - - SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first); - *code_ptr++ = REX_W | REX_B; - *code_ptr++ = MOV_r_i32 + 1; - jump->addr = (sljit_uw)code_ptr; - - if (jump->flags & JUMP_LABEL) - jump->flags |= PATCH_MD; - else - *(sljit_sw*)code_ptr = jump->u.target; - - code_ptr += sizeof(sljit_sw); - *code_ptr++ = REX_B; - *code_ptr++ = GROUP_FF; - *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); - - return code_ptr; -} - -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) -{ - sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); - - if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) { - *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; - *(sljit_sw*)code_ptr = delta; - } - else { - SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); - *code_ptr++ = REX_W | REX_B; - *code_ptr++ = MOV_r_i32 + 1; - *(sljit_sw*)code_ptr = addr; - code_ptr += sizeof(sljit_sw); - *code_ptr++ = REX_B; - *code_ptr++ = GROUP_FF; - *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); - } - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si i, tmp, size, saved_register_size; - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - compiler->flags_saved = 0; - - /* Including the return address saved by the call instruction. */ - saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); - if (reg_map[i] >= 8) - *inst++ = REX_B; - PUSH_REG(reg_lmap[i]); - } - - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); - if (reg_map[i] >= 8) - *inst++ = REX_B; - PUSH_REG(reg_lmap[i]); - } - - if (args > 0) { - size = args * 3; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - - INC_SIZE(size); - -#ifndef _WIN64 - if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */; - } - if (args > 1) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */; - } - if (args > 2) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */; - } -#else - if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */; - } - if (args > 1) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */; - } - if (args > 2) { - *inst++ = REX_W | REX_B; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */; - } -#endif - } - - local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size; - compiler->local_size = local_size; - -#ifdef _WIN64 - if (local_size > 1024) { - /* Allocate stack for the callback, which grows the stack. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); - FAIL_IF(!inst); - INC_SIZE(4 + (3 + sizeof(sljit_si))); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | 4; - /* Allocated size for registers must be divisible by 8. */ - SLJIT_ASSERT(!(saved_register_size & 0x7)); - /* Aligned to 16 byte. */ - if (saved_register_size & 0x8) { - *inst++ = 5 * sizeof(sljit_sw); - local_size -= 5 * sizeof(sljit_sw); - } else { - *inst++ = 4 * sizeof(sljit_sw); - local_size -= 4 * sizeof(sljit_sw); - } - /* Second instruction */ - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg); - *inst++ = REX_W; - *inst++ = MOV_rm_i32; - *inst++ = MOD_REG | reg_lmap[SLJIT_R0]; - *(sljit_si*)inst = local_size; -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); - } -#endif - - SLJIT_ASSERT(local_size > 0); - if (local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | 4; - *inst++ = local_size; - } - else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); - FAIL_IF(!inst); - INC_SIZE(7); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_81; - *inst++ = MOD_REG | SUB | 4; - *(sljit_si*)inst = local_size; - inst += sizeof(sljit_si); - } - -#ifdef _WIN64 - /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */ - if (fscratches >= 6 || fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247429; - } -#endif - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) -{ - sljit_si saved_register_size; - - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - /* Including the return address saved by the call instruction. */ - saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - compiler->local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) -{ - sljit_si i, tmp, size; - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - compiler->flags_saved = 0; - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - -#ifdef _WIN64 - /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */ - if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247428; - } -#endif - - SLJIT_ASSERT(compiler->local_size > 0); - if (compiler->local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | ADD | 4; - *inst = compiler->local_size; - } - else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); - FAIL_IF(!inst); - INC_SIZE(7); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_81; - *inst++ = MOD_REG | ADD | 4; - *(sljit_si*)inst = compiler->local_size; - } - - tmp = compiler->scratches; - for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { - size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); - if (reg_map[i] >= 8) - *inst++ = REX_B; - POP_REG(reg_lmap[i]); - } - - tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; - for (i = tmp; i <= SLJIT_S0; i++) { - size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); - if (reg_map[i] >= 8) - *inst++ = REX_B; - POP_REG(reg_lmap[i]); - } - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) -{ - sljit_ub *inst; - sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + length); - FAIL_IF(!inst); - INC_SIZE(length); - if (rex) - *inst++ = rex; - *inst++ = opcode; - *(sljit_si*)inst = imm; - return SLJIT_SUCCESS; -} - -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, - /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, - /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) -{ - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_ub rex = 0; - sljit_si flags = size & ~0xf; - sljit_si inst_size; - - /* The immediate operand must be 32 bit. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); - /* Both cannot be switched on. */ - SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); - /* Size flags not allowed for typed instructions. */ - SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); - /* Both size flags cannot be switched on. */ - SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); - /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); - - size &= 0xf; - inst_size = size; - - if (!compiler->mode32 && !(flags & EX86_NO_REXW)) - rex |= REX_W; - else if (flags & EX86_REX) - rex |= REX; - - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) - inst_size++; - - /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ - if (b & SLJIT_MEM) { - if (!(b & OFFS_REG_MASK)) { - if (NOT_HALFWORD(immb)) { - if (emit_load_imm64(compiler, TMP_REG3, immb)) - return NULL; - immb = 0; - if (b & REG_MASK) - b |= TO_OFFS_REG(TMP_REG3); - else - b |= TMP_REG3; - } - else if (reg_lmap[b & REG_MASK] == 4) - b |= TO_OFFS_REG(SLJIT_SP); - } - - if ((b & REG_MASK) == SLJIT_UNUSED) - inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ - else { - if (reg_map[b & REG_MASK] >= 8) - rex |= REX_B; - - if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) { - /* Immediate operand. */ - if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); - else - inst_size += sizeof(sljit_si); - } - else if (reg_lmap[b & REG_MASK] == 5) - inst_size += sizeof(sljit_sb); - - if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) { - inst_size += 1; /* SIB byte. */ - if (reg_map[OFFS_REG(b)] >= 8) - rex |= REX_X; - } - } - } - else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8) - rex |= REX_B; - - if (a & SLJIT_IMM) { - if (flags & EX86_BIN_INS) { - if (imma <= 127 && imma >= -128) { - inst_size += 1; - flags |= EX86_BYTE_ARG; - } else - inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { - imma &= compiler->mode32 ? 0x1f : 0x3f; - if (imma != 1) { - inst_size ++; - flags |= EX86_BYTE_ARG; - } - } else if (flags & EX86_BYTE_ARG) - inst_size++; - else if (flags & EX86_HALF_ARG) - inst_size += sizeof(short); - else - inst_size += sizeof(sljit_si); - } - else { - SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); - /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ - if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8) - rex |= REX_R; - } - - if (rex) - inst_size++; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); - PTR_FAIL_IF(!inst); - - /* Encoding the byte. */ - INC_SIZE(inst_size); - if (flags & EX86_PREF_F2) - *inst++ = 0xf2; - if (flags & EX86_PREF_F3) - *inst++ = 0xf3; - if (flags & EX86_PREF_66) - *inst++ = 0x66; - if (rex) - *inst++ = rex; - buf_ptr = inst + size; - - /* Encode mod/rm byte. */ - if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) - *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - - if ((a & SLJIT_IMM) || (a == 0)) - *buf_ptr = 0; - else if (!(flags & EX86_SSE2_OP1)) - *buf_ptr = reg_lmap[a] << 3; - else - *buf_ptr = a << 3; - } - else { - if (a & SLJIT_IMM) { - if (imma == 1) - *inst = GROUP_SHIFT_1; - else - *inst = GROUP_SHIFT_N; - } else - *inst = GROUP_SHIFT_CL; - *buf_ptr = 0; - } - - if (!(b & SLJIT_MEM)) - *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b); - else if ((b & REG_MASK) != SLJIT_UNUSED) { - if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) { - if (immb != 0 || reg_lmap[b & REG_MASK] == 5) { - if (immb <= 127 && immb >= -128) - *buf_ptr |= 0x40; - else - *buf_ptr |= 0x80; - } - - if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) - *buf_ptr++ |= reg_lmap[b & REG_MASK]; - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3); - } - - if (immb != 0 || reg_lmap[b & REG_MASK] == 5) { - if (immb <= 127 && immb >= -128) - *buf_ptr++ = immb; /* 8 bit displacement. */ - else { - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); - } - } - } - else { - if (reg_lmap[b & REG_MASK] == 5) - *buf_ptr |= 0x40; - *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6); - if (reg_lmap[b & REG_MASK] == 5) - *buf_ptr++ = 0; - } - } - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = 0x25; - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); - } - - if (a & SLJIT_IMM) { - if (flags & EX86_BYTE_ARG) - *buf_ptr = imma; - else if (flags & EX86_HALF_ARG) - *(short*)buf_ptr = imma; - else if (!(flags & EX86_SHIFT_INS)) - *(sljit_si*)buf_ptr = imma; - } - - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); -} - -/* --------------------------------------------------------------------- */ -/* Call / return instructions */ -/* --------------------------------------------------------------------- */ - -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) -{ - sljit_ub *inst; - -#ifndef _WIN64 - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); - FAIL_IF(!inst); - INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); - if (type >= SLJIT_CALL3) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2]; - } - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0]; -#else - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); - FAIL_IF(!inst); - INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); - if (type >= SLJIT_CALL3) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2]; - } - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0]; -#endif - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) -{ - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - dst = TMP_REG1; - - if (FAST_IS_REG(dst)) { - if (reg_map[dst] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; - } - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); - INC_SIZE(2); - *inst++ = REX_B; - POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; - } - - /* REX_W is not necessary (src is not immediate). */ - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = POP_rm; - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) -{ - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) { - FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - - if (FAST_IS_REG(src)) { - if (reg_map[src] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); - FAIL_IF(!inst); - - INC_SIZE(1 + 1); - PUSH_REG(reg_lmap[src]); - } - else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); - FAIL_IF(!inst); - - INC_SIZE(2 + 1); - *inst++ = REX_B; - PUSH_REG(reg_lmap[src]); - } - } - else if (src & SLJIT_MEM) { - /* REX_W is not necessary (src is not immediate). */ - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - } - else { - SLJIT_ASSERT(IS_HALFWORD(srcw)); - /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); - FAIL_IF(!inst); - - INC_SIZE(5 + 1); - *inst++ = PUSH_i32; - *(sljit_si*)inst = srcw; - inst += sizeof(sljit_si); - } - - RET(); - return SLJIT_SUCCESS; -} - - -/* --------------------------------------------------------------------- */ -/* Extend input */ -/* --------------------------------------------------------------------- */ - -static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - sljit_si dst_r; - - compiler->mode32 = 0; - - if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) - return SLJIT_SUCCESS; /* Empty instruction. */ - - if (src & SLJIT_IMM) { - if (FAST_IS_REG(dst)) { - if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; - } - return emit_load_imm64(compiler, dst, srcw); - } - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - compiler->mode32 = 0; - return SLJIT_SUCCESS; - } - - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) - dst_r = src; - else { - if (sign) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = MOVSXD_r_rm; - } else { - compiler->mode32 = 1; - FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); - compiler->mode32 = 0; - } - } - - if (dst & SLJIT_MEM) { - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; - compiler->mode32 = 0; - } - - return SLJIT_SUCCESS; -} diff --git a/pcre2/src/sljit/sljitNativeX86_common.c b/pcre2/src/sljit/sljitNativeX86_common.c deleted file mode 100644 index 416c15afa..000000000 --- a/pcre2/src/sljit/sljitNativeX86_common.c +++ /dev/null @@ -1,3004 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) -{ - return "x86" SLJIT_CPUINFO; -} - -/* - 32b register indexes: - 0 - EAX - 1 - ECX - 2 - EDX - 3 - EBX - 4 - none - 5 - EBP - 6 - ESI - 7 - EDI -*/ - -/* - 64b register indexes: - 0 - RAX - 1 - RCX - 2 - RDX - 3 - RBX - 4 - none - 5 - RBP - 6 - RSI - 7 - RDI - 8 - R8 - From now on REX prefix is required - 9 - R9 - 10 - R10 - 11 - R11 - 12 - R12 - 13 - R13 - 14 - R14 - 15 - R15 -*/ - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { - 0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5 -}; - -#define CHECK_EXTRA_REGS(p, w, do) \ - if (p >= SLJIT_R3 && p <= SLJIT_R6) { \ - w = SLJIT_LOCALS_OFFSET + ((p) - (SLJIT_R3 + 4)) * sizeof(sljit_sw); \ - p = SLJIT_MEM1(SLJIT_SP); \ - do; \ - } - -#else /* SLJIT_CONFIG_X86_32 */ - -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) - -/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present - Note: avoid to use r12 and r13 for memory addessing - therefore r12 is better for SAVED_EREG than SAVED_REG. */ -#ifndef _WIN64 -/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9 -}; -/* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1 -}; -#else -/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9 -}; -/* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1 -}; -#endif - -#define REX_W 0x48 -#define REX_R 0x44 -#define REX_X 0x42 -#define REX_B 0x41 -#define REX 0x40 - -#ifndef _WIN64 -#define HALFWORD_MAX 0x7fffffffl -#define HALFWORD_MIN -0x80000000l -#else -#define HALFWORD_MAX 0x7fffffffll -#define HALFWORD_MIN -0x80000000ll -#endif - -#define IS_HALFWORD(x) ((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN) -#define NOT_HALFWORD(x) ((x) > HALFWORD_MAX || (x) < HALFWORD_MIN) - -#define CHECK_EXTRA_REGS(p, w, do) - -#endif /* SLJIT_CONFIG_X86_32 */ - -#define TMP_FREG (0) - -/* Size flags for emit_x86_instruction: */ -#define EX86_BIN_INS 0x0010 -#define EX86_SHIFT_INS 0x0020 -#define EX86_REX 0x0040 -#define EX86_NO_REXW 0x0080 -#define EX86_BYTE_ARG 0x0100 -#define EX86_HALF_ARG 0x0200 -#define EX86_PREF_66 0x0400 -#define EX86_PREF_F2 0x0800 -#define EX86_PREF_F3 0x1000 -#define EX86_SSE2_OP1 0x2000 -#define EX86_SSE2_OP2 0x4000 -#define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2) - -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ - -#define ADD (/* BINARY */ 0 << 3) -#define ADD_EAX_i32 0x05 -#define ADD_r_rm 0x03 -#define ADD_rm_r 0x01 -#define ADDSD_x_xm 0x58 -#define ADC (/* BINARY */ 2 << 3) -#define ADC_EAX_i32 0x15 -#define ADC_r_rm 0x13 -#define ADC_rm_r 0x11 -#define AND (/* BINARY */ 4 << 3) -#define AND_EAX_i32 0x25 -#define AND_r_rm 0x23 -#define AND_rm_r 0x21 -#define ANDPD_x_xm 0x54 -#define BSR_r_rm (/* GROUP_0F */ 0xbd) -#define CALL_i32 0xe8 -#define CALL_rm (/* GROUP_FF */ 2 << 3) -#define CDQ 0x99 -#define CMOVNE_r_rm (/* GROUP_0F */ 0x45) -#define CMP (/* BINARY */ 7 << 3) -#define CMP_EAX_i32 0x3d -#define CMP_r_rm 0x3b -#define CMP_rm_r 0x39 -#define CVTPD2PS_x_xm 0x5a -#define CVTSI2SD_x_rm 0x2a -#define CVTTSD2SI_r_xm 0x2c -#define DIV (/* GROUP_F7 */ 6 << 3) -#define DIVSD_x_xm 0x5e -#define INT3 0xcc -#define IDIV (/* GROUP_F7 */ 7 << 3) -#define IMUL (/* GROUP_F7 */ 5 << 3) -#define IMUL_r_rm (/* GROUP_0F */ 0xaf) -#define IMUL_r_rm_i8 0x6b -#define IMUL_r_rm_i32 0x69 -#define JE_i8 0x74 -#define JNE_i8 0x75 -#define JMP_i8 0xeb -#define JMP_i32 0xe9 -#define JMP_rm (/* GROUP_FF */ 4 << 3) -#define LEA_r_m 0x8d -#define MOV_r_rm 0x8b -#define MOV_r_i32 0xb8 -#define MOV_rm_r 0x89 -#define MOV_rm_i32 0xc7 -#define MOV_rm8_i8 0xc6 -#define MOV_rm8_r8 0x88 -#define MOVSD_x_xm 0x10 -#define MOVSD_xm_x 0x11 -#define MOVSXD_r_rm 0x63 -#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) -#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) -#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) -#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) -#define MUL (/* GROUP_F7 */ 4 << 3) -#define MULSD_x_xm 0x59 -#define NEG_rm (/* GROUP_F7 */ 3 << 3) -#define NOP 0x90 -#define NOT_rm (/* GROUP_F7 */ 2 << 3) -#define OR (/* BINARY */ 1 << 3) -#define OR_r_rm 0x0b -#define OR_EAX_i32 0x0d -#define OR_rm_r 0x09 -#define OR_rm8_r8 0x08 -#define POP_r 0x58 -#define POP_rm 0x8f -#define POPF 0x9d -#define PUSH_i32 0x68 -#define PUSH_r 0x50 -#define PUSH_rm (/* GROUP_FF */ 6 << 3) -#define PUSHF 0x9c -#define RET_near 0xc3 -#define RET_i16 0xc2 -#define SBB (/* BINARY */ 3 << 3) -#define SBB_EAX_i32 0x1d -#define SBB_r_rm 0x1b -#define SBB_rm_r 0x19 -#define SAR (/* SHIFT */ 7 << 3) -#define SHL (/* SHIFT */ 4 << 3) -#define SHR (/* SHIFT */ 5 << 3) -#define SUB (/* BINARY */ 5 << 3) -#define SUB_EAX_i32 0x2d -#define SUB_r_rm 0x2b -#define SUB_rm_r 0x29 -#define SUBSD_x_xm 0x5c -#define TEST_EAX_i32 0xa9 -#define TEST_rm_r 0x85 -#define UCOMISD_x_xm 0x2e -#define UNPCKLPD_x_xm 0x14 -#define XCHG_EAX_r 0x90 -#define XCHG_r_rm 0x87 -#define XOR (/* BINARY */ 6 << 3) -#define XOR_EAX_i32 0x35 -#define XOR_r_rm 0x33 -#define XOR_rm_r 0x31 -#define XORPD_x_xm 0x57 - -#define GROUP_0F 0x0f -#define GROUP_F7 0xf7 -#define GROUP_FF 0xff -#define GROUP_BINARY_81 0x81 -#define GROUP_BINARY_83 0x83 -#define GROUP_SHIFT_1 0xd1 -#define GROUP_SHIFT_N 0xc1 -#define GROUP_SHIFT_CL 0xd3 - -#define MOD_REG 0xc0 -#define MOD_DISP8 0x40 - -#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s)) - -#define PUSH_REG(r) (*inst++ = (PUSH_r + (r))) -#define POP_REG(r) (*inst++ = (POP_r + (r))) -#define RET() (*inst++ = (RET_near)) -#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0) -/* r32, r/m32 */ -#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm)) - -/* Multithreading does not affect these static variables, since they store - built-in CPU features. Therefore they can be overwritten by different threads - if they detect the CPU features in the same time. */ -#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) -static sljit_si cpu_has_sse2 = -1; -#endif -static sljit_si cpu_has_cmov = -1; - -#ifdef _WIN32_WCE -#include -#elif defined(_MSC_VER) && _MSC_VER >= 1400 -#include -#endif - -static void get_cpu_features(void) -{ - sljit_ui features; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - int CPUInfo[4]; - __cpuid(CPUInfo, 1); - features = (sljit_ui)CPUInfo[3]; - -#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) - - /* AT&T syntax. */ - __asm__ ( - "movl $0x1, %%eax\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - /* On x86-32, there is no red zone, so this - should work (no need for a local variable). */ - "push %%ebx\n" -#endif - "cpuid\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - "pop %%ebx\n" -#endif - "movl %%edx, %0\n" - : "=g" (features) - : -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "%eax", "%ecx", "%edx" -#else - : "%rax", "%rbx", "%rcx", "%rdx" -#endif - ); - -#else /* _MSC_VER && _MSC_VER >= 1400 */ - - /* Intel syntax. */ - __asm { - mov eax, 1 - cpuid - mov features, edx - } - -#endif /* _MSC_VER && _MSC_VER >= 1400 */ - -#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - cpu_has_sse2 = (features >> 26) & 0x1; -#endif - cpu_has_cmov = (features >> 15) & 0x1; -} - -static sljit_ub get_jump_code(sljit_si type) -{ - switch (type) { - case SLJIT_EQUAL: - case SLJIT_D_EQUAL: - return 0x84 /* je */; - - case SLJIT_NOT_EQUAL: - case SLJIT_D_NOT_EQUAL: - return 0x85 /* jne */; - - case SLJIT_LESS: - case SLJIT_D_LESS: - return 0x82 /* jc */; - - case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: - return 0x83 /* jae */; - - case SLJIT_GREATER: - case SLJIT_D_GREATER: - return 0x87 /* jnbe */; - - case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: - return 0x86 /* jbe */; - - case SLJIT_SIG_LESS: - return 0x8c /* jl */; - - case SLJIT_SIG_GREATER_EQUAL: - return 0x8d /* jnl */; - - case SLJIT_SIG_GREATER: - return 0x8f /* jnle */; - - case SLJIT_SIG_LESS_EQUAL: - return 0x8e /* jle */; - - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - return 0x80 /* jo */; - - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - return 0x81 /* jno */; - - case SLJIT_D_UNORDERED: - return 0x8a /* jp */; - - case SLJIT_D_ORDERED: - return 0x8b /* jpo */; - } - return 0; -} - -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); -#endif - -static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) -{ - sljit_si short_jump; - sljit_uw label_addr; - - if (jump->flags & JUMP_LABEL) - label_addr = (sljit_uw)(code + jump->u.label->size); - else - label_addr = jump->u.target; - short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) - return generate_far_jump_code(jump, code_ptr, type); -#endif - - if (type == SLJIT_JUMP) { - if (short_jump) - *code_ptr++ = JMP_i8; - else - *code_ptr++ = JMP_i32; - jump->addr++; - } - else if (type >= SLJIT_FAST_CALL) { - short_jump = 0; - *code_ptr++ = CALL_i32; - jump->addr++; - } - else if (short_jump) { - *code_ptr++ = get_jump_code(type) - 0x10; - jump->addr++; - } - else { - *code_ptr++ = GROUP_0F; - *code_ptr++ = get_jump_code(type); - jump->addr += 2; - } - - if (short_jump) { - jump->flags |= PATCH_MB; - code_ptr += sizeof(sljit_sb); - } else { - jump->flags |= PATCH_MW; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - code_ptr += sizeof(sljit_sw); -#else - code_ptr += sizeof(sljit_si); -#endif - } - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ub *code; - sljit_ub *code_ptr; - sljit_ub *buf_ptr; - sljit_ub *buf_end; - sljit_ub len; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - /* Second code generation pass. */ - code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = buf->memory; - buf_end = buf_ptr + buf->used_size; - do { - len = *buf_ptr++; - if (len > 0) { - /* The code is already generated. */ - SLJIT_MEMMOVE(code_ptr, buf_ptr, len); - code_ptr += len; - buf_ptr += len; - } - else { - if (*buf_ptr >= 4) { - jump->addr = (sljit_uw)code_ptr; - if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) - code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4); - else - code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4); - jump = jump->next; - } - else if (*buf_ptr == 0) { - label->addr = (sljit_uw)code_ptr; - label->size = code_ptr - code; - label = label->next; - } - else if (*buf_ptr == 1) { - const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw); - const_ = const_->next; - } - else { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32; - buf_ptr++; - *(sljit_sw*)code_ptr = *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)); - code_ptr += sizeof(sljit_sw); - buf_ptr += sizeof(sljit_sw) - 1; -#else - code_ptr = generate_fixed_jump(code_ptr, *(sljit_sw*)(buf_ptr + 1), *buf_ptr); - buf_ptr += sizeof(sljit_sw); -#endif - } - buf_ptr++; - } - } while (buf_ptr < buf_end); - SLJIT_ASSERT(buf_ptr == buf_end); - buf = buf->next; - } while (buf); - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - - jump = compiler->jumps; - while (jump) { - if (jump->flags & PATCH_MB) { - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); - *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); - } else if (jump->flags & PATCH_MW) { - if (jump->flags & JUMP_LABEL) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); -#else - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); -#endif - } - else { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); -#else - SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); -#endif - } - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - else if (jump->flags & PATCH_MD) - *(sljit_sw*)jump->addr = jump->u.label->addr; -#endif - - jump = jump->next; - } - - /* Maybe we waste some space because of short jumps. */ - SLJIT_ASSERT(code_ptr <= code + compiler->size); - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = code_ptr - code; - return (void*)code; -} - -/* --------------------------------------------------------------------- */ -/* Operators */ -/* --------------------------------------------------------------------- */ - -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); - -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); - -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); - -static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) -{ - sljit_ub *inst; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); -#else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); - FAIL_IF(!inst); - INC_SIZE(6); - *inst++ = REX_W; -#endif - *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ - *inst++ = 0x64; - *inst++ = 0x24; - *inst++ = (sljit_ub)sizeof(sljit_sw); - *inst++ = PUSHF; - compiler->flags_saved = 1; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) -{ - sljit_ub *inst; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - *inst++ = POPF; -#else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); - FAIL_IF(!inst); - INC_SIZE(6); - *inst++ = POPF; - *inst++ = REX_W; -#endif - *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ - *inst++ = 0x64; - *inst++ = 0x24; - *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); - compiler->flags_saved = keep_flags; - return SLJIT_SUCCESS; -} - -#ifdef _WIN32 -#include - -static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) -{ - /* Workaround for calling the internal _chkstk() function on Windows. - This function touches all 4k pages belongs to the requested stack space, - which size is passed in local_size. This is necessary on Windows where - the stack can only grow in 4k steps. However, this function just burn - CPU cycles if the stack is large enough. However, you don't know it in - advance, so it must always be called. I think this is a bad design in - general even if it has some reasons. */ - *(volatile sljit_si*)alloca(local_size) = 0; -} - -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -#include "sljitNativeX86_32.c" -#else -#include "sljitNativeX86_64.c" -#endif - -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - - if (dst == SLJIT_UNUSED) { - /* No destination, doesn't need to setup flags. */ - if (src & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; - } - return SLJIT_SUCCESS; - } - if (FAST_IS_REG(src)) { - inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; - return SLJIT_SUCCESS; - } - if (src & SLJIT_IMM) { - if (FAST_IS_REG(dst)) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); -#else - if (!compiler->mode32) { - if (NOT_HALFWORD(srcw)) - return emit_load_imm64(compiler, dst, srcw); - } - else - return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw); -#endif - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (!compiler->mode32 && NOT_HALFWORD(srcw)) { - FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; - return SLJIT_SUCCESS; - } -#endif - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; - } - if (FAST_IS_REG(dst)) { - inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; - return SLJIT_SUCCESS; - } - - /* Memory to memory move. Requires two instruction. */ - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; - return SLJIT_SUCCESS; -} - -#define EMIT_MOV(compiler, dst, dstw, src, srcw) \ - FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) -{ - sljit_ub *inst; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si size; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - switch (GET_OPCODE(op)) { - case SLJIT_BREAKPOINT: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = INT3; - break; - case SLJIT_NOP: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = NOP; - break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - compiler->flags_saved = 0; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#ifdef _WIN64 - SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_R0] == 0 - && reg_map[SLJIT_R1] == 2 - && reg_map[TMP_REG1] > 7, - invalid_register_assignment_for_div_mul); -#else - SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_R0] == 0 - && reg_map[SLJIT_R1] < 7 - && reg_map[TMP_REG1] == 2, - invalid_register_assignment_for_div_mul); -#endif - compiler->mode32 = op & SLJIT_INT_OP; -#endif - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); - - op = GET_OPCODE(op); - if ((op | 0x2) == SLJIT_UDIVI) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); - inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0); -#else - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); -#endif - FAIL_IF(!inst); - *inst = XOR_r_rm; - } - - if ((op | 0x2) == SLJIT_SDIVI) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; -#else - if (compiler->mode32) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; - } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); - INC_SIZE(2); - *inst++ = REX_W; - *inst = CDQ; - } -#endif - } - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); - INC_SIZE(2); - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); -#else -#ifdef _WIN64 - size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2; -#else - size = (!compiler->mode32) ? 3 : 2; -#endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); -#ifdef _WIN64 - if (!compiler->mode32) - *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0); - else if (op >= SLJIT_UDIVMOD) - *inst++ = REX_B; - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); -#else - if (!compiler->mode32) - *inst++ = REX_W; - *inst++ = GROUP_F7; - *inst = MOD_REG | reg_map[SLJIT_R1]; -#endif -#endif - switch (op) { - case SLJIT_LUMUL: - *inst |= MUL; - break; - case SLJIT_LSMUL: - *inst |= IMUL; - break; - case SLJIT_UDIVMOD: - case SLJIT_UDIVI: - *inst |= DIV; - break; - case SLJIT_SDIVMOD: - case SLJIT_SDIVI: - *inst |= IDIV; - break; - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - if (op <= SLJIT_SDIVMOD) - EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); -#else - if (op >= SLJIT_UDIVI) - EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); -#endif - break; - } - - return SLJIT_SUCCESS; -} - -#define ENCODE_PREFIX(prefix) \ - do { \ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ - FAIL_IF(!inst); \ - INC_SIZE(1); \ - *inst = (prefix); \ - } while (0) - -static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - sljit_si dst_r; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si work_r; -#endif - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - - if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) - return SLJIT_SUCCESS; /* Empty instruction. */ - - if (src & SLJIT_IMM) { - if (FAST_IS_REG(dst)) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); -#else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; -#endif - } - inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_i8; - return SLJIT_SUCCESS; - } - - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (reg_map[src] >= 4) { - SLJIT_ASSERT(dst_r == TMP_REG1); - EMIT_MOV(compiler, TMP_REG1, 0, src, 0); - } else - dst_r = src; -#else - dst_r = src; -#endif - } -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (FAST_IS_REG(src) && reg_map[src] >= 4) { - /* src, dst are registers. */ - SLJIT_ASSERT(SLOW_IS_REG(dst)); - if (reg_map[dst] < 4) { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; - } - else { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - if (sign) { - /* shl reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SHL; - /* sar reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SAR; - } - else { - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); - FAIL_IF(!inst); - *(inst + 1) |= AND; - } - } - return SLJIT_SUCCESS; - } -#endif - else { - /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; - } - - if (dst & SLJIT_MEM) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst_r == TMP_REG1) { - /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & REG_MASK) == SLJIT_R0) { - if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1)) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - else { - if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) - work_r = SLJIT_R0; - else if ((dst & REG_MASK) == SLJIT_R1) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - } - else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - } -#else - inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; -#endif - } - - return SLJIT_SUCCESS; -} - -static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - sljit_si dst_r; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - - if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) - return SLJIT_SUCCESS; /* Empty instruction. */ - - if (src & SLJIT_IMM) { - if (FAST_IS_REG(dst)) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); -#else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; -#endif - } - inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; - } - - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) - dst_r = src; - else { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; - } - - if (dst & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; - } - - return SLJIT_SUCCESS; -} - -static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - - if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - return SLJIT_SUCCESS; - } - if (dst == src && dstw == srcw) { - /* Same input and output */ - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - return SLJIT_SUCCESS; - } - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - return SLJIT_SUCCESS; - } - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; -} - -static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - - if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; - return SLJIT_SUCCESS; - } - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; - return SLJIT_SUCCESS; - } - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; -} - -static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - sljit_si dst_r; - - SLJIT_UNUSED_ARG(op_flags); - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - /* Just set the zero flag. */ - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0); -#else - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REG1, 0); -#endif - FAIL_IF(!inst); - *inst |= SHR; - return SLJIT_SUCCESS; - } - - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); - src = TMP_REG1; - srcw = 0; - } - - inst = emit_x86_instruction(compiler, 2, TMP_REG1, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = BSR_r_rm; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (FAST_IS_REG(dst)) - dst_r = dst; - else { - /* Find an unused temporary register. */ - if ((dst & REG_MASK) != SLJIT_R0 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) - dst_r = SLJIT_R0; - else if ((dst & REG_MASK) != SLJIT_R1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R1)) - dst_r = SLJIT_R1; - else - dst_r = SLJIT_R2; - EMIT_MOV(compiler, dst, dstw, dst_r, 0); - } - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); -#else - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; - compiler->mode32 = 0; - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); - compiler->mode32 = op_flags & SLJIT_INT_OP; -#endif - - if (cpu_has_cmov == -1) - get_cpu_features(); - - if (cpu_has_cmov) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVNE_r_rm; - } else { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - - *inst++ = JE_i8; - *inst++ = 2; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1]; -#else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - - *inst++ = JE_i8; - *inst++ = 3; - *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REG1] >= 8 ? REX_B : 0); - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REG1]; -#endif - } - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); -#else - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); -#endif - FAIL_IF(!inst); - *(inst + 1) |= XOR; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } -#else - if (dst & SLJIT_MEM) - EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0); -#endif - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - sljit_si update = 0; - sljit_si op_flags = GET_ALL_FLAGS(op); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si dst_is_ereg = 0; - sljit_si src_is_ereg = 0; -#else -# define src_is_ereg 0 -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); - CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op_flags & SLJIT_INT_OP; -#endif - - op = GET_OPCODE(op); - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - - if (op_flags & SLJIT_INT_OP) { - if (FAST_IS_REG(src) && src == dst) { - if (!TYPE_CAST_NEEDED(op)) - return SLJIT_SUCCESS; - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; -#endif - } - - SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset); - if (op >= SLJIT_MOVU) { - update = 1; - op -= 8; - } - - if (src & SLJIT_IMM) { - switch (op) { - case SLJIT_MOV_UB: - srcw = (sljit_ub)srcw; - break; - case SLJIT_MOV_SB: - srcw = (sljit_sb)srcw; - break; - case SLJIT_MOV_UH: - srcw = (sljit_uh)srcw; - break; - case SLJIT_MOV_SH: - srcw = (sljit_sh)srcw; - break; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: - srcw = (sljit_ui)srcw; - break; - case SLJIT_MOV_SI: - srcw = (sljit_si)srcw; - break; -#endif - } -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg)) - return emit_mov(compiler, dst, dstw, src, srcw); -#endif - } - - if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK) && (srcw != 0 || (src & OFFS_REG_MASK) != 0)) { - inst = emit_x86_instruction(compiler, 1, src & REG_MASK, 0, src, srcw); - FAIL_IF(!inst); - *inst = LEA_r_m; - src &= SLJIT_MEM | 0xf; - srcw = 0; - } - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { - SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); - dst = TMP_REG1; - } -#endif - - switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: -#endif - FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); - break; - case SLJIT_MOV_UB: - FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw)); - break; - case SLJIT_MOV_SB: - FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); - break; - case SLJIT_MOV_UH: - FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); - break; - case SLJIT_MOV_SH: - FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw)); - break; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: - FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw)); - break; - case SLJIT_MOV_SI: - FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw)); - break; -#endif - } - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1) - return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0); -#endif - - if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) { - inst = emit_x86_instruction(compiler, 1, dst & REG_MASK, 0, dst, dstw); - FAIL_IF(!inst); - *inst = LEA_r_m; - } - return SLJIT_SUCCESS; - } - - if (SLJIT_UNLIKELY(GET_FLAGS(op_flags))) - compiler->flags_saved = 0; - - switch (op) { - case SLJIT_NOT: - if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E)) - return emit_not_with_flags(compiler, dst, dstw, src, srcw); - return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); - - case SLJIT_NEG: - if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) - FAIL_IF(emit_save_flags(compiler)); - return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw); - - case SLJIT_CLZ: - if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) - FAIL_IF(emit_save_flags(compiler)); - return emit_clz(compiler, op_flags, dst, dstw, src, srcw); - } - - return SLJIT_SUCCESS; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -# undef src_is_ereg -#endif -} - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - -#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ - if (IS_HALFWORD(immw) || compiler->mode32) { \ - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ - FAIL_IF(!inst); \ - *(inst + 1) |= (op_imm); \ - } \ - else { \ - FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ - FAIL_IF(!inst); \ - *inst = (op_mr); \ - } - -#define BINARY_EAX_IMM(op_eax_imm, immw) \ - FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw)) - -#else - -#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ - FAIL_IF(!inst); \ - *(inst + 1) |= (op_imm); - -#define BINARY_EAX_IMM(op_eax_imm, immw) \ - FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw)) - -#endif - -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - - if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - return SLJIT_SUCCESS; - } - - if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { -#else - if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) { -#endif - BINARY_EAX_IMM(op_eax_imm, src2w); - } - else { - BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); - } - } - else if (FAST_IS_REG(dst)) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - else if (FAST_IS_REG(src2)) { - /* Special exception for sljit_emit_op_flags. */ - inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - else { - EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - return SLJIT_SUCCESS; - } - - /* Only for cumulative operations. */ - if (dst == src2 && dstw == src2w) { - if (src1 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { -#else - if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) { -#endif - BINARY_EAX_IMM(op_eax_imm, src1w); - } - else { - BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); - } - } - else if (FAST_IS_REG(dst)) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); - FAIL_IF(!inst); - *inst = op_rm; - } - else if (FAST_IS_REG(src1)) { - inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - else { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - return SLJIT_SUCCESS; - } - - /* General version. */ - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, dst, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - } - else { - /* This version requires less memory writing. */ - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - } - - return SLJIT_SUCCESS; -} - -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - - if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - return SLJIT_SUCCESS; - } - - if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { -#else - if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) { -#endif - BINARY_EAX_IMM(op_eax_imm, src2w); - } - else { - BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); - } - } - else if (FAST_IS_REG(dst)) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - else if (FAST_IS_REG(src2)) { - inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - else { - EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; - } - return SLJIT_SUCCESS; - } - - /* General version. */ - if (FAST_IS_REG(dst) && dst != src2) { - EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, dst, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - } - else { - /* This version requires less memory writing. */ - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; - } - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - } - - return SLJIT_SUCCESS; -} - -static sljit_si emit_mul(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - sljit_si dst_r; - - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - /* Register destination. */ - if (dst_r == src1 && !(src2 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (src1 & SLJIT_IMM) { - if (src2 & SLJIT_IMM) { - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); - src2 = dst_r; - src2w = 0; - } - - if (src1w <= 127 && src1w >= -128) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = (sljit_sb)src1w; - } -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_sw*)inst = src1w; - } -#else - else if (IS_HALFWORD(src1w)) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src1w; - } - else { - EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); - if (dst_r != src2) - EMIT_MOV(compiler, dst_r, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } -#endif - } - else if (src2 & SLJIT_IMM) { - /* Note: src1 is NOT immediate. */ - - if (src2w <= 127 && src2w >= -128) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = (sljit_sb)src2w; - } -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_sw*)inst = src2w; - } -#else - else if (IS_HALFWORD(src2w)) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src2w; - } - else { - EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w); - if (dst_r != src1) - EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } -#endif - } - else { - /* Neither argument is immediate. */ - if (ADDRESSING_DEPENDS_ON(src2, dst_r)) - dst_r = TMP_REG1; - EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - - if (dst_r == TMP_REG1) - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - - return SLJIT_SUCCESS; -} - -static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - sljit_si dst_r, done = 0; - - /* These cases better be left to handled by normal way. */ - if (!keep_flags) { - if (dst == src1 && dstw == src1w) - return SLJIT_ERR_UNSUPPORTED; - if (dst == src2 && dstw == src2w) - return SLJIT_ERR_UNSUPPORTED; - } - - dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - - if (FAST_IS_REG(src1)) { - if (FAST_IS_REG(src2)) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); - FAIL_IF(!inst); - *inst = LEA_r_m; - done = 1; - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); -#else - if (src2 & SLJIT_IMM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); -#endif - FAIL_IF(!inst); - *inst = LEA_r_m; - done = 1; - } - } - else if (FAST_IS_REG(src2)) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); -#else - if (src1 & SLJIT_IMM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); -#endif - FAIL_IF(!inst); - *inst = LEA_r_m; - done = 1; - } - } - - if (done) { - if (dst_r == TMP_REG1) - return emit_mov(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; - } - return SLJIT_ERR_UNSUPPORTED; -} - -static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { -#else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { -#endif - BINARY_EAX_IMM(CMP_EAX_i32, src2w); - return SLJIT_SUCCESS; - } - - if (FAST_IS_REG(src1)) { - if (src2 & SLJIT_IMM) { - BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); - } - else { - inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = CMP_r_rm; - } - return SLJIT_SUCCESS; - } - - if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); - FAIL_IF(!inst); - *inst = CMP_rm_r; - return SLJIT_SUCCESS; - } - - if (src2 & SLJIT_IMM) { - if (src1 & SLJIT_IMM) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - src1 = TMP_REG1; - src1w = 0; - } - BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w); - } - else { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = CMP_r_rm; - } - return SLJIT_SUCCESS; -} - -static sljit_si emit_test_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { -#else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { -#endif - BINARY_EAX_IMM(TEST_EAX_i32, src2w); - return SLJIT_SUCCESS; - } - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src2 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { -#else - if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { -#endif - BINARY_EAX_IMM(TEST_EAX_i32, src1w); - return SLJIT_SUCCESS; - } - - if (!(src1 & SLJIT_IMM)) { - if (src2 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (IS_HALFWORD(src2w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); - FAIL_IF(!inst); - *inst = GROUP_F7; - } - else { - FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w); - FAIL_IF(!inst); - *inst = TEST_rm_r; - } -#else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); - FAIL_IF(!inst); - *inst = GROUP_F7; -#endif - return SLJIT_SUCCESS; - } - else if (FAST_IS_REG(src1)) { - inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = TEST_rm_r; - return SLJIT_SUCCESS; - } - } - - if (!(src2 & SLJIT_IMM)) { - if (src1 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (IS_HALFWORD(src1w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w); - FAIL_IF(!inst); - *inst = GROUP_F7; - } - else { - FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w); - FAIL_IF(!inst); - *inst = TEST_rm_r; - } -#else - inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w); - FAIL_IF(!inst); - *inst = GROUP_F7; -#endif - return SLJIT_SUCCESS; - } - else if (FAST_IS_REG(src2)) { - inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); - FAIL_IF(!inst); - *inst = TEST_rm_r; - return SLJIT_SUCCESS; - } - } - - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (IS_HALFWORD(src2w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; - } - else { - FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = TEST_rm_r; - } -#else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; -#endif - } - else { - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = TEST_rm_r; - } - return SLJIT_SUCCESS; -} - -static sljit_si emit_shift(struct sljit_compiler *compiler, - sljit_ub mode, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_ub* inst; - - if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { - if (dst == src1 && dstw == src1w) { - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst |= mode; - return SLJIT_SUCCESS; - } - if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); - FAIL_IF(!inst); - *inst |= mode; - return SLJIT_SUCCESS; - } - if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - return SLJIT_SUCCESS; - } - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); - FAIL_IF(!inst); - *inst |= mode; - return SLJIT_SUCCESS; - } - - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); - FAIL_IF(!inst); - *inst |= mode; - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; - } - - if (dst == SLJIT_PREF_SHIFT_REG) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - } - else if (FAST_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { - if (src1 != dst) - EMIT_MOV(compiler, dst, 0, src1, src1w); - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); - FAIL_IF(!inst); - *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - } - else { - /* This case is really difficult, since ecx itself may used for - addressing, and we must ensure to work even in that case. */ - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0); -#else - /* [esp+0] contains the flags. */ - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0); -#endif - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst |= mode; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0); -#else - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw)); -#endif - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - } - - return SLJIT_SUCCESS; -} - -static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, - sljit_ub mode, sljit_si set_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - /* The CPU does not set flags if the shift count is 0. */ - if (src2 & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0)) - return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); -#else - if ((src2w & 0x1f) != 0) - return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); -#endif - if (!set_flags) - return emit_mov(compiler, dst, dstw, src1, src1w); - /* OR dst, src, 0 */ - return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, - dst, dstw, src1, src1w, SLJIT_IMM, 0); - } - - if (!set_flags) - return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); - - if (!FAST_IS_REG(dst)) - FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); - - FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); - - if (FAST_IS_REG(dst)) - return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - CHECK_EXTRA_REGS(dst, dstw, (void)0); - CHECK_EXTRA_REGS(src1, src1w, (void)0); - CHECK_EXTRA_REGS(src2, src2w, (void)0); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_INT_OP; -#endif - - if (GET_OPCODE(op) >= SLJIT_MUL) { - if (SLJIT_UNLIKELY(GET_FLAGS(op))) - compiler->flags_saved = 0; - else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) - FAIL_IF(emit_save_flags(compiler)); - } - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - if (!GET_FLAGS(op)) { - if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED) - return compiler->error; - } - else - compiler->flags_saved = 0; - if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) - FAIL_IF(emit_save_flags(compiler)); - return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_ADDC: - if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ - FAIL_IF(emit_restore_flags(compiler, 1)); - else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) - FAIL_IF(emit_save_flags(compiler)); - if (SLJIT_UNLIKELY(GET_FLAGS(op))) - compiler->flags_saved = 0; - return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_SUB: - if (!GET_FLAGS(op)) { - if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) - return compiler->error; - } - else - compiler->flags_saved = 0; - if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) - FAIL_IF(emit_save_flags(compiler)); - if (dst == SLJIT_UNUSED) - return emit_cmp_binary(compiler, src1, src1w, src2, src2w); - return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_SUBC: - if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ - FAIL_IF(emit_restore_flags(compiler, 1)); - else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) - FAIL_IF(emit_save_flags(compiler)); - if (SLJIT_UNLIKELY(GET_FLAGS(op))) - compiler->flags_saved = 0; - return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_MUL: - return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w); - case SLJIT_AND: - if (dst == SLJIT_UNUSED) - return emit_test_binary(compiler, src1, src1w, src2, src2w); - return emit_cum_binary(compiler, AND_r_rm, AND_rm_r, AND, AND_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_OR: - return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_XOR: - return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32, - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_SHL: - return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op), - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_LSHR: - return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op), - dst, dstw, src1, src1w, src2, src2w); - case SLJIT_ASHR: - return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op), - dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (reg >= SLJIT_R3 && reg <= SLJIT_R6) - return -1; -#endif - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) -{ - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) -{ - sljit_ub *inst; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); - INC_SIZE(size); - SLJIT_MEMMOVE(inst, instruction, size); - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Floating point operators */ -/* --------------------------------------------------------------------- */ - -/* Alignment + 2 * 16 bytes. */ -static sljit_si sse2_data[3 + (4 + 4) * 2]; -static sljit_si *sse2_buffer; - -static void init_compiler(void) -{ - sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); - /* Single precision constants. */ - sse2_buffer[0] = 0x80000000; - sse2_buffer[4] = 0x7fffffff; - /* Double precision constants. */ - sse2_buffer[8] = 0; - sse2_buffer[9] = 0x80000000; - sse2_buffer[12] = 0xffffffff; - sse2_buffer[13] = 0x7fffffff; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) -{ -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - if (cpu_has_sse2 == -1) - get_cpu_features(); - return cpu_has_sse2; -#else /* SLJIT_DETECT_SSE2 */ - return 1; -#endif /* SLJIT_DETECT_SSE2 */ -} - -static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) -{ - sljit_ub *inst; - - inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; - return SLJIT_SUCCESS; -} - -static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) -{ - sljit_ub *inst; - - inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) -{ - return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); -} - -static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) -{ - return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ub *inst; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVW_FROMD) - compiler->mode32 = 0; -#endif - - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTTSD2SI_r_xm; - - if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) - return emit_mov(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - sljit_ub *inst; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMW) - compiler->mode32 = 0; -#endif - - if (src & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; -#endif - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - src = TMP_REG1; - srcw = 0; - } - - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTSI2SD_x_rm; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 1; -#endif - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; -} - -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - compiler->flags_saved = 0; - if (!FAST_IS_REG(src1)) { - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); - src1 = TMP_FREG; - } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), src1, src2, src2w); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) -{ - sljit_si dst_r; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 1; -#endif - - CHECK_ERROR(); - SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - - if (GET_OPCODE(op) == SLJIT_DMOV) { - if (FAST_IS_REG(dst)) - return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); - if (FAST_IS_REG(src)) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); - } - - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) { - dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - if (FAST_IS_REG(src)) { - /* We overwrite the high bits of source. From SLJIT point of view, - this is not an issue. - Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ - FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_SINGLE_OP, src, src, 0)); - } - else { - FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_SINGLE_OP), TMP_FREG, src, srcw)); - src = TMP_FREG; - } - - FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_SINGLE_OP, dst_r, src, 0)); - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; - } - - if (SLOW_IS_REG(dst)) { - dst_r = dst; - if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); - } - else { - dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); - } - - switch (GET_OPCODE(op)) { - case SLJIT_DNEG: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); - break; - - case SLJIT_DABS: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); - break; - } - - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) -{ - sljit_si dst_r; - - CHECK_ERROR(); - CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 1; -#endif - - if (FAST_IS_REG(dst)) { - dst_r = dst; - if (dst == src1) - ; /* Do nothing here. */ - else if (dst == src2 && (op == SLJIT_DADD || op == SLJIT_DMUL)) { - /* Swap arguments. */ - src2 = src1; - src2w = src1w; - } - else if (dst != src2) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); - else { - dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); - } - } - else { - dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); - } - - switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); - break; - - case SLJIT_DSUB: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); - break; - - case SLJIT_DMUL: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); - break; - - case SLJIT_DDIV: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); - break; - } - - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ -/* Conditional instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - sljit_ub *inst; - struct sljit_label *label; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - /* We should restore the flags before the label, - since other taken jumps has their own flags as well. */ - if (SLJIT_UNLIKELY(compiler->flags_saved)) - PTR_FAIL_IF(emit_restore_flags(compiler, 0)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF(!inst); - - *inst++ = 0; - *inst++ = 0; - - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) -{ - sljit_ub *inst; - struct sljit_jump *jump; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - if (SLJIT_UNLIKELY(compiler->flags_saved)) { - if ((type & 0xff) <= SLJIT_JUMP) - PTR_FAIL_IF(emit_restore_flags(compiler, 0)); - compiler->flags_saved = 0; - } - - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF_NULL(jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - if (type >= SLJIT_CALL1) - PTR_FAIL_IF(call_with_args(compiler, type)); - - /* Worst case size. */ -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - compiler->size += (type >= SLJIT_JUMP) ? 5 : 6; -#else - compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); -#endif - - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF_NULL(inst); - - *inst++ = 0; - *inst++ = type + 4; - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) -{ - sljit_ub *inst; - struct sljit_jump *jump; - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - CHECK_EXTRA_REGS(src, srcw, (void)0); - - if (SLJIT_UNLIKELY(compiler->flags_saved)) { - if (type <= SLJIT_JUMP) - FAIL_IF(emit_restore_flags(compiler, 0)); - compiler->flags_saved = 0; - } - - if (type >= SLJIT_CALL1) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (src == SLJIT_R2) { - EMIT_MOV(compiler, TMP_REG1, 0, src, 0); - src = TMP_REG1; - } - if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3) - srcw += sizeof(sljit_sw); -#endif -#endif -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) - if (src == SLJIT_R2) { - EMIT_MOV(compiler, TMP_REG1, 0, src, 0); - src = TMP_REG1; - } -#endif - FAIL_IF(call_with_args(compiler, type)); - } - - if (src == SLJIT_IMM) { - jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF_NULL(jump); - set_jump(jump, compiler, JUMP_ADDR); - jump->u.target = srcw; - - /* Worst case size. */ -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - compiler->size += 5; -#else - compiler->size += 10 + 3; -#endif - - inst = (sljit_ub*)ensure_buf(compiler, 2); - FAIL_IF_NULL(inst); - - *inst++ = 0; - *inst++ = type + 4; - } - else { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - /* REX_W is not necessary (src is not immediate). */ - compiler->mode32 = 1; -#endif - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm; - } - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) -{ - sljit_ub *inst; - sljit_ub cond_set = 0; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; -#else - /* CHECK_EXTRA_REGS migh overwrite these values. */ - sljit_si dst_save = dst; - sljit_sw dstw_save = dstw; -#endif - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - SLJIT_UNUSED_ARG(srcw); - - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - ADJUST_LOCAL_OFFSET(dst, dstw); - CHECK_EXTRA_REGS(dst, dstw, (void)0); - if (SLJIT_UNLIKELY(compiler->flags_saved)) - FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS)); - - type &= 0xff; - /* setcc = jcc + 0x10. */ - cond_set = get_jump_code(type) + 0x10; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3); - FAIL_IF(!inst); - INC_SIZE(4 + 3); - /* Set low register to conditional flag. */ - *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[TMP_REG1]; - *inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B); - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]; - return SLJIT_SUCCESS; - } - - reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1; - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); - FAIL_IF(!inst); - INC_SIZE(4 + 4); - /* Set low register to conditional flag. */ - *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[reg]; - *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]; - - if (reg != TMP_REG1) - return SLJIT_SUCCESS; - - if (GET_OPCODE(op) < SLJIT_ADD) { - compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV; - return emit_mov(compiler, dst, dstw, TMP_REG1, 0); - } -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0); -#else /* SLJIT_CONFIG_X86_64 */ - if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { - if (reg_map[dst] <= 4) { - /* Low byte is accessible. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); - FAIL_IF(!inst); - INC_SIZE(3 + 3); - /* Set low byte to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_map[dst]; - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst]; - return SLJIT_SUCCESS; - } - - /* Low byte is not accessible. */ - if (cpu_has_cmov == -1) - get_cpu_features(); - - if (cpu_has_cmov) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); - /* a xor reg, reg operation would overwrite the flags. */ - EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - - *inst++ = GROUP_0F; - /* cmovcc = setcc - 0x50. */ - *inst++ = cond_set - 0x50; - *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]; - return SLJIT_SUCCESS; - } - - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */; - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - return SLJIT_SUCCESS; - } - - if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) { - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax); - if (dst != SLJIT_R0) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 2 + 1); - /* Set low register to conditional flag. */ - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst]; - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - } - else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); - FAIL_IF(!inst); - INC_SIZE(2 + 3 + 2 + 2); - /* Set low register to conditional flag. */ - *inst++ = XCHG_r_rm; - *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 1 /* ecx */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */; - *inst++ = XCHG_r_rm; - *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; - } - return SLJIT_SUCCESS; - } - - /* Set TMP_REG1 to the bit. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; - - *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; - - if (GET_OPCODE(op) < SLJIT_ADD) - return emit_mov(compiler, dst, dstw, TMP_REG1, 0); - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0); -#endif /* SLJIT_CONFIG_X86_64 */ -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) -{ - CHECK_ERROR(); - CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - CHECK_EXTRA_REGS(dst, dstw, (void)0); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - - ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (NOT_HALFWORD(offset)) { - FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset)); -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) - SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED); - return compiler->error; -#else - return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0); -#endif - } -#endif - - if (offset != 0) - return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset); - return emit_mov(compiler, dst, dstw, SLJIT_SP, 0); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) -{ - sljit_ub *inst; - struct sljit_const *const_; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; -#endif - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - CHECK_EXTRA_REGS(dst, dstw, (void)0); - - const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; - reg = SLOW_IS_REG(dst) ? dst : TMP_REG1; - - if (emit_load_imm64(compiler, reg, init_value)) - return NULL; -#else - if (dst == SLJIT_UNUSED) - dst = TMP_REG1; - - if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value)) - return NULL; -#endif - - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF(!inst); - - *inst++ = 0; - *inst++ = 1; - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (dst & SLJIT_MEM) - if (emit_mov(compiler, dst, dstw, TMP_REG1, 0)) - return NULL; -#endif - - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) -{ -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)addr = new_addr - (addr + 4); -#else - *(sljit_uw*)addr = new_addr; -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - *(sljit_sw*)addr = new_constant; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) -{ -#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - if (cpu_has_sse2 == -1) - get_cpu_features(); - return cpu_has_sse2; -#else - return 1; -#endif -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void) -{ - if (cpu_has_cmov == -1) - get_cpu_features(); - return cpu_has_cmov; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw) -{ - sljit_ub* inst; - - CHECK_ERROR(); -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(sljit_x86_is_cmov_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP)); - FUNCTION_CHECK_SRC(src, srcw); -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " x86_cmov%s %s%s, ", - !(dst_reg & SLJIT_INT_OP) ? "" : ".i", - JUMP_PREFIX(type), jump_names[type & 0xff]); - sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP); - fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - - ADJUST_LOCAL_OFFSET(src, srcw); - CHECK_EXTRA_REGS(src, srcw, (void)0); - -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = dst_reg & SLJIT_INT_OP; -#endif - dst_reg &= ~SLJIT_INT_OP; - - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); - src = TMP_REG1; - srcw = 0; - } - - inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = get_jump_code(type & 0xff) - 0x40; - return SLJIT_SUCCESS; -} diff --git a/pcre2/src/sljit/sljitUtils.c b/pcre2/src/sljit/sljitUtils.c deleted file mode 100644 index 5294b5f3f..000000000 --- a/pcre2/src/sljit/sljitUtils.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* ------------------------------------------------------------------------ */ -/* Locks */ -/* ------------------------------------------------------------------------ */ - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) - -#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) - -static SLJIT_INLINE void allocator_grab_lock(void) -{ - /* Always successful. */ -} - -static SLJIT_INLINE void allocator_release_lock(void) -{ - /* Always successful. */ -} - -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) -{ - /* Always successful. */ -} - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) -{ - /* Always successful. */ -} - -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ - -#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ - -#include "windows.h" - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) - -static HANDLE allocator_mutex = 0; - -static SLJIT_INLINE void allocator_grab_lock(void) -{ - /* No idea what to do if an error occures. Static mutexes should never fail... */ - if (!allocator_mutex) - allocator_mutex = CreateMutex(NULL, TRUE, NULL); - else - WaitForSingleObject(allocator_mutex, INFINITE); -} - -static SLJIT_INLINE void allocator_release_lock(void) -{ - ReleaseMutex(allocator_mutex); -} - -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) - -static HANDLE global_mutex = 0; - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) -{ - /* No idea what to do if an error occures. Static mutexes should never fail... */ - if (!global_mutex) - global_mutex = CreateMutex(NULL, TRUE, NULL); - else - WaitForSingleObject(global_mutex, INFINITE); -} - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) -{ - ReleaseMutex(global_mutex); -} - -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ - -#else /* _WIN32 */ - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) - -#include - -static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; - -static SLJIT_INLINE void allocator_grab_lock(void) -{ - pthread_mutex_lock(&allocator_mutex); -} - -static SLJIT_INLINE void allocator_release_lock(void) -{ - pthread_mutex_unlock(&allocator_mutex); -} - -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) - -#include - -static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) -{ - pthread_mutex_lock(&global_mutex); -} - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) -{ - pthread_mutex_unlock(&global_mutex); -} - -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ - -#endif /* _WIN32 */ - -/* ------------------------------------------------------------------------ */ -/* Stack */ -/* ------------------------------------------------------------------------ */ - -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) - -#ifdef _WIN32 -#include "windows.h" -#else -/* Provides mmap function. */ -#include -/* For detecting the page size. */ -#include - -#ifndef MAP_ANON - -#include - -/* Some old systems does not have MAP_ANON. */ -static sljit_si dev_zero = -1; - -#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) - -static SLJIT_INLINE sljit_si open_dev_zero(void) -{ - dev_zero = open("/dev/zero", O_RDWR); - return dev_zero < 0; -} - -#else /* SLJIT_SINGLE_THREADED */ - -#include - -static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; - -static SLJIT_INLINE sljit_si open_dev_zero(void) -{ - pthread_mutex_lock(&dev_zero_mutex); - dev_zero = open("/dev/zero", O_RDWR); - pthread_mutex_unlock(&dev_zero_mutex); - return dev_zero < 0; -} - -#endif /* SLJIT_SINGLE_THREADED */ - -#endif - -#endif - -#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) - -/* Planning to make it even more clever in the future. */ -static sljit_sw sljit_page_align = 0; - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data) -{ - struct sljit_stack *stack; - union { - void *ptr; - sljit_uw uw; - } base; -#ifdef _WIN32 - SYSTEM_INFO si; -#endif - - SLJIT_UNUSED_ARG(allocator_data); - if (limit > max_limit || limit < 1) - return NULL; - -#ifdef _WIN32 - if (!sljit_page_align) { - GetSystemInfo(&si); - sljit_page_align = si.dwPageSize - 1; - } -#else - if (!sljit_page_align) { - sljit_page_align = sysconf(_SC_PAGESIZE); - /* Should never happen. */ - if (sljit_page_align < 0) - sljit_page_align = 4096; - sljit_page_align--; - } -#endif - - /* Align limit and max_limit. */ - max_limit = (max_limit + sljit_page_align) & ~sljit_page_align; - - stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data); - if (!stack) - return NULL; - -#ifdef _WIN32 - base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE); - if (!base.ptr) { - SLJIT_FREE(stack, allocator_data); - return NULL; - } - stack->base = base.uw; - stack->limit = stack->base; - stack->max_limit = stack->base + max_limit; - if (sljit_stack_resize(stack, stack->base + limit)) { - sljit_free_stack(stack, allocator_data); - return NULL; - } -#else -#ifdef MAP_ANON - base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -#else - if (dev_zero < 0) { - if (open_dev_zero()) { - SLJIT_FREE(stack, allocator_data); - return NULL; - } - } - base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); -#endif - if (base.ptr == MAP_FAILED) { - SLJIT_FREE(stack, allocator_data); - return NULL; - } - stack->base = base.uw; - stack->limit = stack->base + limit; - stack->max_limit = stack->base + max_limit; -#endif - stack->top = stack->base; - return stack; -} - -#undef PAGE_ALIGN - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data) -{ - SLJIT_UNUSED_ARG(allocator_data); -#ifdef _WIN32 - VirtualFree((void*)stack->base, 0, MEM_RELEASE); -#else - munmap((void*)stack->base, stack->max_limit - stack->base); -#endif - SLJIT_FREE(stack, allocator_data); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) -{ - sljit_uw aligned_old_limit; - sljit_uw aligned_new_limit; - - if ((new_limit > stack->max_limit) || (new_limit < stack->base)) - return -1; -#ifdef _WIN32 - aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; - aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; - if (aligned_new_limit != aligned_old_limit) { - if (aligned_new_limit > aligned_old_limit) { - if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE)) - return -1; - } - else { - if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT)) - return -1; - } - } - stack->limit = new_limit; - return 0; -#else - if (new_limit >= stack->limit) { - stack->limit = new_limit; - return 0; - } - aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; - aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; - /* If madvise is available, we release the unnecessary space. */ -#if defined(MADV_DONTNEED) - if (aligned_new_limit < aligned_old_limit) - madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); -#elif defined(POSIX_MADV_DONTNEED) - if (aligned_new_limit < aligned_old_limit) - posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); -#endif - stack->limit = new_limit; - return 0; -#endif -} - -#endif /* SLJIT_UTIL_STACK */ - -#endif diff --git a/pcre2/test-driver b/pcre2/test-driver deleted file mode 100755 index 8e575b017..000000000 --- a/pcre2/test-driver +++ /dev/null @@ -1,148 +0,0 @@ -#! /bin/sh -# test-driver - basic testsuite driver script. - -scriptversion=2013-07-13.22; # UTC - -# Copyright (C) 2011-2014 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -# Make unconditional expansion of undefined variables an error. This -# helps a lot in preventing typo-related bugs. -set -u - -usage_error () -{ - echo "$0: $*" >&2 - print_usage >&2 - exit 2 -} - -print_usage () -{ - cat <$log_file 2>&1 -estatus=$? - -if test $enable_hard_errors = no && test $estatus -eq 99; then - tweaked_estatus=1 -else - tweaked_estatus=$estatus -fi - -case $tweaked_estatus:$expect_failure in - 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; - 0:*) col=$grn res=PASS recheck=no gcopy=no;; - 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; - 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; - *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; - *:*) col=$red res=FAIL recheck=yes gcopy=yes;; -esac - -# Report the test outcome and exit status in the logs, so that one can -# know whether the test passed or failed simply by looking at the '.log' -# file, without the need of also peaking into the corresponding '.trs' -# file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>$log_file - -# Report outcome to console. -echo "${col}${res}${std}: $test_name" - -# Register the test result, and other relevant metadata. -echo ":test-result: $res" > $trs_file -echo ":global-test-result: $res" >> $trs_file -echo ":recheck: $recheck" >> $trs_file -echo ":copy-in-global-log: $gcopy" >> $trs_file - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: From 960cc628b200d250b90d86a841ad3a26ce60b5da Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 31 Oct 2016 01:37:23 -0700 Subject: [PATCH 045/112] Don't choke defining aliases with quotes Fixes #3510 --- share/functions/alias.fish | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/share/functions/alias.fish b/share/functions/alias.fish index 86a1e702e..41d1b7ae8 100644 --- a/share/functions/alias.fish +++ b/share/functions/alias.fish @@ -15,7 +15,9 @@ function alias --description 'Creates a function wrapping a command' case 0 for func in (functions -n) - functions $func | string match -- "function * --description 'alias *" | string replace -r -- "function .* --description '" ''| string trim -c\' + set -l output (functions $func | string match -r -- "function .* --description '(alias .*)'" | string split \n) + set -q output[2] + and echo $output[2] end return 0 case 1 @@ -62,5 +64,6 @@ function alias --description 'Creates a function wrapping a command' set prefix command end end - echo "function $name --wraps $first_word --description \"alias $argv\"; $prefix $first_word $body \$argv; end" | source + set -l cmd_string (string escape "alias $argv") + echo "function $name --wraps $first_word --description $cmd_string; $prefix $first_word $body \$argv; end" | source end From 2a5ad198bf9e7f2c5a9b927e3dcf7496217a00ac Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Thu, 27 Oct 2016 23:04:12 +0200 Subject: [PATCH 046/112] Rework cursor detection Fixes #3499. --- share/functions/fish_vi_cursor.fish | 58 ++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/share/functions/fish_vi_cursor.fish b/share/functions/fish_vi_cursor.fish index 47fa7467b..c1eef1bfe 100644 --- a/share/functions/fish_vi_cursor.fish +++ b/share/functions/fish_vi_cursor.fish @@ -1,20 +1,44 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' - # Since we read exported variables (KONSOLE_PROFILE_NAME and ITERM_PROFILE) - # we need to check harder if we're actually in a supported terminal, - # because we might be in a term-in-a-term (emacs ansi-term). - if not contains -- $TERM xterm konsole xterm-256color konsole-256color - and not set -q TMUX - return - end - - # XTerm supports this sequence since version 282 - if test -n "$XTERM_VERSION" - # This will fail if $XTERM_VERSION is not in the "XTerm($version)" format. - # In that case, we cannot determine the terminal and should stop - # so "[1 q" does not show up on the user's screen - if not test (string replace -r 'XTerm\((\d*)\)' '$1' -- $XTERM_VERSION) -ge 282 - return + # Check hard if we are in a supporting terminal. + # + # Challenges here are term-in-a-terms (emacs ansi-term does not support this, tmux does), + # that we can only figure out if we are in konsole/iterm/vte via exported variables, + # and ancient xterm versions. + # + # tmux defaults to $TERM = screen, but can do this if it is in a supporting terminal. + # Unfortunately, we can only detect this via the exported variables, so we miss some cases. + # + # We will also miss some cases of terminal-stacking, + # e.g. tmux started in suckless' st (no support) started in konsole. + # But since tmux in konsole seems rather common and that case so uncommon, + # we will just fail there (though it seems that tmux or st swallow it anyway). + # + # We use the `tput` here just to see if terminfo thinks we can change the cursor. + # We cannot use that sequence directly as it's not the correct one for konsole and iTerm, + # and because we may want to change the cursor even though terminfo says we can't (tmux). + if not tput Ss > /dev/null + # Whitelist tmux... + and not begin + set -q TMUX + # ...in a supporting term... + and begin set -q KONSOLE_PROFILE_NAME + or set -q ITERM_PROFILE + or test "$VTE_VERSION" -gt 1910 + end + # .. unless an unsupporting terminal has been started in tmux inside a supporting one + and begin string match -q "screen*" -- $TERM + or string match -q "tmux*" -- $TERM + end end + and not string match -q "konsole*" -- $TERM + # Blacklist + or begin + # vte-based terms set $TERM = xterm*, but only gained support relatively recently. + set -q VTE_VERSION + and test "$VTE_VERSION" -le 1910 + end + or set -q INSIDE_EMACS + return end set -l terminal $argv[1] @@ -29,11 +53,9 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' or set -q ITERM_PROFILE set function __fish_cursor_konsole set uses_echo 1 - else if string match -q "xterm*" -- $TERM; or test "$VTE_VERSION" -gt 1910 + else set function __fish_cursor_xterm set uses_echo 1 - else - return 1 end case konsole set function __fish_cursor_konsole From 49ed20c8cbe48838af74a7f95c440733e18ceab1 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 12:38:56 -0700 Subject: [PATCH 047/112] lint: Use early exit/continue --- src/wgetopt.cpp | 99 +++++++++++++++++++++++++------------------------ src/wutil.cpp | 61 +++++++++++++++--------------- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/src/wgetopt.cpp b/src/wgetopt.cpp index 091bceeab..dbb0d4393 100644 --- a/src/wgetopt.cpp +++ b/src/wgetopt.cpp @@ -381,59 +381,62 @@ int wgetopter_t::_wgetopt_internal(int argc, wchar_t **argv, const wchar_t *opts } // Look at and handle the next short option-character. - { - wchar_t c = *nextchar++; - wchar_t *temp = const_cast(my_index(optstring, c)); + wchar_t c = *nextchar++; + wchar_t *temp = const_cast(my_index(optstring, c)); - // Increment `woptind' when we start to process its last character. - if (*nextchar == '\0') ++woptind; + // Increment `woptind' when we start to process its last character. + if (*nextchar == '\0') ++woptind; - if (temp == NULL || c == ':') { - if (wopterr) { - fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], (wint_t)c); - } - woptopt = c; - - if (*nextchar != '\0') woptind++; - - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - // This is an option that accepts an argument optionally. - if (*nextchar != '\0') { - woptarg = nextchar; - woptind++; - } else - woptarg = NULL; - nextchar = NULL; - } else { - // This is an option that requires an argument. - if (*nextchar != '\0') { - woptarg = nextchar; - // If we end this ARGV-element by taking the rest as an arg, we must advance to - // the next element now. - woptind++; - } else if (woptind == argc) { - if (wopterr) { - // 1003.2 specifies the format of this message. - fwprintf(stderr, _(L"%ls: Option requires an argument -- %lc\n"), argv[0], - (wint_t)c); - } - woptopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - // We already incremented `woptind' once; increment it again when taking next - // ARGV-elt as argument. - woptarg = argv[woptind++]; - nextchar = NULL; - } + if (temp == NULL || c == ':') { + if (wopterr) { + fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], (wint_t)c); } + woptopt = c; + + if (*nextchar != '\0') woptind++; + return '?'; + } + + if (temp[1] != ':') { return c; } + + if (temp[2] == ':') { + // This is an option that accepts an argument optionally. + if (*nextchar != '\0') { + woptarg = nextchar; + woptind++; + } else { + woptarg = NULL; + } + nextchar = NULL; + } else { + // This is an option that requires an argument. + if (*nextchar != '\0') { + woptarg = nextchar; + // If we end this ARGV-element by taking the rest as an arg, we must advance to + // the next element now. + woptind++; + } else if (woptind == argc) { + if (wopterr) { + // 1003.2 specifies the format of this message. + fwprintf(stderr, _(L"%ls: Option requires an argument -- %lc\n"), argv[0], + (wint_t)c); + } + woptopt = c; + if (optstring[0] == ':') { + c = ':'; + } else { + c = '?'; + } + } else { + // We already incremented `woptind' once; increment it again when taking next + // ARGV-elt as argument. + woptarg = argv[woptind++]; + } + nextchar = NULL; + } + return c; } int wgetopter_t::wgetopt_long(int argc, wchar_t **argv, const wchar_t *options, diff --git a/src/wutil.cpp b/src/wutil.cpp index b8897de3b..572f8e510 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -50,40 +50,39 @@ bool wreaddir_resolving(DIR *dir, const std::wstring &dir_path, std::wstring &ou if (!d) return false; out_name = str2wcstring(d->d_name); - if (out_is_dir) { - // The caller cares if this is a directory, so check. - bool is_dir = false; + if (!out_is_dir) return true; - // We may be able to skip stat, if the readdir can tell us the file type directly. - bool check_with_stat = true; + // The caller cares if this is a directory, so check. + bool is_dir = false; + // We may be able to skip stat, if the readdir can tell us the file type directly. + bool check_with_stat = true; #ifdef HAVE_STRUCT_DIRENT_D_TYPE - if (d->d_type == DT_DIR) { - // Known directory. - is_dir = true; - check_with_stat = false; - } else if (d->d_type == DT_LNK || d->d_type == DT_UNKNOWN) { - // We want to treat symlinks to directories as directories. Use stat to resolve it. - check_with_stat = true; - } else { - // Regular file. - is_dir = false; - check_with_stat = false; - } -#endif // HAVE_STRUCT_DIRENT_D_TYPE - if (check_with_stat) { - // We couldn't determine the file type from the dirent; check by stat'ing it. - cstring fullpath = wcs2string(dir_path); - fullpath.push_back('/'); - fullpath.append(d->d_name); - struct stat buf; - if (stat(fullpath.c_str(), &buf) != 0) { - is_dir = false; - } else { - is_dir = static_cast(S_ISDIR(buf.st_mode)); - } - } - *out_is_dir = is_dir; + if (d->d_type == DT_DIR) { + // Known directory. + is_dir = true; + check_with_stat = false; + } else if (d->d_type == DT_LNK || d->d_type == DT_UNKNOWN) { + // We want to treat symlinks to directories as directories. Use stat to resolve it. + check_with_stat = true; + } else { + // Regular file. + is_dir = false; + check_with_stat = false; } +#endif // HAVE_STRUCT_DIRENT_D_TYPE + if (check_with_stat) { + // We couldn't determine the file type from the dirent; check by stat'ing it. + cstring fullpath = wcs2string(dir_path); + fullpath.push_back('/'); + fullpath.append(d->d_name); + struct stat buf; + if (stat(fullpath.c_str(), &buf) != 0) { + is_dir = false; + } else { + is_dir = static_cast(S_ISDIR(buf.st_mode)); + } + } + *out_is_dir = is_dir; return true; } From ca5a4ec1d54a9efcaed16a58c4ea0991a359946c Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 12:52:50 -0700 Subject: [PATCH 048/112] lint: Use early exit/continue --- src/wildcard.cpp | 107 ++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/src/wildcard.cpp b/src/wildcard.cpp index ffd0e6273..43659995f 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -216,22 +216,24 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc, match_acceptable = match_type_shares_prefix(match.type); } - if (match_acceptable && out != NULL) { - // Wildcard complete. - bool full_replacement = match_type_requires_full_replacement(match.type) || - (flags & COMPLETE_REPLACES_TOKEN); - - // If we are not replacing the token, be careful to only store the part of the string - // after the wildcard. - assert(!full_replacement || wcslen(wc) <= wcslen(str)); - wcstring out_completion = full_replacement ? params.orig : str + wcslen(wc); - wcstring out_desc = resolve_description(&out_completion, params.desc, params.desc_func); - - // Note: out_completion may be empty if the completion really is empty, e.g. - // tab-completing 'foo' when a file 'foo' exists. - complete_flags_t local_flags = flags | (full_replacement ? COMPLETE_REPLACES_TOKEN : 0); - append_completion(out, out_completion, out_desc, local_flags, match); + if (!match_acceptable || out == NULL) { + return match_acceptable; } + + // Wildcard complete. + bool full_replacement = + match_type_requires_full_replacement(match.type) || (flags & COMPLETE_REPLACES_TOKEN); + + // If we are not replacing the token, be careful to only store the part of the string after + // the wildcard. + assert(!full_replacement || wcslen(wc) <= wcslen(str)); + wcstring out_completion = full_replacement ? params.orig : str + wcslen(wc); + wcstring out_desc = resolve_description(&out_completion, params.desc, params.desc_func); + + // Note: out_completion may be empty if the completion really is empty, e.g. tab-completing + // 'foo' when a file 'foo' exists. + complete_flags_t local_flags = flags | (full_replacement ? COMPLETE_REPLACES_TOKEN : 0); + append_completion(out, out_completion, out_desc, local_flags, match); return match_acceptable; } else if (next_wc_char_pos > 0) { // Here we have a non-wildcard prefix. Note that we don't do fuzzy matching for stuff before @@ -289,7 +291,10 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc, // We don't even try with this one. return false; } - default: { assert(0 && "Unreachable code reached"); } + default: { + DIE("Unreachable code reached"); + break; + } } assert(0 && "Unreachable code reached"); @@ -322,46 +327,44 @@ bool wildcard_match(const wcstring &str, const wcstring &wc, bool leading_dots_f /// \param err The errno value after a failed stat call on the file. static wcstring file_get_desc(const wcstring &filename, int lstat_res, const struct stat &lbuf, int stat_res, const struct stat &buf, int err) { - if (!lstat_res) { - if (S_ISLNK(lbuf.st_mode)) { - if (!stat_res) { - if (S_ISDIR(buf.st_mode)) { - return COMPLETE_DIRECTORY_SYMLINK_DESC; - } - if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) && waccess(filename, X_OK) == 0) { - // Weird group permissions and other such issues make it non-trivial to - // find out if we can actually execute a file using the result from - // stat. It is much safer to use the access function, since it tells us - // exactly what we want to know. - return COMPLETE_EXEC_LINK_DESC; - } + if (lstat_res) { + return COMPLETE_FILE_DESC; + } - return COMPLETE_SYMLINK_DESC; + if (S_ISLNK(lbuf.st_mode)) { + if (!stat_res) { + if (S_ISDIR(buf.st_mode)) { + return COMPLETE_DIRECTORY_SYMLINK_DESC; + } + if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) && waccess(filename, X_OK) == 0) { + // Weird group permissions and other such issues make it non-trivial to find out if + // we can actually execute a file using the result from stat. It is much safer to + // use the access function, since it tells us exactly what we want to know. + return COMPLETE_EXEC_LINK_DESC; } - if (err == ENOENT) return COMPLETE_ROTTEN_SYMLINK_DESC; - if (err == ELOOP) return COMPLETE_LOOP_SYMLINK_DESC; - // On unknown errors we do nothing. The file will be given the default 'File' - // description or one based on the suffix. - } else if (S_ISCHR(buf.st_mode)) { - return COMPLETE_CHAR_DESC; - } else if (S_ISBLK(buf.st_mode)) { - return COMPLETE_BLOCK_DESC; - } else if (S_ISFIFO(buf.st_mode)) { - return COMPLETE_FIFO_DESC; - } else if (S_ISSOCK(buf.st_mode)) { - return COMPLETE_SOCKET_DESC; - } else if (S_ISDIR(buf.st_mode)) { - return COMPLETE_DIRECTORY_DESC; - } else { - if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXGRP) && waccess(filename, X_OK) == 0) { - // Weird group permissions and other such issues make it non-trivial to find out - // if we can actually execute a file using the result from stat. It is much - // safer to use the access function, since it tells us exactly what we want to - // know. - return COMPLETE_EXEC_DESC; - } + return COMPLETE_SYMLINK_DESC; } + + if (err == ENOENT) return COMPLETE_ROTTEN_SYMLINK_DESC; + if (err == ELOOP) return COMPLETE_LOOP_SYMLINK_DESC; + // On unknown errors we do nothing. The file will be given the default 'File' + // description or one based on the suffix. + } else if (S_ISCHR(buf.st_mode)) { + return COMPLETE_CHAR_DESC; + } else if (S_ISBLK(buf.st_mode)) { + return COMPLETE_BLOCK_DESC; + } else if (S_ISFIFO(buf.st_mode)) { + return COMPLETE_FIFO_DESC; + } else if (S_ISSOCK(buf.st_mode)) { + return COMPLETE_SOCKET_DESC; + } else if (S_ISDIR(buf.st_mode)) { + return COMPLETE_DIRECTORY_DESC; + } else if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXGRP) && waccess(filename, X_OK) == 0) { + // Weird group permissions and other such issues make it non-trivial to find out if we can + // actually execute a file using the result from stat. It is much safer to use the access + // function, since it tells us exactly what we want to know. + return COMPLETE_EXEC_DESC; } return COMPLETE_FILE_DESC; From 77791325950bcb6596bad9e34b6341611db33432 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 14:16:32 -0700 Subject: [PATCH 049/112] lint: Use early exit/continue --- src/reader.cpp | 268 ++++++++++++++++++++++++------------------------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/src/reader.cpp b/src/reader.cpp index 859500233..0d981be16 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1398,125 +1398,127 @@ static bool handle_completions(const std::vector &comp, success = true; } - if (!done) { - fuzzy_match_type_t best_match_type = get_best_match_type(comp); + if (done) { + return success; + } - // Determine whether we are going to replace the token or not. If any commands of the best - // type do not require replacement, then ignore all those that want to use replacement. - bool will_replace_token = true; - for (size_t i = 0; i < comp.size(); i++) { - const completion_t &el = comp.at(i); - if (el.match.type <= best_match_type && !(el.flags & COMPLETE_REPLACES_TOKEN)) { - will_replace_token = false; - break; - } - } + fuzzy_match_type_t best_match_type = get_best_match_type(comp); - // Decide which completions survived. There may be a lot of them; it would be nice if we - // could figure out how to avoid copying them here. - std::vector surviving_completions; - for (size_t i = 0; i < comp.size(); i++) { - const completion_t &el = comp.at(i); - // Ignore completions with a less suitable match type than the best. - if (el.match.type > best_match_type) continue; - - // Only use completions that match replace_token. - bool completion_replace_token = static_cast(el.flags & COMPLETE_REPLACES_TOKEN); - if (completion_replace_token != will_replace_token) continue; - - // Don't use completions that want to replace, if we cannot replace them. - if (completion_replace_token && !reader_can_replace(tok, el.flags)) continue; - - // This completion survived. - surviving_completions.push_back(el); - } - - bool use_prefix = false; - if (match_type_shares_prefix(best_match_type)) { - // Try to find a common prefix to insert among the surviving completions. - wcstring common_prefix; - complete_flags_t flags = 0; - bool prefix_is_partial_completion = false; - for (size_t i = 0; i < surviving_completions.size(); i++) { - const completion_t &el = surviving_completions.at(i); - if (i == 0) { - // First entry, use the whole string. - common_prefix = el.completion; - flags = el.flags; - } else { - // Determine the shared prefix length. - size_t idx, max = mini(common_prefix.size(), el.completion.size()); - for (idx = 0; idx < max; idx++) { - wchar_t ac = common_prefix.at(idx), bc = el.completion.at(idx); - bool matches = (ac == bc); - // If we are replacing the token, allow case to vary. - if (will_replace_token && !matches) { - // Hackish way to compare two strings in a case insensitive way, - // hopefully better than towlower(). - matches = (wcsncasecmp(&ac, &bc, 1) == 0); - } - if (!matches) break; - } - - // idx is now the length of the new common prefix. - common_prefix.resize(idx); - prefix_is_partial_completion = true; - - // Early out if we decide there's no common prefix. - if (idx == 0) break; - } - } - - // Determine if we use the prefix. We use it if it's non-empty and it will actually make - // the command line longer. It may make the command line longer by virtue of not using - // REPLACE_TOKEN (so it always appends to the command line), or by virtue of replacing - // the token but being longer than it. - use_prefix = common_prefix.size() > (will_replace_token ? tok.size() : 0); - assert(!use_prefix || !common_prefix.empty()); - - if (use_prefix) { - // We got something. If more than one completion contributed, then it means we have - // a prefix; don't insert a space after it. - if (prefix_is_partial_completion) flags |= COMPLETE_NO_SPACE; - completion_insert(common_prefix.c_str(), flags); - success = true; - } - } - - if (continue_after_prefix_insertion || !use_prefix) { - // We didn't get a common prefix, or we want to print the list anyways. - size_t len, prefix_start = 0; - wcstring prefix; - parse_util_get_parameter_info(el->text, el->position, NULL, &prefix_start, NULL); - - assert(el->position >= prefix_start); - len = el->position - prefix_start; - - if (will_replace_token || match_type_requires_full_replacement(best_match_type)) { - // No prefix. - prefix.clear(); - } else if (len <= PREFIX_MAX_LEN) { - prefix.append(el->text, prefix_start, len); - } else { - // Append just the end of the string. - prefix = wcstring(&ellipsis_char, 1); - prefix.append(el->text, prefix_start + len - PREFIX_MAX_LEN, PREFIX_MAX_LEN); - } - - wchar_t quote; - parse_util_get_parameter_info(el->text, el->position, "e, NULL, NULL); - // Update the pager data. - data->pager.set_prefix(prefix); - data->pager.set_completions(surviving_completions); - // Invalidate our rendering. - data->current_page_rendering = page_rendering_t(); - // Modify the command line to reflect the new pager. - data->pager_selection_changed(); - reader_repaint_needed(); - success = false; + // Determine whether we are going to replace the token or not. If any commands of the best + // type do not require replacement, then ignore all those that want to use replacement. + bool will_replace_token = true; + for (size_t i = 0; i < comp.size(); i++) { + const completion_t &el = comp.at(i); + if (el.match.type <= best_match_type && !(el.flags & COMPLETE_REPLACES_TOKEN)) { + will_replace_token = false; + break; } } - return success; + + // Decide which completions survived. There may be a lot of them; it would be nice if we could + // figure out how to avoid copying them here. + std::vector surviving_completions; + for (size_t i = 0; i < comp.size(); i++) { + const completion_t &el = comp.at(i); + // Ignore completions with a less suitable match type than the best. + if (el.match.type > best_match_type) continue; + + // Only use completions that match replace_token. + bool completion_replace_token = static_cast(el.flags & COMPLETE_REPLACES_TOKEN); + if (completion_replace_token != will_replace_token) continue; + + // Don't use completions that want to replace, if we cannot replace them. + if (completion_replace_token && !reader_can_replace(tok, el.flags)) continue; + + // This completion survived. + surviving_completions.push_back(el); + } + + bool use_prefix = false; + if (match_type_shares_prefix(best_match_type)) { + // Try to find a common prefix to insert among the surviving completions. + wcstring common_prefix; + complete_flags_t flags = 0; + bool prefix_is_partial_completion = false; + for (size_t i = 0; i < surviving_completions.size(); i++) { + const completion_t &el = surviving_completions.at(i); + if (i == 0) { + // First entry, use the whole string. + common_prefix = el.completion; + flags = el.flags; + } else { + // Determine the shared prefix length. + size_t idx, max = mini(common_prefix.size(), el.completion.size()); + for (idx = 0; idx < max; idx++) { + wchar_t ac = common_prefix.at(idx), bc = el.completion.at(idx); + bool matches = (ac == bc); + // If we are replacing the token, allow case to vary. + if (will_replace_token && !matches) { + // Hackish way to compare two strings in a case insensitive way, + // hopefully better than towlower(). + matches = (wcsncasecmp(&ac, &bc, 1) == 0); + } + if (!matches) break; + } + + // idx is now the length of the new common prefix. + common_prefix.resize(idx); + prefix_is_partial_completion = true; + + // Early out if we decide there's no common prefix. + if (idx == 0) break; + } + } + + // Determine if we use the prefix. We use it if it's non-empty and it will actually make + // the command line longer. It may make the command line longer by virtue of not using + // REPLACE_TOKEN (so it always appends to the command line), or by virtue of replacing + // the token but being longer than it. + use_prefix = common_prefix.size() > (will_replace_token ? tok.size() : 0); + assert(!use_prefix || !common_prefix.empty()); + + if (use_prefix) { + // We got something. If more than one completion contributed, then it means we have + // a prefix; don't insert a space after it. + if (prefix_is_partial_completion) flags |= COMPLETE_NO_SPACE; + completion_insert(common_prefix.c_str(), flags); + success = true; + } + } + + if (!continue_after_prefix_insertion && use_prefix) { + return success; + } + + // We didn't get a common prefix, or we want to print the list anyways. + size_t len, prefix_start = 0; + wcstring prefix; + parse_util_get_parameter_info(el->text, el->position, NULL, &prefix_start, NULL); + + assert(el->position >= prefix_start); + len = el->position - prefix_start; + + if (will_replace_token || match_type_requires_full_replacement(best_match_type)) { + prefix.clear(); // no prefix + } else if (len <= PREFIX_MAX_LEN) { + prefix.append(el->text, prefix_start, len); + } else { + // Append just the end of the string. + prefix = wcstring(&ellipsis_char, 1); + prefix.append(el->text, prefix_start + len - PREFIX_MAX_LEN, PREFIX_MAX_LEN); + } + + wchar_t quote; + parse_util_get_parameter_info(el->text, el->position, "e, NULL, NULL); + // Update the pager data. + data->pager.set_prefix(prefix); + data->pager.set_completions(surviving_completions); + // Invalidate our rendering. + data->current_page_rendering = page_rendering_t(); + // Modify the command line to reflect the new pager. + data->pager_selection_changed(); + reader_repaint_needed(); + return false; } /// Return true if we believe ourselves to be orphaned. loop_count is how many times we've tried to @@ -2652,26 +2654,24 @@ const wchar_t *reader_readline(int nchars) { } case R_BACKWARD_KILL_LINE: { editable_line_t *el = data->active_edit_line(); - if (el->position > 0) { - const wchar_t *buff = el->text.c_str(); - const wchar_t *end = &buff[el->position]; - const wchar_t *begin = end; - - begin--; // make sure we delete at least one character (see issue #580) - - // Delete until we hit a newline, or the beginning of the string. - while (begin > buff && *begin != L'\n') begin--; - - // If we landed on a newline, don't delete it. - if (*begin == L'\n') begin++; - - assert(end >= begin); - size_t len = maxi(end - begin, 1); - begin = end - len; - - reader_kill(el, begin - buff, len, KILL_PREPEND, - last_char != R_BACKWARD_KILL_LINE); + if (el->position <= 0) { + break; } + const wchar_t *buff = el->text.c_str(); + const wchar_t *end = &buff[el->position]; + const wchar_t *begin = end; + + begin--; // make sure we delete at least one character (see issue #580) + + // Delete until we hit a newline, or the beginning of the string. + while (begin > buff && *begin != L'\n') begin--; + + // If we landed on a newline, don't delete it. + if (*begin == L'\n') begin++; + assert(end >= begin); + size_t len = maxi(end - begin, 1); + begin = end - len; + reader_kill(el, begin - buff, len, KILL_PREPEND, last_char != R_BACKWARD_KILL_LINE); break; } case R_KILL_WHOLE_LINE: { From 4fe2a2921f91c1d605277a5210e37c78ac022c21 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 14:37:54 -0700 Subject: [PATCH 050/112] lint: Use early exit/continue --- src/proc.cpp | 96 +++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/proc.cpp b/src/proc.cpp index f415df14d..00b1db12d 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -562,58 +562,60 @@ int job_reap(bool allow_interactive) { proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, p->pid, (WIFSIGNALED(s) ? -1 : WEXITSTATUS(s))); - // Ignore signal SIGPIPE.We issue it ourselves to the pipe writer when the pipe - // reader dies. - if (WIFSIGNALED(s) && WTERMSIG(s) != SIGPIPE) { - int proc_is_job = ((p == j->first_process) && (p->next == 0)); - if (proc_is_job) job_set_flag(j, JOB_NOTIFIED, 1); - if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) { - // Print nothing if we get SIGINT in the foreground process group, to avoid - // spamming obvious stuff on the console (#1119). If we get SIGINT for the - // foreground process, assume the user typed ^C and can see it working. It's - // possible they didn't, and the signal was delivered via pkill, etc., but - // the SIGINT/SIGTERM distinction is precisely to allow INT to be from a UI - // and TERM to be programmatic, so this assumption is keeping with the - // design of signals. If echoctl is on, then the terminal will have written - // ^C to the console. If off, it won't have. We don't echo ^C either way, so - // as to respect the user's preference. - if (WTERMSIG(p->status) != SIGINT || !job_get_flag(j, JOB_FOREGROUND)) { - if (proc_is_job) { - // We want to report the job number, unless it's the only job, in - // which case we don't need to. - const wcstring job_number_desc = - (job_count == 1) ? wcstring() - : format_string(L"Job %d, ", j->job_id); - fwprintf(stdout, _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"), - program_name, job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); - } else { - const wcstring job_number_desc = - (job_count == 1) ? wcstring() - : format_string(L"from job %d, ", j->job_id); - fwprintf(stdout, _(L"%ls: Process %d, \'%ls\' %ls\'%ls\' " - L"terminated by signal %ls (%ls)"), - program_name, p->pid, p->argv0(), job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); - } + // Ignore signal SIGPIPE.We issue it ourselves to the pipe writer when the pipe reader + // dies. + if (!WIFSIGNALED(s) || WTERMSIG(s) == SIGPIPE) { + continue; + } - if (cur_term != NULL) - tputs(clr_eol, 1, &writeb); - else - fwprintf(stdout, L"\x1b[K"); // no term set up - do clr_eol manually + // Handle signals other than SIGPIPE. + int proc_is_job = ((p == j->first_process) && (p->next == 0)); + if (proc_is_job) job_set_flag(j, JOB_NOTIFIED, 1); + if (job_get_flag(j, JOB_SKIP_NOTIFICATION)) { + continue; + } - fwprintf(stdout, L"\n"); - } - found = 1; + // Print nothing if we get SIGINT in the foreground process group, to avoid spamming + // obvious stuff on the console (#1119). If we get SIGINT for the foreground + // process, assume the user typed ^C and can see it working. It's possible they + // didn't, and the signal was delivered via pkill, etc., but the SIGINT/SIGTERM + // distinction is precisely to allow INT to be from a UI + // and TERM to be programmatic, so this assumption is keeping with the design of + // signals. If echoctl is on, then the terminal will have written ^C to the console. + // If off, it won't have. We don't echo ^C either way, so as to respect the user's + // preference. + if (WTERMSIG(p->status) != SIGINT || !job_get_flag(j, JOB_FOREGROUND)) { + if (proc_is_job) { + // We want to report the job number, unless it's the only job, in which case + // we don't need to. + const wcstring job_number_desc = + (job_count == 1) ? wcstring() : format_string(L"Job %d, ", j->job_id); + fwprintf(stdout, _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"), + program_name, job_number_desc.c_str(), + truncate_command(j->command()).c_str(), + sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); + } else { + const wcstring job_number_desc = + (job_count == 1) ? wcstring() + : format_string(L"from job %d, ", j->job_id); + fwprintf(stdout, _(L"%ls: Process %d, \'%ls\' %ls\'%ls\' " + L"terminated by signal %ls (%ls)"), + program_name, p->pid, p->argv0(), job_number_desc.c_str(), + truncate_command(j->command()).c_str(), + sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); } - // Clear status so it is not reported more than once. - p->status = 0; + if (cur_term != NULL) { + tputs(clr_eol, 1, &writeb); + } else { + fwprintf(stdout, L"\x1b[K"); // no term set up - do clr_eol manually + } + fwprintf(stdout, L"\n"); } + found = 1; + p->status = 0; // clear status so it is not reported more than once } // If all processes have completed, tell the user the job has completed and delete it from From 225caa2fe83505ba0002ea8adf336b9d58a41a6f Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 14:49:22 -0700 Subject: [PATCH 051/112] lint: Use early exit/continue --- src/parser.cpp | 67 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 9406b3b9f..9e71ae062 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -270,45 +270,46 @@ static void print_profile(const std::vector &items, FILE *out) int my_time; me = items.at(pos); - if (!me->skipped) { - my_time = me->parse + me->exec; + if (me->skipped) { + continue; + } - for (i = pos + 1; i < items.size(); i++) { - prev = items.at(i); - if (prev->skipped) { - continue; - } - - if (prev->level <= me->level) { - break; - } - - if (prev->level > me->level + 1) { - continue; - } - - my_time -= prev->parse; - my_time -= prev->exec; + my_time = me->parse + me->exec; + for (i = pos + 1; i < items.size(); i++) { + prev = items.at(i); + if (prev->skipped) { + continue; + } + if (prev->level <= me->level) { + break; + } + if (prev->level > me->level + 1) { + continue; } - if (me->cmd.size() > 0) { - if (fwprintf(out, L"%d\t%d\t", my_time, me->parse + me->exec) < 0) { - wperror(L"fwprintf"); - return; - } + my_time -= prev->parse + prev->exec; + } - for (i = 0; i < me->level; i++) { - if (fwprintf(out, L"-") < 0) { - wperror(L"fwprintf"); - return; - } - } - if (fwprintf(out, L"> %ls\n", me->cmd.c_str()) < 0) { - wperror(L"fwprintf"); - return; - } + if (me->cmd.size() == 0) { + continue; + } + + if (fwprintf(out, L"%d\t%d\t", my_time, me->parse + me->exec) < 0) { + wperror(L"fwprintf"); + return; + } + + for (i = 0; i < me->level; i++) { + if (fwprintf(out, L"-") < 0) { + wperror(L"fwprintf"); + return; } } + + if (fwprintf(out, L"> %ls\n", me->cmd.c_str()) < 0) { + wperror(L"fwprintf"); + return; + } } } From eab836864e79053a5396bcd499da1e967f7f3d27 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 14:52:36 -0700 Subject: [PATCH 052/112] lint: Use early exit/continue --- src/history.cpp | 66 +++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/history.cpp b/src/history.cpp index 7c33166ef..82c894aaa 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -939,43 +939,45 @@ void history_t::populate_from_mmap(void) { /// if successful. Returns the mapped memory region by reference. bool history_t::map_file(const wcstring &name, const char **out_map_start, size_t *out_map_len, file_id_t *file_id) { - bool result = false; wcstring filename = history_filename(name, L""); - if (!filename.empty()) { - int fd = wopen_cloexec(filename, O_RDONLY); - if (fd >= 0) { - // Get the file ID if requested. - if (file_id != NULL) *file_id = file_id_for_fd(fd); + if (filename.empty()) { + return false; + } - // Take a read lock to guard against someone else appending. This is released when the - // file is closed (below). We will read the file after releasing the lock, but that's - // not a problem, because we never modify already written data. In short, the purpose of - // this lock is to ensure we don't see the file size change mid-update. - // - // We may fail to lock (e.g. on lockless NFS - see - // https://github.com/fish-shell/fish-shell/issues/685 ). In that case, we proceed as - // if it did not fail. The risk is that we may get an incomplete history item; this - // is unlikely because we only treat an item as valid if it has a terminating - // newline. - // - // Simulate a failing lock in chaos_mode. - if (!chaos_mode) history_file_lock(fd, F_RDLCK); - off_t len = lseek(fd, 0, SEEK_END); - if (len != (off_t)-1) { - size_t mmap_length = (size_t)len; - if (lseek(fd, 0, SEEK_SET) == 0) { - char *mmap_start; - if ((mmap_start = (char *)mmap(0, mmap_length, PROT_READ, MAP_PRIVATE, fd, - 0)) != MAP_FAILED) { - result = true; - *out_map_start = mmap_start; - *out_map_len = mmap_length; - } - } + int fd = wopen_cloexec(filename, O_RDONLY); + if (fd == -1) { + return false; + } + + bool result = false; + // Get the file ID if requested. + if (file_id != NULL) *file_id = file_id_for_fd(fd); + + // Take a read lock to guard against someone else appending. This is released when the file + // is closed (below). We will read the file after releasing the lock, but that's not a + // problem, because we never modify already written data. In short, the purpose of this lock + // is to ensure we don't see the file size change mid-update. + // + // We may fail to lock (e.g. on lockless NFS - see issue #685. In that case, we proceed as + // if it did not fail. The risk is that we may get an incomplete history item; this is + // unlikely because we only treat an item as valid if it has a terminating newline. + // + // Simulate a failing lock in chaos_mode. + if (!chaos_mode) history_file_lock(fd, F_RDLCK); + off_t len = lseek(fd, 0, SEEK_END); + if (len != (off_t)-1) { + size_t mmap_length = (size_t)len; + if (lseek(fd, 0, SEEK_SET) == 0) { + char *mmap_start; + if ((mmap_start = (char *)mmap(0, mmap_length, PROT_READ, MAP_PRIVATE, fd, + 0)) != MAP_FAILED) { + result = true; + *out_map_start = mmap_start; + *out_map_len = mmap_length; } - close(fd); } } + close(fd); return result; } From 6192e2453e632b68cccd08882d7677c7b4b94f36 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 15:05:41 -0700 Subject: [PATCH 053/112] lint: Use early exit/continue --- src/highlight.cpp | 220 +++++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 109 deletions(-) diff --git a/src/highlight.cpp b/src/highlight.cpp index 1f1dcac52..0558d9336 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -122,73 +122,73 @@ bool is_potential_path(const wcstring &potential_path_fragment, const wcstring_l } } - if (!has_magic && !clean_potential_path_fragment.empty()) { - // Don't test the same path multiple times, which can happen if the path is absolute and the - // CDPATH contains multiple entries. - std::set checked_paths; + if (has_magic || clean_potential_path_fragment.empty()) { + return result; + } - // Keep a cache of which paths / filesystems are case sensitive. - case_sensitivity_cache_t case_sensitivity_cache; + // Don't test the same path multiple times, which can happen if the path is absolute and the + // CDPATH contains multiple entries. + std::set checked_paths; - for (size_t wd_idx = 0; wd_idx < directories.size() && !result; wd_idx++) { - const wcstring &wd = directories.at(wd_idx); + // Keep a cache of which paths / filesystems are case sensitive. + case_sensitivity_cache_t case_sensitivity_cache; - const wcstring abs_path = - path_apply_working_directory(clean_potential_path_fragment, wd); + for (size_t wd_idx = 0; wd_idx < directories.size() && !result; wd_idx++) { + const wcstring &wd = directories.at(wd_idx); - // Skip this if it's empty or we've already checked it. - if (abs_path.empty() || checked_paths.count(abs_path)) continue; - checked_paths.insert(abs_path); + const wcstring abs_path = path_apply_working_directory(clean_potential_path_fragment, wd); - // If we end with a slash, then it must be a directory. - bool must_be_full_dir = abs_path.at(abs_path.size() - 1) == L'/'; - if (must_be_full_dir) { - struct stat buf; - if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode)) { - result = true; - } - } else { - // We do not end with a slash; it does not have to be a directory. - DIR *dir = NULL; - const wcstring dir_name = wdirname(abs_path); - const wcstring filename_fragment = wbasename(abs_path); - if (dir_name == L"/" && filename_fragment == L"/") { - // cd ///.... No autosuggestion. - result = true; - } else if ((dir = wopendir(dir_name))) { - // Check if we're case insensitive. - const bool do_case_insensitive = - fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache); + // Skip this if it's empty or we've already checked it. + if (abs_path.empty() || checked_paths.count(abs_path)) continue; + checked_paths.insert(abs_path); - wcstring matched_file; + // If we end with a slash, then it must be a directory. + bool must_be_full_dir = abs_path.at(abs_path.size() - 1) == L'/'; + if (must_be_full_dir) { + struct stat buf; + if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode)) { + result = true; + } + } else { + // We do not end with a slash; it does not have to be a directory. + DIR *dir = NULL; + const wcstring dir_name = wdirname(abs_path); + const wcstring filename_fragment = wbasename(abs_path); + if (dir_name == L"/" && filename_fragment == L"/") { + // cd ///.... No autosuggestion. + result = true; + } else if ((dir = wopendir(dir_name))) { + // Check if we're case insensitive. + const bool do_case_insensitive = + fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache); - // We opened the dir_name; look for a string where the base name prefixes it - // Don't ask for the is_dir value unless we care, because it can cause extra - // filesystem access. - wcstring ent; - bool is_dir = false; - while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL)) { - // Maybe skip directories. - if (require_dir && !is_dir) { - continue; - } + wcstring matched_file; - if (string_prefixes_string(filename_fragment, ent) || - (do_case_insensitive && - string_prefixes_string_case_insensitive(filename_fragment, ent))) { - // We matched. - matched_file = ent; - break; - } + // We opened the dir_name; look for a string where the base name prefixes it Don't + // ask for the is_dir value unless we care, because it can cause extra filesystem + // access. + wcstring ent; + bool is_dir = false; + while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL)) { + // Maybe skip directories. + if (require_dir && !is_dir) { + continue; } - closedir(dir); - // We succeeded if we found a match. - result = !matched_file.empty(); + if (string_prefixes_string(filename_fragment, ent) || + (do_case_insensitive && + string_prefixes_string_case_insensitive(filename_fragment, ent))) { + matched_file = ent; // we matched + break; + } } + closedir(dir); + + result = !matched_file.empty(); // we succeeded if we found a match } } } + return result; } @@ -354,24 +354,25 @@ bool autosuggest_validate_from_history(const history_item_t &item, } } - // If not handled specially, handle it here. - if (!handled) { - bool cmd_ok = false; + if (handled) { + return suggestionOK; + } - if (path_get_path(parsed_command, NULL)) { - cmd_ok = true; - } else if (builtin_exists(parsed_command) || - function_exists_no_autoload(parsed_command, vars)) { - cmd_ok = true; - } + // Not handled specially so handle it here. + bool cmd_ok = false; + if (path_get_path(parsed_command, NULL)) { + cmd_ok = true; + } else if (builtin_exists(parsed_command) || + function_exists_no_autoload(parsed_command, vars)) { + cmd_ok = true; + } - if (cmd_ok) { - const path_list_t &paths = item.get_required_paths(); - if (paths.empty()) { - suggestionOK = true; - } else { - suggestionOK = detector.paths_are_valid(paths); - } + if (cmd_ok) { + const path_list_t &paths = item.get_required_paths(); + if (paths.empty()) { + suggestionOK = true; + } else { + suggestionOK = detector.paths_are_valid(paths); } } @@ -1093,26 +1094,27 @@ const highlighter_t::color_array_t &highlighter_t::highlight() { // Color the command. const parse_node_t *cmd_node = parse_tree.get_child(node, 0, parse_token_type_string); - if (cmd_node != NULL && cmd_node->has_source()) { - bool is_valid_cmd = false; - if (!this->io_ok) { - // We cannot check if the command is invalid, so just assume it's valid. - is_valid_cmd = true; - } else { - // Check to see if the command is valid. - wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length); - - // Try expanding it. If we cannot, it's an error. - bool expanded = expand_one( - cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS); - if (expanded && !has_expand_reserved(cmd)) { - is_valid_cmd = - command_is_valid(cmd, decoration, working_directory, vars); - } - } - this->color_node(*cmd_node, - is_valid_cmd ? highlight_spec_command : highlight_spec_error); + if (cmd_node == NULL || !cmd_node->has_source()) { + break; // not much as we can do without a node that has source text } + + bool is_valid_cmd = false; + if (!this->io_ok) { + // We cannot check if the command is invalid, so just assume it's valid. + is_valid_cmd = true; + } else { + // Check to see if the command is valid. + wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length); + + // Try expanding it. If we cannot, it's an error. + bool expanded = expand_one( + cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS); + if (expanded && !has_expand_reserved(cmd)) { + is_valid_cmd = command_is_valid(cmd, decoration, working_directory, vars); + } + } + this->color_node(*cmd_node, + is_valid_cmd ? highlight_spec_command : highlight_spec_error); break; } case symbol_arguments_or_redirections_list: @@ -1141,29 +1143,29 @@ const highlighter_t::color_array_t &highlighter_t::highlight() { } } - if (this->io_ok && this->cursor_pos <= this->buff.size()) { - // If the cursor is over an argument, and that argument is a valid path, underline it. - for (parse_node_tree_t::const_iterator iter = parse_tree.begin(); iter != parse_tree.end(); - ++iter) { - const parse_node_t &node = *iter; + if (!this->io_ok || this->cursor_pos > this->buff.size()) { + return color_array; + } - // Must be an argument with source. - if (node.type != symbol_argument || !node.has_source()) continue; + // If the cursor is over an argument, and that argument is a valid path, underline it. + for (parse_node_tree_t::const_iterator iter = parse_tree.begin(); iter != parse_tree.end(); + ++iter) { + const parse_node_t &node = *iter; - // See if this node contains the cursor. We check <= source_length so that, when - // backspacing (and the cursor is just beyond the last token), we may still underline - // it. - if (this->cursor_pos >= node.source_start && - this->cursor_pos - node.source_start <= node.source_length && - node_is_potential_path(buff, node, working_directory)) { - // It is, underline it. - for (size_t i = node.source_start; i < node.source_start + node.source_length; - i++) { - // Don't color highlight_spec_error because it looks dorky. For example, - // trying to cd into a non-directory would show an underline and also red. - if (highlight_get_primary(this->color_array.at(i)) != highlight_spec_error) { - this->color_array.at(i) |= highlight_modifier_valid_path; - } + // Must be an argument with source. + if (node.type != symbol_argument || !node.has_source()) continue; + + // See if this node contains the cursor. We check <= source_length so that, when backspacing + // (and the cursor is just beyond the last token), we may still underline it. + if (this->cursor_pos >= node.source_start && + this->cursor_pos - node.source_start <= node.source_length && + node_is_potential_path(buff, node, working_directory)) { + // It is, underline it. + for (size_t i = node.source_start; i < node.source_start + node.source_length; i++) { + // Don't color highlight_spec_error because it looks dorky. For example, + // trying to cd into a non-directory would show an underline and also red. + if (highlight_get_primary(this->color_array.at(i)) != highlight_spec_error) { + this->color_array.at(i) |= highlight_modifier_valid_path; } } } From 6c3900ff642914dbb3172c54ae449f7b820dddd7 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 15:37:16 -0700 Subject: [PATCH 054/112] lint: Use early exit/continue --- src/expand.cpp | 420 +++++++++++++++++++++++++------------------------ 1 file changed, 214 insertions(+), 206 deletions(-) diff --git a/src/expand.cpp b/src/expand.cpp index 04937de30..ef1cd613f 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -435,7 +435,7 @@ struct find_job_data_t { /// The following function is invoked on the main thread, because the job list is not thread safe. /// It should search the job list for something matching the given proc, and then return 1 to stop -/// the search, 0 to continue it . +/// the search, 0 to continue it. static int find_job(const struct find_job_data_t *info) { ASSERT_IS_MAIN_THREAD(); @@ -494,42 +494,45 @@ static int find_job(const struct find_job_data_t *info) { found = 1; } - if (!found) { - job_iterator_t jobs; - while ((j = jobs.next())) { - if (j->command_is_empty()) continue; + if (found) { + return found; + } - size_t offset; - if (match_pid(j->command(), proc, &offset)) { - if (flags & EXPAND_FOR_COMPLETIONS) { - append_completion(&completions, j->command_wcstr() + offset + wcslen(proc), - COMPLETE_JOB_DESC, 0); - } else { - append_completion(&completions, to_string(j->pgid)); - found = 1; - } + job_iterator_t jobs; + while ((j = jobs.next())) { + if (j->command_is_empty()) continue; + + size_t offset; + if (match_pid(j->command(), proc, &offset)) { + if (flags & EXPAND_FOR_COMPLETIONS) { + append_completion(&completions, j->command_wcstr() + offset + wcslen(proc), + COMPLETE_JOB_DESC, 0); + } else { + append_completion(&completions, to_string(j->pgid)); + found = 1; } } + } - if (!found) { - jobs.reset(); - while ((j = jobs.next())) { - process_t *p; - if (j->command_is_empty()) continue; - for (p = j->first_process; p; p = p->next) { - if (p->actual_cmd.empty()) continue; + if (found) { + return found; + } - size_t offset; - if (match_pid(p->actual_cmd, proc, &offset)) { - if (flags & EXPAND_FOR_COMPLETIONS) { - append_completion(&completions, - wcstring(p->actual_cmd, offset + wcslen(proc)), - COMPLETE_CHILD_PROCESS_DESC, 0); - } else { - append_completion(&completions, to_string(p->pid), L"", 0); - found = 1; - } - } + jobs.reset(); + while ((j = jobs.next())) { + process_t *p; + if (j->command_is_empty()) continue; + for (p = j->first_process; p; p = p->next) { + if (p->actual_cmd.empty()) continue; + + size_t offset; + if (match_pid(p->actual_cmd, proc, &offset)) { + if (flags & EXPAND_FOR_COMPLETIONS) { + append_completion(&completions, wcstring(p->actual_cmd, offset + wcslen(proc)), + COMPLETE_CHILD_PROCESS_DESC, 0); + } else { + append_completion(&completions, to_string(p->pid), L"", 0); + found = 1; } } } @@ -746,193 +749,196 @@ static int expand_variables(const wcstring &instr, std::vector *ou for (long i = last_idx - 1; (i >= 0) && is_ok && !empty; i--) { const wchar_t c = instr.at(i); - if ((c == VARIABLE_EXPAND) || (c == VARIABLE_EXPAND_SINGLE)) { - size_t start_pos = i + 1; - size_t stop_pos; - long var_len; - int is_single = (c == VARIABLE_EXPAND_SINGLE); + if (c != VARIABLE_EXPAND && c != VARIABLE_EXPAND_SINGLE) { + continue; + } - stop_pos = start_pos; - while (stop_pos < insize) { - const wchar_t nc = instr.at(stop_pos); - if (nc == VARIABLE_EXPAND_EMPTY) { - stop_pos++; - break; - } - if (!wcsvarchr(nc)) break; + long var_len; + int is_single = (c == VARIABLE_EXPAND_SINGLE); + size_t start_pos = i + 1; + size_t stop_pos = start_pos; + while (stop_pos < insize) { + const wchar_t nc = instr.at(stop_pos); + if (nc == VARIABLE_EXPAND_EMPTY) { stop_pos++; - } - - // printf( "Stop for '%c'\n", in[stop_pos]); - var_len = stop_pos - start_pos; - - if (var_len == 0) { - if (errors) { - parse_util_expand_variable_error(instr, 0 /* global_token_pos */, i, errors); - } - - is_ok = false; break; } + if (!wcsvarchr(nc)) break; - var_tmp.append(instr, start_pos, var_len); - env_var_t var_val; - if (var_len == 1 && var_tmp[0] == VARIABLE_EXPAND_EMPTY) { - var_val = env_var_t::missing_var(); - } else { - var_val = expand_var(var_tmp.c_str()); + stop_pos++; + } + + // printf( "Stop for '%c'\n", in[stop_pos]); + var_len = stop_pos - start_pos; + + if (var_len == 0) { + if (errors) { + parse_util_expand_variable_error(instr, 0 /* global_token_pos */, i, errors); } - if (!var_val.missing()) { - int all_vars = 1; - wcstring_list_t var_item_list; + is_ok = false; + break; + } - if (is_ok) { - tokenize_variable_array(var_val, var_item_list); + var_tmp.append(instr, start_pos, var_len); + env_var_t var_val; + if (var_len == 1 && var_tmp[0] == VARIABLE_EXPAND_EMPTY) { + var_val = env_var_t::missing_var(); + } else { + var_val = expand_var(var_tmp.c_str()); + } - const size_t slice_start = stop_pos; - if (slice_start < insize && instr.at(slice_start) == L'[') { - wchar_t *slice_end; - size_t bad_pos; - all_vars = 0; - const wchar_t *in = instr.c_str(); - bad_pos = parse_slice(in + slice_start, &slice_end, var_idx_list, - var_pos_list, var_item_list.size()); - if (bad_pos != 0) { - append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value"); + if (!var_val.missing()) { + int all_vars = 1; + wcstring_list_t var_item_list; + + if (is_ok) { + tokenize_variable_array(var_val, var_item_list); + + const size_t slice_start = stop_pos; + if (slice_start < insize && instr.at(slice_start) == L'[') { + wchar_t *slice_end; + size_t bad_pos; + all_vars = 0; + const wchar_t *in = instr.c_str(); + bad_pos = parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, + var_item_list.size()); + if (bad_pos != 0) { + append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value"); + is_ok = false; + break; + } + stop_pos = (slice_end - in); + } + + if (!all_vars) { + wcstring_list_t string_values(var_idx_list.size()); + for (size_t j = 0; j < var_idx_list.size(); j++) { + long tmp = var_idx_list.at(j); + // Check that we are within array bounds. If not, truncate the list to + // exit. + if (tmp < 1 || (size_t)tmp > var_item_list.size()) { + size_t var_src_pos = var_pos_list.at(j); + // The slice was parsed starting at stop_pos, so we have to add that + // to the error position. + append_syntax_error(errors, slice_start + var_src_pos, + ARRAY_BOUNDS_ERR); is_ok = false; + var_idx_list.resize(j); break; + } else { + // Replace each index in var_idx_list inplace with the string value + // at the specified index. + // al_set( var_idx_list, j, wcsdup((const wchar_t *)al_get( + // &var_item_list, tmp-1 ) ) ); + string_values.at(j) = var_item_list.at(tmp - 1); } - stop_pos = (slice_end - in); } - if (!all_vars) { - wcstring_list_t string_values(var_idx_list.size()); - for (size_t j = 0; j < var_idx_list.size(); j++) { - long tmp = var_idx_list.at(j); - // Check that we are within array bounds. If not, truncate the list to - // exit. - if (tmp < 1 || (size_t)tmp > var_item_list.size()) { - size_t var_src_pos = var_pos_list.at(j); - // The slice was parsed starting at stop_pos, so we have to add that - // to the error position. - append_syntax_error(errors, slice_start + var_src_pos, - ARRAY_BOUNDS_ERR); - is_ok = false; - var_idx_list.resize(j); - break; - } else { - // Replace each index in var_idx_list inplace with the string value - // at the specified index. - // al_set( var_idx_list, j, wcsdup((const wchar_t *)al_get( - // &var_item_list, tmp-1 ) ) ); - string_values.at(j) = var_item_list.at(tmp - 1); - } - } - - // string_values is the new var_item_list. - var_item_list.swap(string_values); - } - } - - if (is_ok) { - if (is_single) { - wcstring res(instr, 0, i); - if (i > 0) { - if (instr.at(i - 1) != VARIABLE_EXPAND_SINGLE) { - res.push_back(INTERNAL_SEPARATOR); - } else if (var_item_list.empty() || var_item_list.front().empty()) { - // First expansion is empty, but we need to recursively expand. - res.push_back(VARIABLE_EXPAND_EMPTY); - } - } - - for (size_t j = 0; j < var_item_list.size(); j++) { - const wcstring &next = var_item_list.at(j); - if (is_ok) { - if (j != 0) res.append(L" "); - res.append(next); - } - } - assert(stop_pos <= insize); - res.append(instr, stop_pos, insize - stop_pos); - is_ok &= expand_variables(res, out, i, errors); - } else { - for (size_t j = 0; j < var_item_list.size(); j++) { - const wcstring &next = var_item_list.at(j); - if (is_ok && (i == 0) && stop_pos == insize) { - append_completion(out, next); - } else { - if (is_ok) { - wcstring new_in; - new_in.append(instr, 0, i); - - if (i > 0) { - if (instr.at(i - 1) != VARIABLE_EXPAND) { - new_in.push_back(INTERNAL_SEPARATOR); - } else if (next.empty()) { - new_in.push_back(VARIABLE_EXPAND_EMPTY); - } - } - assert(stop_pos <= insize); - new_in.append(next); - new_in.append(instr, stop_pos, insize - stop_pos); - is_ok &= expand_variables(new_in, out, i, errors); - } - } - } - } + // string_values is the new var_item_list. + var_item_list.swap(string_values); } + } + if (!is_ok) { return is_ok; } - // Even with no value, we still need to parse out slice syntax. Behave as though we - // had 1 value, so $foo[1] always works. - const size_t slice_start = stop_pos; - if (slice_start < insize && instr.at(slice_start) == L'[') { - const wchar_t *in = instr.c_str(); - wchar_t *slice_end; - size_t bad_pos; - - bad_pos = parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, 1); - if (bad_pos != 0) { - append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value"); - is_ok = 0; - return is_ok; - } - stop_pos = (slice_end - in); - - // Validate that the parsed indexes are valid. - for (size_t j = 0; j < var_idx_list.size(); j++) { - long tmp = var_idx_list.at(j); - if (tmp != 1) { - size_t var_src_pos = var_pos_list.at(j); - append_syntax_error(errors, slice_start + var_src_pos, ARRAY_BOUNDS_ERR); - is_ok = 0; - return is_ok; + if (is_single) { + wcstring res(instr, 0, i); + if (i > 0) { + if (instr.at(i - 1) != VARIABLE_EXPAND_SINGLE) { + res.push_back(INTERNAL_SEPARATOR); + } else if (var_item_list.empty() || var_item_list.front().empty()) { + // First expansion is empty, but we need to recursively expand. + res.push_back(VARIABLE_EXPAND_EMPTY); } } - } - // Expand a non-existing variable. - if (c == VARIABLE_EXPAND) { - // Regular expansion, i.e. expand this argument to nothing. - empty = true; - } else { - // Expansion to single argument. - wcstring res; - res.append(instr, 0, i); - if (i > 0 && instr.at(i - 1) == VARIABLE_EXPAND_SINGLE) { - res.push_back(VARIABLE_EXPAND_EMPTY); + for (size_t j = 0; j < var_item_list.size(); j++) { + const wcstring &next = var_item_list.at(j); + if (is_ok) { + if (j != 0) res.append(L" "); + res.append(next); + } } assert(stop_pos <= insize); res.append(instr, stop_pos, insize - stop_pos); - is_ok &= expand_variables(res, out, i, errors); + } else { + for (size_t j = 0; j < var_item_list.size(); j++) { + const wcstring &next = var_item_list.at(j); + if (is_ok && i == 0 && stop_pos == insize) { + append_completion(out, next); + } else { + if (is_ok) { + wcstring new_in; + new_in.append(instr, 0, i); + + if (i > 0) { + if (instr.at(i - 1) != VARIABLE_EXPAND) { + new_in.push_back(INTERNAL_SEPARATOR); + } else if (next.empty()) { + new_in.push_back(VARIABLE_EXPAND_EMPTY); + } + } + assert(stop_pos <= insize); + new_in.append(next); + new_in.append(instr, stop_pos, insize - stop_pos); + is_ok &= expand_variables(new_in, out, i, errors); + } + } + } + } + + return is_ok; + } + + // Even with no value, we still need to parse out slice syntax. Behave as though we + // had 1 value, so $foo[1] always works. + const size_t slice_start = stop_pos; + if (slice_start < insize && instr.at(slice_start) == L'[') { + const wchar_t *in = instr.c_str(); + wchar_t *slice_end; + size_t bad_pos; + + bad_pos = parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, 1); + if (bad_pos != 0) { + append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value"); + is_ok = 0; return is_ok; } + stop_pos = (slice_end - in); + + // Validate that the parsed indexes are valid. + for (size_t j = 0; j < var_idx_list.size(); j++) { + long tmp = var_idx_list.at(j); + if (tmp != 1) { + size_t var_src_pos = var_pos_list.at(j); + append_syntax_error(errors, slice_start + var_src_pos, ARRAY_BOUNDS_ERR); + is_ok = 0; + return is_ok; + } + } + } + + // Expand a non-existing variable. + if (c == VARIABLE_EXPAND) { + // Regular expansion, i.e. expand this argument to nothing. + empty = true; + } else { + // Expansion to single argument. + wcstring res; + res.append(instr, 0, i); + if (i > 0 && instr.at(i - 1) == VARIABLE_EXPAND_SINGLE) { + res.push_back(VARIABLE_EXPAND_EMPTY); + } + assert(stop_pos <= insize); + res.append(instr, stop_pos, insize - stop_pos); + + is_ok &= expand_variables(res, out, i, errors); + return is_ok; } } @@ -1543,24 +1549,26 @@ static std::string escape_single_quoted_hack_hack_hack_hack(const char *str) { bool fish_xdm_login_hack_hack_hack_hack(std::vector *cmds, int argc, const char *const *argv) { - bool result = false; - if (cmds && cmds->size() == 1) { - const std::string &cmd = cmds->at(0); - if (cmd == "exec \"${@}\"" || cmd == "exec \"$@\"") { - // We're going to construct a new command that starts with exec, and then has the - // remaining arguments escaped. - std::string new_cmd = "exec"; - for (int i = 1; i < argc; i++) { - const char *arg = argv[i]; - if (arg) { - new_cmd.push_back(' '); - new_cmd.append(escape_single_quoted_hack_hack_hack_hack(arg)); - } - } + if (!cmds || cmds->size() != 1) { + return false; + } - cmds->at(0) = new_cmd; - result = true; + bool result = false; + const std::string &cmd = cmds->at(0); + if (cmd == "exec \"${@}\"" || cmd == "exec \"$@\"") { + // We're going to construct a new command that starts with exec, and then has the + // remaining arguments escaped. + std::string new_cmd = "exec"; + for (int i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (arg) { + new_cmd.push_back(' '); + new_cmd.append(escape_single_quoted_hack_hack_hack_hack(arg)); + } } + + cmds->at(0) = new_cmd; + result = true; } return result; } From 26c1430e82955574b6b769538893498a83609929 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 16:04:13 -0700 Subject: [PATCH 055/112] lint: Use early exit/continue --- src/exec.cpp | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/exec.cpp b/src/exec.cpp index 63d5a4d2e..89f395faf 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -1174,37 +1174,38 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, // If the caller asked us to preserve the exit status, restore the old status. Otherwise set the // status of the subcommand. proc_set_last_status(apply_exit_status ? subcommand_status : prev_status); - is_subshell = prev_subshell; - if (lst != NULL && io_buffer.get() != NULL) { - const char *begin = io_buffer->out_buffer_ptr(); - const char *end = begin + io_buffer->out_buffer_size(); - if (split_output) { - const char *cursor = begin; - while (cursor < end) { - // Look for the next separator. - const char *stop = (const char *)memchr(cursor, '\n', end - cursor); - const bool hit_separator = (stop != NULL); - if (!hit_separator) { - // If it's not found, just use the end. - stop = end; - } - // Stop now points at the first character we do not want to copy. - const wcstring wc = str2wcstring(cursor, stop - cursor); - lst->push_back(wc); + if (lst == NULL || io_buffer.get() == NULL) { + return subcommand_status; + } - // If we hit a separator, skip over it; otherwise we're at the end. - cursor = stop + (hit_separator ? 1 : 0); + const char *begin = io_buffer->out_buffer_ptr(); + const char *end = begin + io_buffer->out_buffer_size(); + if (split_output) { + const char *cursor = begin; + while (cursor < end) { + // Look for the next separator. + const char *stop = (const char *)memchr(cursor, '\n', end - cursor); + const bool hit_separator = (stop != NULL); + if (!hit_separator) { + // If it's not found, just use the end. + stop = end; } - } else { - // we're not splitting output, but we still want to trim off a trailing newline. - if (end != begin && end[-1] == '\n') { - --end; - } - const wcstring wc = str2wcstring(begin, end - begin); + // Stop now points at the first character we do not want to copy. + const wcstring wc = str2wcstring(cursor, stop - cursor); lst->push_back(wc); + + // If we hit a separator, skip over it; otherwise we're at the end. + cursor = stop + (hit_separator ? 1 : 0); } + } else { + // We're not splitting output, but we still want to trim off a trailing newline. + if (end != begin && end[-1] == '\n') { + --end; + } + const wcstring wc = str2wcstring(begin, end - begin); + lst->push_back(wc); } return subcommand_status; From 3bd24ddb17cafadfc4fc83cb5511f5977686fe13 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 16:16:15 -0700 Subject: [PATCH 056/112] lint: Use early exit/continue --- src/complete.cpp | 212 ++++++++++++++++++++++++----------------------- 1 file changed, 108 insertions(+), 104 deletions(-) diff --git a/src/complete.cpp b/src/complete.cpp index 8cf1a4041..2f750f412 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -956,71 +956,73 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop } } - if (use_common) { - for (option_list_t::const_iterator oiter = options.begin(); oiter != options.end(); - ++oiter) { - const complete_entry_opt_t *o = &*oiter; - // If this entry is for the base command, check if any of the arguments match. - if (!this->condition_test(o->condition)) continue; - if (o->option.empty()) { - use_files = use_files && ((o->result_mode & NO_FILES) == 0); - complete_from_args(str, o->comp, o->localized_desc(), o->flags); - } + if (!use_common) { + continue; + } - if (wcslen(str) > 0 && use_switches) { - // Check if the short style option matches. - if (short_ok(str, o, options)) { - // It's a match. - const wcstring desc = o->localized_desc(); - append_completion(&this->completions, o->option, desc, 0); - } - - // Check if the long style option matches. - if (o->type == option_type_single_long || o->type == option_type_double_long) { - int match = 0, match_no_case = 0; - - wcstring whole_opt(o->expected_dash_count(), L'-'); - whole_opt.append(o->option); - - match = string_prefixes_string(str, whole_opt); - - if (!match) { - match_no_case = wcsncasecmp(str, whole_opt.c_str(), wcslen(str)) == 0; - } - - if (match || match_no_case) { - int has_arg = 0; // does this switch have any known arguments - int req_arg = 0; // does this switch _require_ an argument - - size_t offset = 0; - complete_flags_t flags = 0; - - if (match) { - offset = wcslen(str); - } else { - flags = COMPLETE_REPLACES_TOKEN; - } - - has_arg = !o->comp.empty(); - req_arg = (o->result_mode & NO_COMMON); - - if (o->type == option_type_double_long && (has_arg && !req_arg)) { - // Optional arguments to a switch can only be handled using the '=', - // so we add it as a completion. By default we avoid using '=' and - // instead rely on '--switch switch-arg', since it is more commonly - // supported by homebrew getopt-like functions. - wcstring completion = - format_string(L"%ls=", whole_opt.c_str() + offset); - append_completion(&this->completions, completion, C_(o->desc), - flags); - } - - append_completion(&this->completions, whole_opt.c_str() + offset, - C_(o->desc), flags); - } - } - } + for (option_list_t::const_iterator oiter = options.begin(); oiter != options.end(); + ++oiter) { + const complete_entry_opt_t *o = &*oiter; + // If this entry is for the base command, check if any of the arguments match. + if (!this->condition_test(o->condition)) continue; + if (o->option.empty()) { + use_files = use_files && ((o->result_mode & NO_FILES) == 0); + complete_from_args(str, o->comp, o->localized_desc(), o->flags); } + + if (wcslen(str) == 0 || !use_switches) { + continue; + } + + // Check if the short style option matches. + if (short_ok(str, o, options)) { + // It's a match. + const wcstring desc = o->localized_desc(); + append_completion(&this->completions, o->option, desc, 0); + } + + // Check if the long style option matches. + if (o->type != option_type_single_long && o->type != option_type_double_long) { + continue; + } + int match = 0, match_no_case = 0; + + wcstring whole_opt(o->expected_dash_count(), L'-'); + whole_opt.append(o->option); + + match = string_prefixes_string(str, whole_opt); + if (!match) { + match_no_case = wcsncasecmp(str, whole_opt.c_str(), wcslen(str)) == 0; + } + + if (!match && !match_no_case) { + continue; + } + + int has_arg = 0; // does this switch have any known arguments + int req_arg = 0; // does this switch _require_ an argument + size_t offset = 0; + complete_flags_t flags = 0; + + if (match) { + offset = wcslen(str); + } else { + flags = COMPLETE_REPLACES_TOKEN; + } + + has_arg = !o->comp.empty(); + req_arg = (o->result_mode & NO_COMMON); + + if (o->type == option_type_double_long && (has_arg && !req_arg)) { + // Optional arguments to a switch can only be handled using the '=', so we add it as + // a completion. By default we avoid using '=' and instead rely on '--switch + // switch-arg', since it is more commonly supported by homebrew getopt-like + // functions. + wcstring completion = format_string(L"%ls=", whole_opt.c_str() + offset); + append_completion(&this->completions, completion, C_(o->desc), flags); + } + + append_completion(&this->completions, whole_opt.c_str() + offset, C_(o->desc), flags); } } @@ -1196,50 +1198,52 @@ bool completer_t::try_complete_user(const wcstring &str) { #else const wchar_t *cmd = str.c_str(); const wchar_t *first_char = cmd; - int res = 0; - double start_time = timef(); - if (*first_char == L'~' && !wcschr(first_char, L'/')) { - const wchar_t *user_name = first_char + 1; - const wchar_t *name_end = wcschr(user_name, L'~'); - if (name_end == 0) { - struct passwd *pw; - size_t name_len = wcslen(user_name); - - setpwent(); - - while ((pw = getpwent()) != 0) { - double current_time = timef(); - - if (current_time - start_time > 0.2) { - return 1; - } - - if (pw->pw_name) { - const wcstring pw_name_str = str2wcstring(pw->pw_name); - const wchar_t *pw_name = pw_name_str.c_str(); - if (wcsncmp(user_name, pw_name, name_len) == 0) { - wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); - append_completion(&this->completions, &pw_name[name_len], desc, - COMPLETE_NO_SPACE); - - res = 1; - } else if (wcsncasecmp(user_name, pw_name, name_len) == 0) { - wcstring name = format_string(L"~%ls", pw_name); - wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); - - append_completion(&this->completions, name, desc, COMPLETE_REPLACES_TOKEN | - COMPLETE_DONT_ESCAPE | - COMPLETE_NO_SPACE); - res = 1; - } - } - } - endpwent(); - } + if (*first_char != L'~' || wcschr(first_char, L'/')) { + return false; } - return res; + const wchar_t *user_name = first_char + 1; + const wchar_t *name_end = wcschr(user_name, L'~'); + if (name_end) { + return false; + } + + double start_time = timef(); + bool result = false; + struct passwd *pw; + size_t name_len = wcslen(user_name); + + setpwent(); + while ((pw = getpwent()) != 0) { + double current_time = timef(); + if (current_time - start_time > 0.2) { + return 1; + } + + if (!pw->pw_name) { + continue; + } + + const wcstring pw_name_str = str2wcstring(pw->pw_name); + const wchar_t *pw_name = pw_name_str.c_str(); + if (wcsncmp(user_name, pw_name, name_len) == 0) { + wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); + append_completion(&this->completions, &pw_name[name_len], desc, COMPLETE_NO_SPACE); + + result = true; + } else if (wcsncasecmp(user_name, pw_name, name_len) == 0) { + wcstring name = format_string(L"~%ls", pw_name); + wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); + + append_completion(&this->completions, name, desc, COMPLETE_REPLACES_TOKEN | + COMPLETE_DONT_ESCAPE | + COMPLETE_NO_SPACE); + result = true; + } + } + endpwent(); + return result; #endif } From 46b791240a03f66001f8ed1555cb474f05f69fa7 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 19:17:08 -0700 Subject: [PATCH 057/112] lint: Use early exit/continue --- src/builtin.cpp | 554 ++++++++++++++++++++++++------------------------ 1 file changed, 277 insertions(+), 277 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index e9018a833..eacaaf394 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -188,25 +188,26 @@ void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t * if (pos && *pos) { // Then find the next empty line. for (; *pos; pos++) { - if (*pos == L'\n') { - wchar_t *pos2; - int is_empty = 1; + if (*pos != L'\n') { + continue; + } - for (pos2 = pos + 1; *pos2; pos2++) { - if (*pos2 == L'\n') break; + int is_empty = 1; + wchar_t *pos2; + for (pos2 = pos + 1; *pos2; pos2++) { + if (*pos2 == L'\n') break; - if (*pos2 != L'\t' && *pos2 != L' ') { - is_empty = 0; - break; - } - } - if (is_empty) { - // And cut it. - *(pos2 + 1) = L'\0'; - cut = 1; + if (*pos2 != L'\t' && *pos2 != L' ') { + is_empty = 0; break; } } + if (is_empty) { + // And cut it. + *(pos2 + 1) = L'\0'; + cut = 1; + break; + } } } @@ -1198,70 +1199,60 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t ** return res; } +// Convert a octal or hex character to its binary value. Surprisingly a version +// of this function using a lookup table is only ~1.5% faster than the `switch` +// statement version below. Since that requires initializing a table statically +// (which is problematic if we run on an EBCDIC system) we don't use that +// solution. Also, we relax the style rule that `case` blocks should always be +// enclosed in parentheses given the nature of this code. static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) { assert(base == 8 || base == 16); // base must be hex or octal switch (wc) { - case L'0': { + case L'0': return 0; - } - case L'1': { + case L'1': return 1; - } - case L'2': { + case L'2': return 2; - } - case L'3': { + case L'3': return 3; - } - case L'4': { + case L'4': return 4; - } - case L'5': { + case L'5': return 5; - } - case L'6': { + case L'6': return 6; - } - case L'7': { + case L'7': return 7; - } default: { break; } } - if (base == 16) { - switch (wc) { - case L'8': { - return 8; - } - case L'9': { - return 9; - } - case L'a': - case L'A': { - return 10; - } - case L'b': - case L'B': { - return 11; - } - case L'c': - case L'C': { - return 12; - } - case L'd': - case L'D': { - return 13; - } - case L'e': - case L'E': { - return 14; - } - case L'f': - case L'F': { - return 15; - } - default: { break; } - } + if (base != 16) return UINT_MAX; + + switch (wc) { + case L'8': + return 8; + case L'9': + return 9; + case L'a': + case L'A': + return 10; + case L'b': + case L'B': + return 11; + case L'c': + case L'C': + return 12; + case L'd': + case L'D': + return 13; + case L'e': + case L'E': + return 14; + case L'f': + case L'F': + return 15; + default: { break; } } return UINT_MAX; @@ -1295,21 +1286,23 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons start = 1; } - if (base != 0) { - unsigned int idx; - unsigned char val = 0; // resulting character - for (idx = start; idx < start + max_digits; idx++) { - unsigned int digit = builtin_echo_digit(str[idx], base); - if (digit == UINT_MAX) break; - val = val * base + digit; - } + if (base == 0) { + return success; + } - // We succeeded if we consumed at least one digit. - if (idx > start) { - *consumed = idx; - *out_val = val; - success = true; - } + unsigned int idx; + unsigned char val = 0; // resulting character + for (idx = start; idx < start + max_digits; idx++) { + unsigned int digit = builtin_echo_digit(str[idx], base); + if (digit == UINT_MAX) break; + val = val * base + digit; + } + + // We succeeded if we consumed at least one digit. + if (idx > start) { + *consumed = idx; + *out_val = val; + success = true; } return success; } @@ -1546,7 +1539,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis {L"inherit-variable", required_argument, 0, 'V'}, {0, 0, 0, 0}}; - while (1 && !res) { + while (res == STATUS_BUILTIN_OK) { int opt_index = 0; // The leading - here specifies RETURN_IN_ORDER. @@ -1556,7 +1549,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis case 0: { if (long_options[opt_index].flag != 0) break; append_format(*out_err, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name); - res = 1; + res = STATUS_BUILTIN_ERROR; break; } case 'd': { @@ -1567,7 +1560,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis int sig = wcs2sig(w.woptarg); if (sig < 0) { append_format(*out_err, _(L"%ls: Unknown signal '%ls'"), argv[0], w.woptarg); - res = 1; + res = STATUS_BUILTIN_ERROR; break; } events.push_back(event_t::signal_event(sig)); @@ -1617,7 +1610,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis append_format(*out_err, _(L"%ls: Cannot find calling job for event handler"), argv[0]); - res = 1; + res = STATUS_BUILTIN_ERROR; } else { e.type = EVENT_JOB_ID; e.param1.job_id = job_id; @@ -1628,14 +1621,14 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis if (errno || !end || *end) { append_format(*out_err, _(L"%ls: Invalid process id %ls"), argv[0], w.woptarg); - res = 1; + res = STATUS_BUILTIN_ERROR; break; } e.type = EVENT_EXIT; e.param1.pid = (opt == 'j' ? -1 : 1) * abs(pid); } - if (!res) { + if (res == STATUS_BUILTIN_OK) { events.push_back(e); } break; @@ -1676,7 +1669,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis } case '?': { builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); - res = 1; + res = STATUS_BUILTIN_ERROR; break; } default: { @@ -1686,83 +1679,86 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis } } - if (!res) { - // Determine the function name, and remove it from the list of positionals. - wcstring function_name; - bool name_is_missing = positionals.empty(); - if (!name_is_missing) { - if (name_is_first_positional) { - function_name = positionals.front(); - positionals.erase(positionals.begin()); - } else { - function_name = positionals.back(); - positionals.erase(positionals.end() - 1); - } - } + if (res != STATUS_BUILTIN_OK) { + return STATUS_BUILTIN_ERROR; + } - if (name_is_missing) { - append_format(*out_err, _(L"%ls: Expected function name"), argv[0]); - res = 1; - } else if (wcsfuncname(function_name)) { - append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), argv[0], - function_name.c_str()); - - res = 1; - } else if (parser_keywords_is_reserved(function_name)) { - append_format( - *out_err, - _(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), - argv[0], function_name.c_str()); - - res = 1; - } else if (function_name.empty()) { - append_format(*out_err, _(L"%ls: No function name given"), argv[0]); - res = 1; + // Determine the function name, and remove it from the list of positionals. + wcstring function_name; + bool name_is_missing = positionals.empty(); + if (!name_is_missing) { + if (name_is_first_positional) { + function_name = positionals.front(); + positionals.erase(positionals.begin()); } else { - if (has_named_arguments) { - // All remaining positionals are named arguments. - named_arguments.swap(positionals); - for (size_t i = 0; i < named_arguments.size(); i++) { - if (wcsvarname(named_arguments.at(i))) { - append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), argv[0], - named_arguments.at(i).c_str()); - res = STATUS_BUILTIN_ERROR; - break; - } + function_name = positionals.back(); + positionals.erase(positionals.end() - 1); + } + } + + if (name_is_missing) { + append_format(*out_err, _(L"%ls: Expected function name"), argv[0]); + res = STATUS_BUILTIN_ERROR; + } else if (wcsfuncname(function_name)) { + append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), argv[0], + function_name.c_str()); + + res = STATUS_BUILTIN_ERROR; + } else if (parser_keywords_is_reserved(function_name)) { + append_format( + *out_err, + _(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), argv[0], + function_name.c_str()); + + res = STATUS_BUILTIN_ERROR; + } else if (function_name.empty()) { + append_format(*out_err, _(L"%ls: No function name given"), argv[0]); + res = STATUS_BUILTIN_ERROR; + } else { + if (has_named_arguments) { + // All remaining positionals are named arguments. + named_arguments.swap(positionals); + for (size_t i = 0; i < named_arguments.size(); i++) { + if (wcsvarname(named_arguments.at(i))) { + append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), argv[0], + named_arguments.at(i).c_str()); + res = STATUS_BUILTIN_ERROR; + break; } - } else if (!positionals.empty()) { - // +1 because we already got the function name. - append_format(*out_err, _(L"%ls: Expected one argument, got %lu"), argv[0], - (unsigned long)(positionals.size() + 1)); - res = 1; } + } else if (!positionals.empty()) { + // +1 because we already got the function name. + append_format(*out_err, _(L"%ls: Expected one argument, got %lu"), argv[0], + (unsigned long)(positionals.size() + 1)); + res = STATUS_BUILTIN_ERROR; } + } - if (!res) { - // Here we actually define the function! - function_data_t d; + if (res != STATUS_BUILTIN_OK) { + return res; + } - d.name = function_name; - if (desc) d.description = desc; - d.events.swap(events); - d.shadow_scope = shadow_scope; - d.named_arguments.swap(named_arguments); - d.inherit_vars.swap(inherit_vars); + // Here we actually define the function! + function_data_t d; - for (size_t i = 0; i < d.events.size(); i++) { - event_t &e = d.events.at(i); - e.function_name = d.name; - } + d.name = function_name; + if (desc) d.description = desc; + d.events.swap(events); + d.shadow_scope = shadow_scope; + d.named_arguments.swap(named_arguments); + d.inherit_vars.swap(inherit_vars); - d.definition = contents.c_str(); + for (size_t i = 0; i < d.events.size(); i++) { + event_t &e = d.events.at(i); + e.function_name = d.name; + } - function_add(d, parser, definition_line_offset); + d.definition = contents.c_str(); + function_add(d, parser, definition_line_offset); - // Handle wrap targets. - for (size_t w = 0; w < wrap_targets.size(); w++) { - complete_add_wrapper(function_name, wrap_targets.at(w)); - } - } + // Handle wrap targets. + for (size_t w = 0; w < wrap_targets.size(); w++) { + complete_add_wrapper(function_name, wrap_targets.at(w)); } return res; @@ -2098,57 +2094,58 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) } } - if (i != argc && !exit_res) { - env_var_t ifs = env_get_string(L"IFS"); - if (ifs.missing_or_empty()) { - // Every character is a separate token. - size_t bufflen = buff.size(); - if (array) { - if (bufflen > 0) { - wcstring chars(bufflen + (bufflen - 1), ARRAY_SEP); - wcstring::iterator out = chars.begin(); - for (wcstring::const_iterator it = buff.begin(), end = buff.end(); it != end; - ++it) { - *out = *it; - out += 2; - } - env_set(argv[i], chars.c_str(), place); - } else { - env_set(argv[i], NULL, place); - } - } else { // not array - size_t j = 0; - for (; i + 1 < argc; ++i) { - if (j < bufflen) { - wchar_t buffer[2] = {buff[j++], 0}; - env_set(argv[i], buffer, place); - } else { - env_set(argv[i], L"", place); - } - } - if (i < argc) env_set(argv[i], &buff[j], place); - } - } else if (array) { - wcstring tokens; - tokens.reserve(buff.size()); - bool empty = true; + if (i == argc || exit_res != STATUS_BUILTIN_OK) { + return exit_res; + } - for (wcstring_range loc = wcstring_tok(buff, ifs); loc.first != wcstring::npos; - loc = wcstring_tok(buff, ifs, loc)) { - if (!empty) tokens.push_back(ARRAY_SEP); - tokens.append(buff, loc.first, loc.second); - empty = false; + env_var_t ifs = env_get_string(L"IFS"); + if (ifs.missing_or_empty()) { + // Every character is a separate token. + size_t bufflen = buff.size(); + if (array) { + if (bufflen > 0) { + wcstring chars(bufflen + (bufflen - 1), ARRAY_SEP); + wcstring::iterator out = chars.begin(); + for (wcstring::const_iterator it = buff.begin(), end = buff.end(); it != end; + ++it) { + *out = *it; + out += 2; + } + env_set(argv[i], chars.c_str(), place); + } else { + env_set(argv[i], NULL, place); } - env_set(argv[i], empty ? NULL : tokens.c_str(), place); } else { // not array - wcstring_range loc = wcstring_range(0, 0); - - while (i < argc) { - loc = wcstring_tok(buff, (i + 1 < argc) ? ifs : wcstring(), loc); - env_set(argv[i], loc.first == wcstring::npos ? L"" : &buff.c_str()[loc.first], - place); - ++i; + size_t j = 0; + for (; i + 1 < argc; ++i) { + if (j < bufflen) { + wchar_t buffer[2] = {buff[j++], 0}; + env_set(argv[i], buffer, place); + } else { + env_set(argv[i], L"", place); + } } + if (i < argc) env_set(argv[i], &buff[j], place); + } + } else if (array) { + wcstring tokens; + tokens.reserve(buff.size()); + bool empty = true; + + for (wcstring_range loc = wcstring_tok(buff, ifs); loc.first != wcstring::npos; + loc = wcstring_tok(buff, ifs, loc)) { + if (!empty) tokens.push_back(ARRAY_SEP); + tokens.append(buff, loc.first, loc.second); + empty = false; + } + env_set(argv[i], empty ? NULL : tokens.c_str(), place); + } else { // not array + wcstring_range loc = wcstring_range(0, 0); + + while (i < argc) { + loc = wcstring_tok(buff, (i + 1 < argc) ? ifs : wcstring(), loc); + env_set(argv[i], loc.first == wcstring::npos ? L"" : &buff.c_str()[loc.first], place); + ++i; } } @@ -2244,7 +2241,7 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg else { streams.err.append_format(L"%ls: Invalid job control mode '%ls'\n", L"status", w.woptarg); - res = 1; + res = STATUS_BUILTIN_ERROR; } mode = DONE; break; @@ -2268,68 +2265,69 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg } } - if (!res) { - switch (mode) { - case DONE: { - break; - } - case CURRENT_FILENAME: { - const wchar_t *fn = parser.current_filename(); - - if (!fn) fn = _(L"Standard input"); - - streams.out.append_format(L"%ls\n", fn); - - break; - } - case CURRENT_LINE_NUMBER: { - streams.out.append_format(L"%d\n", parser.get_lineno()); - break; - } - case IS_INTERACTIVE: { - return !is_interactive_session; - } - case IS_SUBST: { - return !is_subshell; - } - case IS_BLOCK: { - return !is_block; - } - case IS_LOGIN: { - return !is_login; - } - case IS_FULL_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_ALL; - } - case IS_INTERACTIVE_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_INTERACTIVE; - } - case IS_NO_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_NONE; - } - case STACK_TRACE: { - streams.out.append(parser.stack_trace()); - break; - } - case NORMAL: { - if (is_login) - streams.out.append_format(_(L"This is a login shell\n")); - else - streams.out.append_format(_(L"This is not a login shell\n")); - - streams.out.append_format( - _(L"Job control: %ls\n"), - job_control_mode == JOB_CONTROL_INTERACTIVE - ? _(L"Only on interactive jobs") - : (job_control_mode == JOB_CONTROL_NONE ? _(L"Never") : _(L"Always"))); - streams.out.append(parser.stack_trace()); - break; - } - default: { break; } - } + if (res == STATUS_BUILTIN_ERROR) { + return res; } - return res; + switch (mode) { + case DONE: { + return STATUS_BUILTIN_OK; + } + case CURRENT_FILENAME: { + const wchar_t *fn = parser.current_filename(); + + if (!fn) fn = _(L"Standard input"); + streams.out.append_format(L"%ls\n", fn); + return STATUS_BUILTIN_OK; + } + case CURRENT_LINE_NUMBER: { + streams.out.append_format(L"%d\n", parser.get_lineno()); + return STATUS_BUILTIN_OK; + } + case IS_INTERACTIVE: { + return !is_interactive_session; + } + case IS_SUBST: { + return !is_subshell; + } + case IS_BLOCK: { + return !is_block; + } + case IS_LOGIN: { + return !is_login; + } + case IS_FULL_JOB_CONTROL: { + return job_control_mode != JOB_CONTROL_ALL; + } + case IS_INTERACTIVE_JOB_CONTROL: { + return job_control_mode != JOB_CONTROL_INTERACTIVE; + } + case IS_NO_JOB_CONTROL: { + return job_control_mode != JOB_CONTROL_NONE; + } + case STACK_TRACE: { + streams.out.append(parser.stack_trace()); + return STATUS_BUILTIN_OK; + } + case NORMAL: { + if (is_login) { + streams.out.append_format(_(L"This is a login shell\n")); + } else { + streams.out.append_format(_(L"This is not a login shell\n")); + } + + streams.out.append_format( + _(L"Job control: %ls\n"), + job_control_mode == JOB_CONTROL_INTERACTIVE + ? _(L"Only on interactive jobs") + : (job_control_mode == JOB_CONTROL_NONE ? _(L"Never") : _(L"Always"))); + streams.out.append(parser.stack_trace()); + return STATUS_BUILTIN_OK; + } + default: { break; } + } + + DIE("status subcommand not handled"); } /// The exit builtin. Calls reader_exit to exit and returns the value specified. @@ -2637,25 +2635,27 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } - if (j) { - if (streams.err_is_redirected) { - streams.err.append_format(FG_MSG, j->job_id, j->command_wcstr()); - } else { - // If we aren't redirecting, send output to real stderr, since stuff in sb_err won't get - // printed until the command finishes. - fwprintf(stderr, FG_MSG, j->job_id, j->command_wcstr()); - } - - const wcstring ft = tok_first(j->command()); - if (!ft.empty()) env_set(L"_", ft.c_str(), ENV_EXPORT); - reader_write_title(j->command()); - - make_first(j); - job_set_flag(j, JOB_FOREGROUND, 1); - - job_continue(j, job_is_stopped(j)); + if (!j) { + return STATUS_BUILTIN_ERROR; } - return j ? STATUS_BUILTIN_OK : STATUS_BUILTIN_ERROR; + + if (streams.err_is_redirected) { + streams.err.append_format(FG_MSG, j->job_id, j->command_wcstr()); + } else { + // If we aren't redirecting, send output to real stderr, since stuff in sb_err won't get + // printed until the command finishes. + fwprintf(stderr, FG_MSG, j->job_id, j->command_wcstr()); + } + + const wcstring ft = tok_first(j->command()); + if (!ft.empty()) env_set(L"_", ft.c_str(), ENV_EXPORT); + reader_write_title(j->command()); + + make_first(j); + job_set_flag(j, JOB_FOREGROUND, 1); + + job_continue(j, job_is_stopped(j)); + return STATUS_BUILTIN_OK; } /// Helper function for builtin_bg(). From d441de33e563adb8b80083e09e46dc58220268b2 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 20:21:26 -0700 Subject: [PATCH 058/112] lint: Use early exit/continue --- src/screen.cpp | 80 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/src/screen.cpp b/src/screen.cpp index a199672fc..8095f1a8f 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -105,24 +105,26 @@ static bool allow_soft_wrap(void) { /// Does this look like the escape sequence for setting a screen name. static bool is_screen_name_escape_seq(const wchar_t *code, size_t *resulting_length) { - bool found = false; - if (code[1] == L'k') { - const env_var_t term_name = env_get_string(L"TERM"); - if (!term_name.missing() && string_prefixes_string(L"screen", term_name)) { - const wchar_t *const screen_name_end_sentinel = L"\x1b\\"; - const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel); - if (screen_name_end == NULL) { - // Consider just k to be the code. - *resulting_length = 2; - } else { - const wchar_t *escape_sequence_end = - screen_name_end + wcslen(screen_name_end_sentinel); - *resulting_length = escape_sequence_end - code; - } - found = true; - } + if (code[1] != L'k') { + return false; } - return found; + + const env_var_t term_name = env_get_string(L"TERM"); + if (term_name.missing() || !string_prefixes_string(L"screen", term_name)) { + return false; + } + + const wchar_t *const screen_name_end_sentinel = L"\x1b\\"; + const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel); + if (screen_name_end == NULL) { + // Consider just k to be the code. + *resulting_length = 2; + } else { + const wchar_t *escape_sequence_end = + screen_name_end + wcslen(screen_name_end_sentinel); + *resulting_length = escape_sequence_end - code; + } + return true; } /// iTerm2 escape codes: CSI followed by ], terminated by either BEL or escape + backslash. @@ -169,28 +171,28 @@ static bool is_two_byte_escape_seq(const wchar_t *code, size_t *resulting_length /// Generic VT100 CSI-style sequence. , followed by zero or more ASCII characters NOT in /// the range [@,_], followed by one character in that range. static bool is_csi_style_escape_seq(const wchar_t *code, size_t *resulting_length) { - bool found = false; - if (code[1] == L'[') { - // Start at 2 to skip over [ - size_t cursor = 2; - for (; code[cursor] != L'\0'; cursor++) { - // Consume a sequence of ASCII characters not in the range [@, ~]. - wchar_t widechar = code[cursor]; - - // If we're not in ASCII, just stop. - if (widechar > 127) break; - - // If we're the end character, then consume it and then stop. - if (widechar >= L'@' && widechar <= L'~') { - cursor++; - break; - } - } - // curs now indexes just beyond the end of the sequence (or at the terminating zero). - found = true; - *resulting_length = cursor; + if (code[1] != L'[') { + return false; } - return found; + + // Start at 2 to skip over [ + size_t cursor = 2; + for (; code[cursor] != L'\0'; cursor++) { + // Consume a sequence of ASCII characters not in the range [@, ~]. + wchar_t widechar = code[cursor]; + + // If we're not in ASCII, just stop. + if (widechar > 127) break; + + // If we're the end character, then consume it and then stop. + if (widechar >= L'@' && widechar <= L'~') { + cursor++; + break; + } + } + // cursor now indexes just beyond the end of the sequence (or at the terminating zero). + *resulting_length = cursor; + return true; } /// Returns the number of characters in the escape code starting at 'code' (which should initially @@ -817,7 +819,7 @@ static void s_update(screen_t *scr, const wchar_t *left_prompt, const wchar_t *r } // Output any rprompt if this is the first line. - if (i == 0 && right_prompt_width > 0) { + if (i == 0 && right_prompt_width > 0) { //!OCLINT(Use early exit/continue) s_move(scr, &output, (int)(screen_width - right_prompt_width), (int)i); s_set_color(scr, &output, 0xffffffff); s_write_str(&output, right_prompt); From 520f810bf93a5bdd6eb9ec498ae4a68a929dae9b Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 20:26:10 -0700 Subject: [PATCH 059/112] lint: Use early exit/continue --- src/parse_execution.cpp | 160 ++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 78 deletions(-) diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 8887c682a..b18514ef2 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -372,38 +372,41 @@ parse_execution_result_t parse_execution_context_t::run_function_statement( wcstring_list_t argument_list; parse_execution_result_t result = this->determine_arguments(header, &argument_list, failglob); - if (result == parse_execution_success) { - // The function definition extends from the end of the header to the function end. It's not - // just the range of the contents because that loses comments - see issue #1710. - assert(block_end_command.has_source()); - size_t contents_start = header.source_start + header.source_length; - size_t contents_end = - block_end_command.source_start; // 1 past the last character in the function definition - assert(contents_end >= contents_start); - - // Swallow whitespace at both ends. - while (contents_start < contents_end && iswspace(this->src.at(contents_start))) { - contents_start++; - } - while (contents_start < contents_end && iswspace(this->src.at(contents_end - 1))) { - contents_end--; - } - - assert(contents_end >= contents_start); - const wcstring contents_str = - wcstring(this->src, contents_start, contents_end - contents_start); - int definition_line_offset = this->line_offset_of_character_at_offset(contents_start); - wcstring error_str; - io_streams_t streams; - int err = builtin_function(*parser, streams, argument_list, contents_str, - definition_line_offset, &error_str); - proc_set_last_status(err); - - if (!error_str.empty()) { - this->report_error(header, L"%ls", error_str.c_str()); - result = parse_execution_errored; - } + if (result != parse_execution_success) { + return result; } + + // The function definition extends from the end of the header to the function end. It's not + // just the range of the contents because that loses comments - see issue #1710. + assert(block_end_command.has_source()); + size_t contents_start = header.source_start + header.source_length; + size_t contents_end = + block_end_command.source_start; // 1 past the last character in the function definition + assert(contents_end >= contents_start); + + // Swallow whitespace at both ends. + while (contents_start < contents_end && iswspace(this->src.at(contents_start))) { + contents_start++; + } + while (contents_start < contents_end && iswspace(this->src.at(contents_end - 1))) { + contents_end--; + } + + assert(contents_end >= contents_start); + const wcstring contents_str = + wcstring(this->src, contents_start, contents_end - contents_start); + int definition_line_offset = this->line_offset_of_character_at_offset(contents_start); + wcstring error_str; + io_streams_t streams; + int err = builtin_function(*parser, streams, argument_list, contents_str, + definition_line_offset, &error_str); + proc_set_last_status(err); + + if (!error_str.empty()) { + this->report_error(header, L"%ls", error_str.c_str()); + result = parse_execution_errored; + } + return result; } @@ -546,66 +549,67 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement( switch_values_expanded.size()); } - if (result == parse_execution_success) { - const wcstring &switch_value_expanded = switch_values_expanded.at(0).completion; + if (result != parse_execution_success) { + return result; + } - switch_block_t *sb = new switch_block_t(); - parser->push_block(sb); + const wcstring &switch_value_expanded = switch_values_expanded.at(0).completion; - // Expand case statements. - const parse_node_t *case_item_list = get_child(statement, 3, symbol_case_item_list); + switch_block_t *sb = new switch_block_t(); + parser->push_block(sb); - // Loop while we don't have a match but do have more of the list. - const parse_node_t *matching_case_item = NULL; - while (matching_case_item == NULL && case_item_list != NULL) { - if (should_cancel_execution(sb)) { - result = parse_execution_cancelled; - break; - } + // Expand case statements. + const parse_node_t *case_item_list = get_child(statement, 3, symbol_case_item_list); - // Get the next item and the remainder of the list. - const parse_node_t *case_item = - tree.next_node_in_node_list(*case_item_list, symbol_case_item, &case_item_list); - if (case_item == NULL) { - // No more items. - break; - } + // Loop while we don't have a match but do have more of the list. + const parse_node_t *matching_case_item = NULL; + while (matching_case_item == NULL && case_item_list != NULL) { + if (should_cancel_execution(sb)) { + result = parse_execution_cancelled; + break; + } - // Pull out the argument list. - const parse_node_t &arg_list = *get_child(*case_item, 1, symbol_argument_list); + // Get the next item and the remainder of the list. + const parse_node_t *case_item = + tree.next_node_in_node_list(*case_item_list, symbol_case_item, &case_item_list); + if (case_item == NULL) { + // No more items. + break; + } - // Expand arguments. A case item list may have a wildcard that fails to expand to - // anything. We also report case errors, but don't stop execution; i.e. a case item that - // contains an unexpandable process will report and then fail to match. - wcstring_list_t case_args; - parse_execution_result_t case_result = - this->determine_arguments(arg_list, &case_args, failglob); - if (case_result == parse_execution_success) { - for (size_t i = 0; i < case_args.size(); i++) { - const wcstring &arg = case_args.at(i); + // Pull out the argument list. + const parse_node_t &arg_list = *get_child(*case_item, 1, symbol_argument_list); - // Unescape wildcards so they can be expanded again. - wcstring unescaped_arg = parse_util_unescape_wildcards(arg); - bool match = wildcard_match(switch_value_expanded, unescaped_arg); + // Expand arguments. A case item list may have a wildcard that fails to expand to + // anything. We also report case errors, but don't stop execution; i.e. a case item that + // contains an unexpandable process will report and then fail to match. + wcstring_list_t case_args; + parse_execution_result_t case_result = + this->determine_arguments(arg_list, &case_args, failglob); + if (case_result == parse_execution_success) { + for (size_t i = 0; i < case_args.size(); i++) { + const wcstring &arg = case_args.at(i); - // If this matched, we're done. - if (match) { - matching_case_item = case_item; - break; - } + // Unescape wildcards so they can be expanded again. + wcstring unescaped_arg = parse_util_unescape_wildcards(arg); + bool match = wildcard_match(switch_value_expanded, unescaped_arg); + + // If this matched, we're done. + if (match) { + matching_case_item = case_item; + break; } } } - - if (result == parse_execution_success && matching_case_item != NULL) { - // Success, evaluate the job list. - const parse_node_t *job_list = get_child(*matching_case_item, 3, symbol_job_list); - result = this->run_job_list(*job_list, sb); - } - - parser->pop_block(sb); } + if (result == parse_execution_success && matching_case_item != NULL) { + // Success, evaluate the job list. + const parse_node_t *job_list = get_child(*matching_case_item, 3, symbol_job_list); + result = this->run_job_list(*job_list, sb); + } + + parser->pop_block(sb); return result; } From 2c38978115eef555c8c5efcbc5346aa59ec89f9a Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 21:05:27 -0700 Subject: [PATCH 060/112] lint: Use early exit/continue --- src/parse_util.cpp | 164 ++++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 76 deletions(-) diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 80c89e160..184dcd1f3 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -197,26 +197,28 @@ static int parse_util_locate_brackets_range(const wcstring &str, size_t *inout_c int ret = parse_util_locate_brackets_of_type(valid_range_start, &bracket_range_begin, &bracket_range_end, accept_incomplete, open_type, close_type); - if (ret > 0) { - // The command substitutions must not be NULL and must be in the valid pointer range, and - // the end must be bigger than the beginning. - assert(bracket_range_begin != NULL && bracket_range_begin >= valid_range_start && - bracket_range_begin <= valid_range_end); - assert(bracket_range_end != NULL && bracket_range_end > bracket_range_begin && - bracket_range_end >= valid_range_start && bracket_range_end <= valid_range_end); - - // Assign the substring to the out_contents. - const wchar_t *interior_begin = bracket_range_begin + 1; - out_contents->assign(interior_begin, bracket_range_end - interior_begin); - - // Return the start and end. - *out_start = bracket_range_begin - buff; - *out_end = bracket_range_end - buff; - - // Update the inout_cursor_offset. Note this may cause it to exceed str.size(), though - // overflow is not likely. - *inout_cursor_offset = 1 + *out_end; + if (ret <= 0) { + return ret; } + + // The command substitutions must not be NULL and must be in the valid pointer range, and + // the end must be bigger than the beginning. + assert(bracket_range_begin != NULL && bracket_range_begin >= valid_range_start && + bracket_range_begin <= valid_range_end); + assert(bracket_range_end != NULL && bracket_range_end > bracket_range_begin && + bracket_range_end >= valid_range_start && bracket_range_end <= valid_range_end); + + // Assign the substring to the out_contents. + const wchar_t *interior_begin = bracket_range_begin + 1; + out_contents->assign(interior_begin, bracket_range_end - interior_begin); + + // Return the start and end. + *out_start = bracket_range_begin - buff; + *out_end = bracket_range_end - buff; + + // Update the inout_cursor_offset. Note this may cause it to exceed str.size(), though + // overflow is not likely. + *inout_cursor_offset = 1 + *out_end; return ret; } @@ -921,24 +923,28 @@ static parser_test_error_bits_t detect_dollar_cmdsub_errors(size_t arg_src_offse parse_error_list_t *out_errors) { parser_test_error_bits_t result_bits = 0; wcstring unescaped_arg_src; - if (unescape_string(arg_src, &unescaped_arg_src, UNESCAPE_SPECIAL) && - !unescaped_arg_src.empty()) { - wchar_t last = unescaped_arg_src.at(unescaped_arg_src.size() - 1); - if (last == VARIABLE_EXPAND) { - result_bits |= PARSER_TEST_ERROR; - if (out_errors != NULL) { - wcstring subcommand_first_token = tok_first(cmdsubst_src); - if (subcommand_first_token.empty()) { - // e.g. $(). Report somthing. - subcommand_first_token = L"..."; - } - append_syntax_error( - out_errors, - arg_src_offset + arg_src.size() - 1, // global position of the dollar - ERROR_BAD_VAR_SUBCOMMAND1, truncate_string(subcommand_first_token).c_str()); + + if (!unescape_string(arg_src, &unescaped_arg_src, UNESCAPE_SPECIAL) || + unescaped_arg_src.empty()) { + return result_bits; + } + + wchar_t last = unescaped_arg_src.at(unescaped_arg_src.size() - 1); + if (last == VARIABLE_EXPAND) { + result_bits |= PARSER_TEST_ERROR; + if (out_errors != NULL) { + wcstring subcommand_first_token = tok_first(cmdsubst_src); + if (subcommand_first_token.empty()) { + // e.g. $(). Report somthing. + subcommand_first_token = L"..."; } + append_syntax_error( + out_errors, + arg_src_offset + arg_src.size() - 1, // global position of the dollar + ERROR_BAD_VAR_SUBCOMMAND1, truncate_string(subcommand_first_token).c_str()); } } + return result_bits; } @@ -1023,23 +1029,24 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t // Check for invalid variable expansions. const size_t unesc_size = unesc.size(); for (size_t idx = 0; idx < unesc_size; idx++) { - if (unesc.at(idx) == VARIABLE_EXPAND || unesc.at(idx) == VARIABLE_EXPAND_SINGLE) { - wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0'; + if (unesc.at(idx) != VARIABLE_EXPAND && unesc.at(idx) != VARIABLE_EXPAND_SINGLE) { + continue; + } - if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE && - !wcsvarchr(next_char)) { - err = 1; - if (out_errors) { - // We have something like $$$^.... Back up until we reach the first $. - size_t first_dollar = idx; - while (first_dollar > 0 && - (unesc.at(first_dollar - 1) == VARIABLE_EXPAND || - unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) { - first_dollar--; - } - parse_util_expand_variable_error(unesc, node.source_start, first_dollar, - out_errors); + wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0'; + if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE && + !wcsvarchr(next_char)) { + err = 1; + if (out_errors) { + // We have something like $$$^.... Back up until we reach the first $. + size_t first_dollar = idx; + while (first_dollar > 0 && + (unesc.at(first_dollar - 1) == VARIABLE_EXPAND || + unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) { + first_dollar--; } + parse_util_expand_variable_error(unesc, node.source_start, first_dollar, + out_errors); } } } @@ -1147,33 +1154,38 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src, assert(next_job_list != NULL); const parse_node_t *next_job = node_tree.next_node_in_node_list(*next_job_list, symbol_job, NULL); - if (next_job != NULL) { - const parse_node_t *next_statement = - node_tree.get_child(*next_job, 0, symbol_statement); - if (next_statement != NULL) { - const parse_node_t *spec_statement = - node_tree.get_child(*next_statement, 0); - if (spec_statement && - spec_statement->type == symbol_boolean_statement) { - switch (parse_node_tree_t::statement_boolean_type( - *spec_statement)) { - // These are not allowed. - case parse_bool_and: - errored = append_syntax_error( - &parse_errors, spec_statement->source_start, - BOOL_AFTER_BACKGROUND_ERROR_MSG, L"and"); - break; - case parse_bool_or: - errored = append_syntax_error( - &parse_errors, spec_statement->source_start, - BOOL_AFTER_BACKGROUND_ERROR_MSG, L"or"); - break; - case parse_bool_not: - // This one is OK. - break; - } - } - } + if (next_job == NULL) { + break; + } + + const parse_node_t *next_statement = + node_tree.get_child(*next_job, 0, symbol_statement); + if (next_statement == NULL) { + break; + } + + const parse_node_t *spec_statement = + node_tree.get_child(*next_statement, 0); + if (!spec_statement || + spec_statement->type != symbol_boolean_statement) { + break; + } + + switch (parse_node_tree_t::statement_boolean_type(*spec_statement)) { + case parse_bool_and: { // this is not allowed + errored = append_syntax_error( + &parse_errors, spec_statement->source_start, + BOOL_AFTER_BACKGROUND_ERROR_MSG, L"and"); + break; + } + case parse_bool_or: { // this is not allowed + errored = append_syntax_error( + &parse_errors, spec_statement->source_start, + BOOL_AFTER_BACKGROUND_ERROR_MSG, L"or"); + break; + } + // All others are OK. + default: { break; } } break; } From d4fb9a0e65b84f28e28c204c8b624cf54f5bc4e7 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 21:18:59 -0700 Subject: [PATCH 061/112] lint: Use early exit/continue --- src/io.cpp | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/io.cpp b/src/io.cpp index b274897fd..be33bcb12 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -165,35 +165,35 @@ void io_print(const io_chain_t &chain) /// created is marked close-on-exec. Returns -1 on failure (in which case the given fd is still /// closed). static int move_fd_to_unused(int fd, const io_chain_t &io_chain) { - int new_fd = fd; - if (fd >= 0 && io_chain.get_io_for_fd(fd).get() != NULL) { - // We have fd >= 0, and it's a conflict. dup it and recurse. Note that we recurse before - // anything is closed; this forces the kernel to give us a new one (or report fd - // exhaustion). - int tmp_fd; - do { - tmp_fd = dup(fd); - } while (tmp_fd < 0 && errno == EINTR); - - assert(tmp_fd != fd); - if (tmp_fd < 0) { - // Likely fd exhaustion. - new_fd = -1; - } else { - // Ok, we have a new candidate fd. Recurse. If we get a valid fd, either it's the same - // as what we gave it, or it's a new fd and what we gave it has been closed. If we get a - // negative value, the fd also has been closed. - set_cloexec(tmp_fd); - new_fd = move_fd_to_unused(tmp_fd, io_chain); - } - - // We're either returning a new fd or an error. In both cases, we promise to close the old - // one. - assert(new_fd != fd); - int saved_errno = errno; - exec_close(fd); - errno = saved_errno; + if (fd < 0 || io_chain.get_io_for_fd(fd).get() == NULL) { + return fd; } + + // We have fd >= 0, and it's a conflict. dup it and recurse. Note that we recurse before + // anything is closed; this forces the kernel to give us a new one (or report fd exhaustion). + int new_fd = fd; + int tmp_fd; + do { + tmp_fd = dup(fd); + } while (tmp_fd < 0 && errno == EINTR); + + assert(tmp_fd != fd); + if (tmp_fd < 0) { + // Likely fd exhaustion. + new_fd = -1; + } else { + // Ok, we have a new candidate fd. Recurse. If we get a valid fd, either it's the same as + // what we gave it, or it's a new fd and what we gave it has been closed. If we get a + // negative value, the fd also has been closed. + set_cloexec(tmp_fd); + new_fd = move_fd_to_unused(tmp_fd, io_chain); + } + + // We're either returning a new fd or an error. In both cases, we promise to close the old one. + assert(new_fd != fd); + int saved_errno = errno; + exec_close(fd); + errno = saved_errno; return new_fd; } From feaeca49991ee6985918e730dbdec97f483064f2 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 30 Oct 2016 21:28:23 -0700 Subject: [PATCH 062/112] lint: Use early exit/continue --- src/builtin_complete.cpp | 136 ++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp index 489ff3c91..25c60ffbc 100644 --- a/src/builtin_complete.cpp +++ b/src/builtin_complete.cpp @@ -322,86 +322,88 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } - if (!res) { - if (do_complete) { - const wchar_t *token; + if (res) { + return 1; + } - parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, - 0, 0); + if (do_complete) { + const wchar_t *token; - // Create a scoped transient command line, so that bulitin_commandline will see our - // argument, not the reader buffer. - builtin_commandline_scoped_transient_t temp_buffer(do_complete_param); + parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, + 0, 0); - if (recursion_level < 1) { - recursion_level++; + // Create a scoped transient command line, so that bulitin_commandline will see our + // argument, not the reader buffer. + builtin_commandline_scoped_transient_t temp_buffer(do_complete_param); - std::vector comp; - complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT, - env_vars_snapshot_t::current()); + if (recursion_level < 1) { + recursion_level++; - for (size_t i = 0; i < comp.size(); i++) { - const completion_t &next = comp.at(i); + std::vector comp; + complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT, + env_vars_snapshot_t::current()); - // Make a fake commandline, and then apply the completion to it. - const wcstring faux_cmdline = token; - size_t tmp_cursor = faux_cmdline.size(); - wcstring faux_cmdline_with_completion = completion_apply_to_command_line( - next.completion, next.flags, faux_cmdline, &tmp_cursor, false); + for (size_t i = 0; i < comp.size(); i++) { + const completion_t &next = comp.at(i); - // completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE - // is set. We don't want to set COMPLETE_NO_SPACE because that won't close - // quotes. What we want is to close the quote, but not append the space. So we - // just look for the space and clear it. - if (!(next.flags & COMPLETE_NO_SPACE) && - string_suffixes_string(L" ", faux_cmdline_with_completion)) { - faux_cmdline_with_completion.resize(faux_cmdline_with_completion.size() - - 1); - } + // Make a fake commandline, and then apply the completion to it. + const wcstring faux_cmdline = token; + size_t tmp_cursor = faux_cmdline.size(); + wcstring faux_cmdline_with_completion = completion_apply_to_command_line( + next.completion, next.flags, faux_cmdline, &tmp_cursor, false); - // The input data is meant to be something like you would have on the command - // line, e.g. includes backslashes. The output should be raw, i.e. unescaped. So - // we need to unescape the command line. See #1127. - unescape_string_in_place(&faux_cmdline_with_completion, UNESCAPE_DEFAULT); - streams.out.append(faux_cmdline_with_completion); - - // Append any description. - if (!next.description.empty()) { - streams.out.push_back(L'\t'); - streams.out.append(next.description); - } - streams.out.push_back(L'\n'); + // completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE + // is set. We don't want to set COMPLETE_NO_SPACE because that won't close + // quotes. What we want is to close the quote, but not append the space. So we + // just look for the space and clear it. + if (!(next.flags & COMPLETE_NO_SPACE) && + string_suffixes_string(L" ", faux_cmdline_with_completion)) { + faux_cmdline_with_completion.resize(faux_cmdline_with_completion.size() - + 1); } - recursion_level--; - } - } else if (w.woptind != argc) { - streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]); - builtin_print_help(parser, streams, argv[0], streams.err); + // The input data is meant to be something like you would have on the command + // line, e.g. includes backslashes. The output should be raw, i.e. unescaped. So + // we need to unescape the command line. See #1127. + unescape_string_in_place(&faux_cmdline_with_completion, UNESCAPE_DEFAULT); + streams.out.append(faux_cmdline_with_completion); + + // Append any description. + if (!next.description.empty()) { + streams.out.push_back(L'\t'); + streams.out.append(next.description); + } + streams.out.push_back(L'\n'); + } + + recursion_level--; + } + } else if (w.woptind != argc) { + streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]); + builtin_print_help(parser, streams, argv[0], streams.err); + + res = true; + } else if (cmd.empty() && path.empty()) { + // No arguments specified, meaning we print the definitions of all specified completions + // to stdout. + streams.out.append(complete_print()); + } else { + int flags = COMPLETE_AUTO_SPACE; + + if (remove) { + builtin_complete_remove(cmd, path, short_opt.c_str(), gnu_opt, old_opt); - res = true; - } else if (cmd.empty() && path.empty()) { - // No arguments specified, meaning we print the definitions of all specified completions - // to stdout. - streams.out.append(complete_print()); } else { - int flags = COMPLETE_AUTO_SPACE; + builtin_complete_add(cmd, path, short_opt.c_str(), gnu_opt, old_opt, result_mode, + authoritative, condition, comp, desc, flags); + } - if (remove) { - builtin_complete_remove(cmd, path, short_opt.c_str(), gnu_opt, old_opt); - - } else { - builtin_complete_add(cmd, path, short_opt.c_str(), gnu_opt, old_opt, result_mode, - authoritative, condition, comp, desc, flags); - } - - // Handle wrap targets (probably empty). We only wrap commands, not paths. - for (size_t w = 0; w < wrap_targets.size(); w++) { - const wcstring &wrap_target = wrap_targets.at(w); - for (size_t i = 0; i < cmd.size(); i++) { - (remove ? complete_remove_wrapper : complete_add_wrapper)(cmd.at(i), - wrap_target); - } + // Handle wrap targets (probably empty). We only wrap commands, not paths. + for (size_t w = 0; w < wrap_targets.size(); w++) { + const wcstring &wrap_target = wrap_targets.at(w); + for (size_t i = 0; i < cmd.size(); i++) { + (remove ? complete_remove_wrapper : complete_add_wrapper)(cmd.at(i), + wrap_target); } } } From 50fc3d72df6857a9bd50c2f279c81c71029648b3 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Mon, 31 Oct 2016 08:54:05 -0700 Subject: [PATCH 063/112] lint: Use early exit/continue --- src/autoload.cpp | 84 +++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/autoload.cpp b/src/autoload.cpp index c84606081..d4f84a503 100644 --- a/src/autoload.cpp +++ b/src/autoload.cpp @@ -238,50 +238,48 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_ wcstring path = next + L"/" + cmd + L".fish"; const file_access_attempt_t access = access_file(path, R_OK); - if (access.accessible) { - found_file = true; - - // Now we're actually going to take the lock. - scoped_lock locker(lock); - autoload_function_t *func = this->get_node(cmd); - - // Generate the source if we need to load it. - bool need_to_load_function = - really_load && - (func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded); - if (need_to_load_function) { - // Generate the script source. - wcstring esc = escape_string(path, 1); - script_source = L"source " + esc; - has_script_source = true; - - // Remove any loaded command because we are going to reload it. Note that this - // will deadlock if command_removed calls back into us. - if (func && func->is_loaded) { - command_removed(cmd); - func->is_placeholder = false; - } - - // Mark that we're reloading it. - reloaded = true; - } - - // Create the function if we haven't yet. This does not load it. Do not trigger - // eviction unless we are actually loading, because we don't want to evict off of - // the main thread. - if (!func) { - func = get_autoloaded_function_with_creation(cmd, really_load); - } - - // It's a fiction to say the script is loaded at this point, but we're definitely - // going to load it down below. - if (need_to_load_function) func->is_loaded = true; - - // Unconditionally record our access time. - func->access = access; - - break; + if (!access.accessible) { + continue; } + + found_file = true; + // Now we're actually going to take the lock. + scoped_lock locker(lock); + autoload_function_t *func = this->get_node(cmd); + + // Generate the source if we need to load it. + bool need_to_load_function = + really_load && + (func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded); + if (need_to_load_function) { + // Generate the script source. + wcstring esc = escape_string(path, 1); + script_source = L"source " + esc; + has_script_source = true; + + // Remove any loaded command because we are going to reload it. Note that this + // will deadlock if command_removed calls back into us. + if (func && func->is_loaded) { + command_removed(cmd); + func->is_placeholder = false; + } + + // Mark that we're reloading it. + reloaded = true; + } + + // Create the function if we haven't yet. This does not load it. Do not trigger + // eviction unless we are actually loading, because we don't want to evict off of + // the main thread. + if (!func) func = get_autoloaded_function_with_creation(cmd, really_load); + + // It's a fiction to say the script is loaded at this point, but we're definitely + // going to load it down below. + if (need_to_load_function) func->is_loaded = true; + + // Unconditionally record our access time. + func->access = access; + break; } // If no file or builtin script was found we insert a placeholder function. Later we only From 9f05697dcc0133af9cf1e08c1ebfc63932221329 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 31 Oct 2016 21:19:50 -0700 Subject: [PATCH 064/112] sorin right prompt: reset color at end bold mode being left enabled was causing issues in the pager. --- share/tools/web_config/sample_prompts/sorin.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/share/tools/web_config/sample_prompts/sorin.fish b/share/tools/web_config/sample_prompts/sorin.fish index 0608047f2..21d516a81 100644 --- a/share/tools/web_config/sample_prompts/sorin.fish +++ b/share/tools/web_config/sample_prompts/sorin.fish @@ -49,5 +49,6 @@ function fish_right_prompt printf (set_color white)◼' ' end end + set_color normal end end From edcf15e3d7f0444e2954c45eeaac808782c48498 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 31 Oct 2016 23:29:50 -0700 Subject: [PATCH 065/112] Sorin prompt: updates Use $USER, prompt_hostname, string Update to use correct color names such as magenta over purple. Use bright color variants instead of bold in some cases. --- share/completions/fish_key_reader.fish | 1 + .../web_config/sample_prompts/sorin.fish | 22 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 share/completions/fish_key_reader.fish diff --git a/share/completions/fish_key_reader.fish b/share/completions/fish_key_reader.fish new file mode 100644 index 000000000..fba8f57e8 --- /dev/null +++ b/share/completions/fish_key_reader.fish @@ -0,0 +1 @@ +complete -c fish_key_reader -s y -d "Young cow" diff --git a/share/tools/web_config/sample_prompts/sorin.fish b/share/tools/web_config/sample_prompts/sorin.fish index 21d516a81..0869c22b6 100644 --- a/share/tools/web_config/sample_prompts/sorin.fish +++ b/share/tools/web_config/sample_prompts/sorin.fish @@ -2,8 +2,7 @@ # author: Ivan Tham function fish_prompt - test $SSH_TTY; and printf (set_color red)(whoami)(set_color white)'@'(set_color yellow)(prompt_hostname)' ' - + test $SSH_TTY; and printf (set_color red)$USER(set_color brwhite)'@'(set_color yellow)(prompt_hostname)' ' test $USER = 'root'; and echo (set_color red)"#" # Main @@ -15,10 +14,10 @@ function fish_right_prompt test $status != 0; and printf (set_color red)"⏎ " if git rev-parse ^ /dev/null - # Purple if branch detached else green - git branch -qv | grep "\*" | grep -q detached - and set_color purple --bold - or set_color green --bold + # Magenta if branch detached else green + git branch -qv | grep "\*" | string match -rq detached + and set_color brmagenta + or set_color brgreen # Need optimization on this block (eliminate space) git name-rev --name-only HEAD @@ -32,9 +31,9 @@ function fish_right_prompt (git status --porcelain | cut -c 1-2 | uniq) switch $i case "*[ahead *" - printf (set_color purple)⬆' ' + printf (set_color magenta)⬆' ' case "*behind *" - printf (set_color purple)⬇' ' + printf (set_color magenta)⬇' ' case "." printf (set_color green)✚' ' case " D" @@ -42,13 +41,12 @@ function fish_right_prompt case "*M*" printf (set_color blue)✱' ' case "*R*" - printf (set_color purple)➜' ' + printf (set_color brmagenta)➜' ' case "*U*" - printf (set_color brown)═' ' + printf (set_color bryellow)═' ' case "??" - printf (set_color white)◼' ' + printf (set_color brwhite)◼' ' end end - set_color normal end end From 19e12e37478670d529fecf39c79c8163088dc0e7 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Mon, 31 Oct 2016 23:46:40 -0700 Subject: [PATCH 066/112] Revert mistaken file inclusion. I was testing command descriptions and mistakenly left in a bogus file. --- share/completions/fish_key_reader.fish | 1 - 1 file changed, 1 deletion(-) delete mode 100644 share/completions/fish_key_reader.fish diff --git a/share/completions/fish_key_reader.fish b/share/completions/fish_key_reader.fish deleted file mode 100644 index fba8f57e8..000000000 --- a/share/completions/fish_key_reader.fish +++ /dev/null @@ -1 +0,0 @@ -complete -c fish_key_reader -s y -d "Young cow" From e73226d7e8ae4720843b2d7fbe06cdae1c1f49ac Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 19:12:14 -0700 Subject: [PATCH 067/112] lint: unused parameter --- src/builtin.cpp | 14 +++++++++----- src/builtin_string.cpp | 3 ++- src/expand.cpp | 6 ++++-- src/history.cpp | 2 +- src/output.cpp | 2 +- src/parse_productions.cpp | 6 ++++-- src/wildcard.cpp | 1 - 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index eacaaf394..e173d157f 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -3299,13 +3299,11 @@ static bool builtin_handles_help(const wchar_t *cmd) { /// Execute a builtin command int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &streams) { - int (*cmd)(parser_t & parser, io_streams_t & streams, const wchar_t *const *argv) = NULL; + UNUSED(parser); + UNUSED(streams); if (argv == NULL || argv[0] == NULL) return STATUS_BUILTIN_ERROR; const builtin_data_t *data = builtin_lookup(argv[0]); - cmd = (int (*)(parser_t & parser, io_streams_t & streams, const wchar_t *const *))( - data ? data->func : NULL); - if (argv[1] != NULL && !builtin_handles_help(argv[0]) && argv[2] == NULL && parse_util_argument_is_help(argv[1], 0)) { builtin_print_help(parser, streams, argv[0], streams.out); @@ -3313,7 +3311,13 @@ int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &stre } if (data != NULL) { - return cmd(parser, streams, argv); + // Warning: layering violation and naughty cast. The code originally had a much more + // complicated solution to achieve exactly the same result: lie about the constness of argv. + // Some of the builtins we call do mutate the array via their calls to wgetopt() which could + // result in the pointers being reordered. This is harmless because we only get called once + // with a given argv array and nothing else will look at the contents of the array after we + // return. + return data->func(parser, streams, (wchar_t **)argv); } debug(0, UNKNOWN_BUILTIN_ERR_MSG, argv[0]); diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp index eb8e7e2f1..af7cfae27 100644 --- a/src/builtin_string.cpp +++ b/src/builtin_string.cpp @@ -1159,7 +1159,8 @@ static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_ static const struct string_subcommand { const wchar_t *name; - int (*handler)(parser_t &, io_streams_t &, int argc, wchar_t **argv); + int (*handler)(parser_t &, io_streams_t &, int argc, //!OCLINT(unused param) + wchar_t **argv); //!OCLINT(unused param) } string_subcommands[] = { diff --git a/src/expand.cpp b/src/expand.cpp index ef1cd613f..26d2a5f6d 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -1302,8 +1302,10 @@ static void remove_internal_separator(wcstring *str, bool conv) { /// A stage in string expansion is represented as a function that takes an input and returns a list /// of output (by reference). We get flags and errors. It may return an error; if so expansion /// halts. -typedef expand_error_t (*expand_stage_t)(const wcstring &input, std::vector *out, - expand_flags_t flags, parse_error_list_t *errors); +typedef expand_error_t (*expand_stage_t)(const wcstring &input, //!OCLINT(unused param) + std::vector *out, //!OCLINT(unused param) + expand_flags_t flags, //!OCLINT(unused param) + parse_error_list_t *errors); //!OCLINT(unused param) static expand_error_t expand_stage_cmdsubst(const wcstring &input, std::vector *out, expand_flags_t flags, parse_error_list_t *errors) { diff --git a/src/history.cpp b/src/history.cpp index 82c894aaa..554d521bf 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -769,7 +769,7 @@ void history_t::save_internal_unless_disabled() { } // This might be a good candidate for moving to a background thread. - time_profiler_t profiler(vacuum ? "save_internal vacuum" + time_profiler_t profiler(vacuum ? "save_internal vacuum" //!OCLINT(unused var) : "save_internal no vacuum"); //!OCLINT(side-effect) this->save_internal(vacuum); diff --git a/src/output.cpp b/src/output.cpp index 03c1f9fa5..271ddae5f 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -32,7 +32,7 @@ static int writeb_internal(char c); /// The function used for output. -static int (*out)(char c) = writeb_internal; +static int (*out)(char c) = writeb_internal; //!OCLINT(unused param) /// Whether term256 and term24bit are supported. static color_support_t color_support = 0; diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp index 1b577d6ed..b3d976905 100644 --- a/src/parse_productions.cpp +++ b/src/parse_productions.cpp @@ -428,6 +428,7 @@ RESOLVE_ONLY(end_command) = {KEYWORD(parse_keyword_end)}; case (symbol_##sym): \ resolver = resolve_##sym; \ break; + const production_t *parse_productions::production_for_token(parse_token_type_t node_type, const parse_token_t &input1, const parse_token_t &input2, @@ -436,8 +437,9 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n token_type_description(node_type), input1.describe().c_str()); // Fetch the function to resolve the list of productions. - const production_t *(*resolver)(const parse_token_t &input1, const parse_token_t &input2, - parse_node_tag_t *out_tag) = NULL; + const production_t *(*resolver)(const parse_token_t &input1, //!OCLINT(unused param) + const parse_token_t &input2, //!OCLINT(unused param) + parse_node_tag_t *out_tag) = NULL; //!OCLINT(unused param) switch (node_type) { TEST(job_list) TEST(job) diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 43659995f..38f226a1b 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -846,7 +846,6 @@ void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc, } else { // Not the last segment, nonempty wildcard. assert(next_slash != NULL); - wcstring child_effective_prefix = effective_prefix + wc_segment; this->expand_intermediate_segment(base_dir, dir, wc_segment, wc_remainder, effective_prefix + wc_segment + L'/'); } From c10952c354f942bd9533e5836081abebac25b42f Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 19:19:45 -0700 Subject: [PATCH 068/112] lint: fish_indent all sample prompts --- .../web_config/sample_prompts/acidhub.fish | 29 +--- .../web_config/sample_prompts/classic.fish | 30 ++-- .../sample_prompts/classic_status.fish | 18 +- .../sample_prompts/classic_vcs.fish | 107 ++++++------ .../sample_prompts/debian_chroot.fish | 71 ++++---- .../sample_prompts/informative.fish | 40 ++--- .../sample_prompts/informative_vcs.fish | 158 +++++++++--------- .../sample_prompts/justadollar.fish | 2 +- .../web_config/sample_prompts/lonetwin.fish | 14 +- .../web_config/sample_prompts/minimalist.fish | 8 +- .../tools/web_config/sample_prompts/nim.fish | 25 +-- .../web_config/sample_prompts/pythonista.fish | 42 ++--- .../sample_prompts/robbyrussell.fish | 130 +++++++------- .../sample_prompts/screen_savvy.fish | 10 +- .../web_config/sample_prompts/sorin.fish | 48 +++--- .../web_config/sample_prompts/terlar.fish | 46 ++--- .../sample_prompts/user_host_path.fish | 18 +- 17 files changed, 399 insertions(+), 397 deletions(-) diff --git a/share/tools/web_config/sample_prompts/acidhub.fish b/share/tools/web_config/sample_prompts/acidhub.fish index afb702463..08fd47fe7 100644 --- a/share/tools/web_config/sample_prompts/acidhub.fish +++ b/share/tools/web_config/sample_prompts/acidhub.fish @@ -12,8 +12,8 @@ function fish_prompt -d "Write out the prompt" if [ (_git_branch_name) ] set -l git_branch (set_color -o blue)(_git_branch_name) if [ (_is_git_dirty) ] - for i in (git branch -qv --no-color| string match -r \*|cut -d' ' -f4-|cut -d] -f1|tr , \n)\ - (git status --porcelain | cut -c 1-2 | uniq) + for i in (git branch -qv --no-color | string match -r \* | cut -d' ' -f4- | cut -d] -f1 | tr , \n)\ + (git status --porcelain | cut -c 1-2 | uniq) switch $i case "*[ahead *" set git_status "$git_status"(set_color red)⬆ @@ -39,29 +39,10 @@ function fish_prompt -d "Write out the prompt" set git_info "(git$git_status$git_branch"(set_color white)")" end set_color -b black - printf '%s%s%s%s%s%s%s%s%s%s%s%s%s'\ - (set_color -o white) \ - '❰' \ - (set_color green) \ - $USER \ - (set_color white) \ - '❙' \ - (set_color yellow) \ - (echo $PWD | sed -e "s|^$HOME|~|") \ - (set_color white) \ - $git_info \ - (set_color white) \ - '❱' \ - (set_color white) + printf '%s%s%s%s%s%s%s%s%s%s%s%s%s' (set_color -o white) '❰' (set_color green) $USER (set_color white) '❙' (set_color yellow) (echo $PWD | sed -e "s|^$HOME|~|") (set_color white) $git_info (set_color white) '❱' (set_color white) if test $laststatus -eq 0 - printf "%s✔%s≻%s " \ - (set_color -o green)\ - (set_color white) \ - (set_color normal) + printf "%s✔%s≻%s " (set_color -o green) (set_color white) (set_color normal) else - printf "%s✘%s≻%s " \ - (set_color -o red) \ - (set_color white) \ - (set_color normal) + printf "%s✘%s≻%s " (set_color -o red) (set_color white) (set_color normal) end end diff --git a/share/tools/web_config/sample_prompts/classic.fish b/share/tools/web_config/sample_prompts/classic.fish index 4310d9594..2eaa4ddd0 100644 --- a/share/tools/web_config/sample_prompts/classic.fish +++ b/share/tools/web_config/sample_prompts/classic.fish @@ -1,19 +1,19 @@ # name: Classic function fish_prompt --description "Write out the prompt" - set -l color_cwd - set -l suffix - switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else - set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '>' - end + set -l color_cwd + set -l suffix + switch $USER + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' + set color_cwd $fish_color_cwd + set suffix '>' + end - echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/tools/web_config/sample_prompts/classic_status.fish b/share/tools/web_config/sample_prompts/classic_status.fish index d180a4d74..dd0548949 100644 --- a/share/tools/web_config/sample_prompts/classic_status.fish +++ b/share/tools/web_config/sample_prompts/classic_status.fish @@ -13,16 +13,16 @@ function fish_prompt --description "Write out the prompt" set -l color_cwd set -l suffix switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '>' + set suffix '>' end echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " diff --git a/share/tools/web_config/sample_prompts/classic_vcs.fish b/share/tools/web_config/sample_prompts/classic_vcs.fish index 683e91778..beac87a8b 100644 --- a/share/tools/web_config/sample_prompts/classic_vcs.fish +++ b/share/tools/web_config/sample_prompts/classic_vcs.fish @@ -3,65 +3,68 @@ # vim: set noet: function fish_prompt --description 'Write out the prompt' - set -l last_status $status - set -l normal (set_color normal) + set -l last_status $status + set -l normal (set_color normal) - # Hack; fish_config only copies the fish_prompt function (see #736) - if not set -q -g __fish_classic_git_functions_defined - set -g __fish_classic_git_functions_defined + # Hack; fish_config only copies the fish_prompt function (see #736) + if not set -q -g __fish_classic_git_functions_defined + set -g __fish_classic_git_functions_defined - function __fish_repaint_user --on-variable fish_color_user --description "Event handler, repaint when fish_color_user changes" - if status --is-interactive - commandline -f repaint ^/dev/null - end - end + function __fish_repaint_user --on-variable fish_color_user --description "Event handler, repaint when fish_color_user changes" + if status --is-interactive + commandline -f repaint ^/dev/null + end + end - function __fish_repaint_host --on-variable fish_color_host --description "Event handler, repaint when fish_color_host changes" - if status --is-interactive - commandline -f repaint ^/dev/null - end - end + function __fish_repaint_host --on-variable fish_color_host --description "Event handler, repaint when fish_color_host changes" + if status --is-interactive + commandline -f repaint ^/dev/null + end + end - function __fish_repaint_status --on-variable fish_color_status --description "Event handler; repaint when fish_color_status changes" - if status --is-interactive - commandline -f repaint ^/dev/null - end - end + function __fish_repaint_status --on-variable fish_color_status --description "Event handler; repaint when fish_color_status changes" + if status --is-interactive + commandline -f repaint ^/dev/null + end + end - function __fish_repaint_bind_mode --on-variable fish_key_bindings --description "Event handler; repaint when fish_key_bindings changes" - if status --is-interactive - commandline -f repaint ^/dev/null - end - end + function __fish_repaint_bind_mode --on-variable fish_key_bindings --description "Event handler; repaint when fish_key_bindings changes" + if status --is-interactive + commandline -f repaint ^/dev/null + end + end - # initialize our new variables - if not set -q __fish_classic_git_prompt_initialized - set -qU fish_color_user; or set -U fish_color_user -o green - set -qU fish_color_host; or set -U fish_color_host -o cyan - set -qU fish_color_status; or set -U fish_color_status red - set -U __fish_classic_git_prompt_initialized - end - end + # initialize our new variables + if not set -q __fish_classic_git_prompt_initialized + set -qU fish_color_user + or set -U fish_color_user -o green + set -qU fish_color_host + or set -U fish_color_host -o cyan + set -qU fish_color_status + or set -U fish_color_status red + set -U __fish_classic_git_prompt_initialized + end + end - set -l color_cwd - set -l prefix - switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else - set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '>' - end + set -l color_cwd + set -l prefix + switch $USER + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' + set color_cwd $fish_color_cwd + set suffix '>' + end - set -l prompt_status - if test $last_status -ne 0 - set prompt_status ' ' (set_color $fish_color_status) "[$last_status]" "$normal" - end + set -l prompt_status + if test $last_status -ne 0 + set prompt_status ' ' (set_color $fish_color_status) "[$last_status]" "$normal" + end - echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) (prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " + echo -n -s (set_color $fish_color_user) "$USER" $normal @ (set_color $fish_color_host) (prompt_hostname) $normal ' ' (set_color $color_cwd) (prompt_pwd) $normal (__fish_vcs_prompt) $normal $prompt_status "> " end diff --git a/share/tools/web_config/sample_prompts/debian_chroot.fish b/share/tools/web_config/sample_prompts/debian_chroot.fish index a1666ea97..249dc91ab 100644 --- a/share/tools/web_config/sample_prompts/debian_chroot.fish +++ b/share/tools/web_config/sample_prompts/debian_chroot.fish @@ -2,48 +2,55 @@ # author: Maurizio De Santis function fish_prompt --description 'Write out the prompt, prepending the Debian chroot environment if present' - if not set -q __fish_prompt_normal - set -g __fish_prompt_normal (set_color normal) + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + + if not set -q __fish_prompt_chroot_env + set -g __fish_prompt_chroot_env (set_color yellow) + end + + # Set variable identifying the chroot you work in (used in the prompt below) + if begin + not set -q debian_chroot + and test -r /etc/debian_chroot end - - if not set -q __fish_prompt_chroot_env - set -g __fish_prompt_chroot_env (set_color yellow) + set debian_chroot (cat /etc/debian_chroot) + end + if begin + not set -q __fish_debian_chroot_prompt + and set -q debian_chroot + and test -n $debian_chroot end + set -g __fish_debian_chroot_prompt "($debian_chroot)" + end - # Set variable identifying the chroot you work in (used in the prompt below) - if begin; not set -q debian_chroot; and test -r /etc/debian_chroot; end - set debian_chroot (cat /etc/debian_chroot) - end - if begin; not set -q __fish_debian_chroot_prompt; and set -q debian_chroot; and test -n $debian_chroot; end - set -g __fish_debian_chroot_prompt "($debian_chroot)" - end + # Prepend the chroot environment if present + if set -q __fish_debian_chroot_prompt + echo -n -s "$__fish_prompt_chroot_env" "$__fish_debian_chroot_prompt" "$__fish_prompt_normal" ' ' + end - # Prepend the chroot environment if present - if set -q __fish_debian_chroot_prompt - echo -n -s "$__fish_prompt_chroot_env" "$__fish_debian_chroot_prompt" "$__fish_prompt_normal" ' ' - end + switch $USER - switch $USER + case root toor - case root toor - - if not set -q __fish_prompt_cwd - if set -q fish_color_cwd_root - set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) - else - set -g __fish_prompt_cwd (set_color $fish_color_cwd) - end + if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) end + end - echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' - case '*' + case '*' - if not set -q __fish_prompt_cwd - set -g __fish_prompt_cwd (set_color $fish_color_cwd) - end + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end - echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' - end + end end diff --git a/share/tools/web_config/sample_prompts/informative.fish b/share/tools/web_config/sample_prompts/informative.fish index 41468b39e..3f084bd30 100644 --- a/share/tools/web_config/sample_prompts/informative.fish +++ b/share/tools/web_config/sample_prompts/informative.fish @@ -6,41 +6,41 @@ function fish_prompt --description 'Write out the prompt' #Save the return status of the previous command set stat $status -if not set -q __fish_prompt_normal + if not set -q __fish_prompt_normal set -g __fish_prompt_normal (set_color normal) end -if not set -q __fish_color_blue + if not set -q __fish_color_blue set -g __fish_color_blue (set_color -o blue) end -#Set the color for the status depending on the value + #Set the color for the status depending on the value set __fish_color_status (set_color -o green) if test $stat -gt 0 set __fish_color_status (set_color -o red) end -switch $USER + switch $USER -case root toor + case root toor -if not set -q __fish_prompt_cwd - if set -q fish_color_cwd_root - set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) - else + if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + + printf '%s@%s %s%s%s# ' $USER (prompt_hostname) "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" + + case '*' + + if not set -q __fish_prompt_cwd set -g __fish_prompt_cwd (set_color $fish_color_cwd) end - end -printf '%s@%s %s%s%s# ' $USER (prompt_hostname) "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" - -case '*' - -if not set -q __fish_prompt_cwd - set -g __fish_prompt_cwd (set_color $fish_color_cwd) - end - -printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER (prompt_hostname) "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" + printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER (prompt_hostname) "$__fish_prompt_cwd" "$PWD" "$__fish_color_status" "$stat" "$__fish_prompt_normal" -end + end end diff --git a/share/tools/web_config/sample_prompts/informative_vcs.fish b/share/tools/web_config/sample_prompts/informative_vcs.fish index c9fe667f6..f8d01faf8 100644 --- a/share/tools/web_config/sample_prompts/informative_vcs.fish +++ b/share/tools/web_config/sample_prompts/informative_vcs.fish @@ -4,94 +4,94 @@ function fish_prompt --description 'Write out the prompt' - if not set -q __fish_git_prompt_show_informative_status - set -g __fish_git_prompt_show_informative_status 1 - end - if not set -q __fish_git_prompt_hide_untrackedfiles - set -g __fish_git_prompt_hide_untrackedfiles 1 - end + if not set -q __fish_git_prompt_show_informative_status + set -g __fish_git_prompt_show_informative_status 1 + end + if not set -q __fish_git_prompt_hide_untrackedfiles + set -g __fish_git_prompt_hide_untrackedfiles 1 + end - if not set -q __fish_git_prompt_color_branch - set -g __fish_git_prompt_color_branch magenta --bold - end - if not set -q __fish_git_prompt_showupstream - set -g __fish_git_prompt_showupstream "informative" - end - if not set -q __fish_git_prompt_char_upstream_ahead - set -g __fish_git_prompt_char_upstream_ahead "↑" - end - if not set -q __fish_git_prompt_char_upstream_behind - set -g __fish_git_prompt_char_upstream_behind "↓" - end - if not set -q __fish_git_prompt_char_upstream_prefix - set -g __fish_git_prompt_char_upstream_prefix "" - end + if not set -q __fish_git_prompt_color_branch + set -g __fish_git_prompt_color_branch magenta --bold + end + if not set -q __fish_git_prompt_showupstream + set -g __fish_git_prompt_showupstream "informative" + end + if not set -q __fish_git_prompt_char_upstream_ahead + set -g __fish_git_prompt_char_upstream_ahead "↑" + end + if not set -q __fish_git_prompt_char_upstream_behind + set -g __fish_git_prompt_char_upstream_behind "↓" + end + if not set -q __fish_git_prompt_char_upstream_prefix + set -g __fish_git_prompt_char_upstream_prefix "" + end - if not set -q __fish_git_prompt_char_stagedstate - set -g __fish_git_prompt_char_stagedstate "●" - end - if not set -q __fish_git_prompt_char_dirtystate - set -g __fish_git_prompt_char_dirtystate "✚" - end - if not set -q __fish_git_prompt_char_untrackedfiles - set -g __fish_git_prompt_char_untrackedfiles "…" - end - if not set -q __fish_git_prompt_char_conflictedstate - set -g __fish_git_prompt_char_conflictedstate "✖" - end - if not set -q __fish_git_prompt_char_cleanstate - set -g __fish_git_prompt_char_cleanstate "✔" - end + if not set -q __fish_git_prompt_char_stagedstate + set -g __fish_git_prompt_char_stagedstate "●" + end + if not set -q __fish_git_prompt_char_dirtystate + set -g __fish_git_prompt_char_dirtystate "✚" + end + if not set -q __fish_git_prompt_char_untrackedfiles + set -g __fish_git_prompt_char_untrackedfiles "…" + end + if not set -q __fish_git_prompt_char_conflictedstate + set -g __fish_git_prompt_char_conflictedstate "✖" + end + if not set -q __fish_git_prompt_char_cleanstate + set -g __fish_git_prompt_char_cleanstate "✔" + end - if not set -q __fish_git_prompt_color_dirtystate - set -g __fish_git_prompt_color_dirtystate blue - end - if not set -q __fish_git_prompt_color_stagedstate - set -g __fish_git_prompt_color_stagedstate yellow - end - if not set -q __fish_git_prompt_color_invalidstate - set -g __fish_git_prompt_color_invalidstate red - end - if not set -q __fish_git_prompt_color_untrackedfiles - set -g __fish_git_prompt_color_untrackedfiles $fish_color_normal - end - if not set -q __fish_git_prompt_color_cleanstate - set -g __fish_git_prompt_color_cleanstate green --bold - end + if not set -q __fish_git_prompt_color_dirtystate + set -g __fish_git_prompt_color_dirtystate blue + end + if not set -q __fish_git_prompt_color_stagedstate + set -g __fish_git_prompt_color_stagedstate yellow + end + if not set -q __fish_git_prompt_color_invalidstate + set -g __fish_git_prompt_color_invalidstate red + end + if not set -q __fish_git_prompt_color_untrackedfiles + set -g __fish_git_prompt_color_untrackedfiles $fish_color_normal + end + if not set -q __fish_git_prompt_color_cleanstate + set -g __fish_git_prompt_color_cleanstate green --bold + end - set -l last_status $status + set -l last_status $status - if not set -q __fish_prompt_normal - set -g __fish_prompt_normal (set_color normal) - end + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end - set -l color_cwd - set -l prefix - switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else - set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '$' - end + set -l color_cwd + set -l prefix + switch $USER + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' + set color_cwd $fish_color_cwd + set suffix '$' + end - # PWD - set_color $color_cwd - echo -n (prompt_pwd) - set_color normal + # PWD + set_color $color_cwd + echo -n (prompt_pwd) + set_color normal - printf '%s ' (__fish_vcs_prompt) + printf '%s ' (__fish_vcs_prompt) - if not test $last_status -eq 0 - set_color $fish_color_error - end + if not test $last_status -eq 0 + set_color $fish_color_error + end - echo -n "$suffix " + echo -n "$suffix " - set_color normal + set_color normal end diff --git a/share/tools/web_config/sample_prompts/justadollar.fish b/share/tools/web_config/sample_prompts/justadollar.fish index d39a2f4a2..a9b438a00 100644 --- a/share/tools/web_config/sample_prompts/justadollar.fish +++ b/share/tools/web_config/sample_prompts/justadollar.fish @@ -1,4 +1,4 @@ # name: Just a Dollar function fish_prompt - echo -n '$ ' + echo -n '$ ' end diff --git a/share/tools/web_config/sample_prompts/lonetwin.fish b/share/tools/web_config/sample_prompts/lonetwin.fish index cd4abfdc8..a8844017d 100644 --- a/share/tools/web_config/sample_prompts/lonetwin.fish +++ b/share/tools/web_config/sample_prompts/lonetwin.fish @@ -2,13 +2,13 @@ # author: Steve function fish_prompt --description 'Write out the prompt' - if not set -q __fish_prompt_normal - set -g __fish_prompt_normal (set_color normal) - end + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end - if not set -q __fish_prompt_cwd - set -g __fish_prompt_cwd (set_color $fish_color_cwd) - end + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end - echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' + echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" '> ' end diff --git a/share/tools/web_config/sample_prompts/minimalist.fish b/share/tools/web_config/sample_prompts/minimalist.fish index 14cc04458..70fb357f6 100644 --- a/share/tools/web_config/sample_prompts/minimalist.fish +++ b/share/tools/web_config/sample_prompts/minimalist.fish @@ -2,8 +2,8 @@ # author: ridiculous_fish function fish_prompt - set_color $fish_color_cwd - echo -n (basename $PWD) - set_color normal - echo -n ' ) ' + set_color $fish_color_cwd + echo -n (basename $PWD) + set_color normal + echo -n ' ) ' end diff --git a/share/tools/web_config/sample_prompts/nim.fish b/share/tools/web_config/sample_prompts/nim.fish index ef3de3242..6c6616821 100644 --- a/share/tools/web_config/sample_prompts/nim.fish +++ b/share/tools/web_config/sample_prompts/nim.fish @@ -2,8 +2,11 @@ # author: Guilhem "Nim" Saurel − https://github.com/nim65s/dotfiles/ function fish_prompt - and set retc green; or set retc red - tty|string match -q -r tty; and set tty tty; or set tty pts + and set retc green + or set retc red + tty | string match -q -r tty + and set tty tty + or set tty pts set_color $retc if [ $tty = tty ] @@ -46,16 +49,16 @@ function fish_prompt echo -n (date +%X) set_color -o green echo -n ] - + if type -q acpi - if [ (acpi -a 2> /dev/null | string match -r off) ] - echo -n '─[' - set_color -o red - echo -n (acpi -b|cut -d' ' -f 4-) - set_color -o green - echo -n ']' - end - end + if [ (acpi -a 2> /dev/null | string match -r off) ] + echo -n '─[' + set_color -o red + echo -n (acpi -b|cut -d' ' -f 4-) + set_color -o green + echo -n ']' + end + end echo set_color normal for job in (jobs) diff --git a/share/tools/web_config/sample_prompts/pythonista.fish b/share/tools/web_config/sample_prompts/pythonista.fish index 6607e5b87..9529035c4 100644 --- a/share/tools/web_config/sample_prompts/pythonista.fish +++ b/share/tools/web_config/sample_prompts/pythonista.fish @@ -3,28 +3,28 @@ function fish_prompt - if not set -q VIRTUAL_ENV_DISABLE_PROMPT - set -g VIRTUAL_ENV_DISABLE_PROMPT true - end - set_color yellow - printf '%s' (whoami) - set_color normal - printf ' at ' + if not set -q VIRTUAL_ENV_DISABLE_PROMPT + set -g VIRTUAL_ENV_DISABLE_PROMPT true + end + set_color yellow + printf '%s' (whoami) + set_color normal + printf ' at ' - set_color magenta - echo -n (prompt_hostname) - set_color normal - printf ' in ' + set_color magenta + echo -n (prompt_hostname) + set_color normal + printf ' in ' - set_color $fish_color_cwd - printf '%s' (prompt_pwd) - set_color normal + set_color $fish_color_cwd + printf '%s' (prompt_pwd) + set_color normal - # Line 2 - echo - if test $VIRTUAL_ENV - printf "(%s) " (set_color blue)(basename $VIRTUAL_ENV)(set_color normal) - end - printf '↪ ' - set_color normal + # Line 2 + echo + if test $VIRTUAL_ENV + printf "(%s) " (set_color blue)(basename $VIRTUAL_ENV)(set_color normal) + end + printf '↪ ' + set_color normal end diff --git a/share/tools/web_config/sample_prompts/robbyrussell.fish b/share/tools/web_config/sample_prompts/robbyrussell.fish index 0a895ba4b..1e94127f9 100644 --- a/share/tools/web_config/sample_prompts/robbyrussell.fish +++ b/share/tools/web_config/sample_prompts/robbyrussell.fish @@ -3,74 +3,76 @@ function fish_prompt - if not set -q -g __fish_robbyrussell_functions_defined - set -g __fish_robbyrussell_functions_defined - function _git_branch_name - echo (git symbolic-ref HEAD ^/dev/null | sed -e 's|^refs/heads/||') + if not set -q -g __fish_robbyrussell_functions_defined + set -g __fish_robbyrussell_functions_defined + function _git_branch_name + echo (git symbolic-ref HEAD ^/dev/null | sed -e 's|^refs/heads/||') + end + + function _is_git_dirty + echo (git status -s --ignore-submodules=dirty ^/dev/null) + end + + function _is_git_repo + type -q git + or return 1 + git status -s >/dev/null ^/dev/null + end + + function _hg_branch_name + echo (hg branch ^/dev/null) + end + + function _is_hg_dirty + echo (hg status -mard ^/dev/null) + end + + function _is_hg_repo + type -q hg + or return 1 + hg summary >/dev/null ^/dev/null + end + + function _repo_branch_name + eval "_$argv[1]_branch_name" + end + + function _is_repo_dirty + eval "_is_$argv[1]_dirty" + end + + function _repo_type + if _is_hg_repo + echo 'hg' + else if _is_git_repo + echo 'git' + end + end end - function _is_git_dirty - echo (git status -s --ignore-submodules=dirty ^/dev/null) + set -l cyan (set_color -o cyan) + set -l yellow (set_color -o yellow) + set -l red (set_color -o red) + set -l blue (set_color -o blue) + set -l normal (set_color normal) + + set -l arrow "$red➜ " + if [ $USER = 'root' ] + set arrow "$red# " end - function _is_git_repo - type -q git; or return 1 - git status -s >/dev/null ^/dev/null + set -l cwd $cyan(basename (prompt_pwd)) + + set -l repo_type (_repo_type) + if [ $repo_type ] + set -l repo_branch $red(_repo_branch_name $repo_type) + set repo_info "$blue $repo_type:($repo_branch$blue)" + + if [ (_is_repo_dirty $repo_type) ] + set -l dirty "$yellow ✗" + set repo_info "$repo_info$dirty" + end end - function _hg_branch_name - echo (hg branch ^/dev/null) - end - - function _is_hg_dirty - echo (hg status -mard ^/dev/null) - end - - function _is_hg_repo - type -q hg; or return 1 - hg summary >/dev/null ^/dev/null - end - - function _repo_branch_name - eval "_$argv[1]_branch_name" - end - - function _is_repo_dirty - eval "_is_$argv[1]_dirty" - end - - function _repo_type - if _is_hg_repo - echo 'hg' - else if _is_git_repo - echo 'git' - end - end - end - - set -l cyan (set_color -o cyan) - set -l yellow (set_color -o yellow) - set -l red (set_color -o red) - set -l blue (set_color -o blue) - set -l normal (set_color normal) - - set -l arrow "$red➜ " - if [ $USER = 'root' ] - set arrow "$red# " - end - - set -l cwd $cyan(basename (prompt_pwd)) - - set -l repo_type (_repo_type) - if [ $repo_type ] - set -l repo_branch $red(_repo_branch_name $repo_type) - set repo_info "$blue $repo_type:($repo_branch$blue)" - - if [ (_is_repo_dirty $repo_type) ] - set -l dirty "$yellow ✗" - set repo_info "$repo_info$dirty" - end - end - - echo -n -s $arrow ' '$cwd $repo_info $normal ' ' + echo -n -s $arrow ' '$cwd $repo_info $normal ' ' end diff --git a/share/tools/web_config/sample_prompts/screen_savvy.fish b/share/tools/web_config/sample_prompts/screen_savvy.fish index 3d72178ec..411a55019 100644 --- a/share/tools/web_config/sample_prompts/screen_savvy.fish +++ b/share/tools/web_config/sample_prompts/screen_savvy.fish @@ -1,9 +1,9 @@ # name: Screen Savvy # author: Matthias function fish_prompt -d "Write out the prompt" - if test -z $WINDOW - printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) - else - printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) - end + if test -z $WINDOW + printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + else + printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (prompt_hostname) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + end end diff --git a/share/tools/web_config/sample_prompts/sorin.fish b/share/tools/web_config/sample_prompts/sorin.fish index 0869c22b6..60f40307c 100644 --- a/share/tools/web_config/sample_prompts/sorin.fish +++ b/share/tools/web_config/sample_prompts/sorin.fish @@ -2,51 +2,55 @@ # author: Ivan Tham function fish_prompt - test $SSH_TTY; and printf (set_color red)$USER(set_color brwhite)'@'(set_color yellow)(prompt_hostname)' ' - test $USER = 'root'; and echo (set_color red)"#" + test $SSH_TTY + and printf (set_color red)$USER(set_color brwhite)'@'(set_color yellow)(prompt_hostname)' ' + test $USER = 'root' + and echo (set_color red)"#" # Main - echo -n (set_color cyan)(prompt_pwd) (set_color red)'❯'(set_color yellow)'❯'(set_color green)'❯ ' + echo -n (set_color cyan)(prompt_pwd) (set_color red)'❯'(set_color yellow)'❯'(set_color green)'❯ ' end function fish_right_prompt # last status - test $status != 0; and printf (set_color red)"⏎ " + test $status != 0 + and printf (set_color red)"⏎ " - if git rev-parse ^ /dev/null + if git rev-parse ^/dev/null # Magenta if branch detached else green git branch -qv | grep "\*" | string match -rq detached - and set_color brmagenta - or set_color brgreen + and set_color brmagenta + or set_color brgreen # Need optimization on this block (eliminate space) git name-rev --name-only HEAD # Merging state - git merge -q ^ /dev/null; or printf ':'(set_color red)'merge' + git merge -q ^/dev/null + or printf ':'(set_color red)'merge' printf ' ' # Symbols - for i in (git branch -qv --no-color|grep \*|cut -d' ' -f4-|cut -d] -f1|tr , \n)\ - (git status --porcelain | cut -c 1-2 | uniq) - switch $i + for i in (git branch -qv --no-color|grep \*|cut -d' ' -f4-|cut -d] -f1|tr , \n)\ + (git status --porcelain | cut -c 1-2 | uniq) + switch $i case "*[ahead *" printf (set_color magenta)⬆' ' case "*behind *" printf (set_color magenta)⬇' ' - case "." - printf (set_color green)✚' ' - case " D" - printf (set_color red)✖' ' - case "*M*" - printf (set_color blue)✱' ' + case "." + printf (set_color green)✚' ' + case " D" + printf (set_color red)✖' ' + case "*M*" + printf (set_color blue)✱' ' case "*R*" printf (set_color brmagenta)➜' ' case "*U*" printf (set_color bryellow)═' ' - case "??" - printf (set_color brwhite)◼' ' - end - end - end + case "??" + printf (set_color brwhite)◼' ' + end + end + end end diff --git a/share/tools/web_config/sample_prompts/terlar.fish b/share/tools/web_config/sample_prompts/terlar.fish index c8dfefc39..d49ef340c 100644 --- a/share/tools/web_config/sample_prompts/terlar.fish +++ b/share/tools/web_config/sample_prompts/terlar.fish @@ -2,35 +2,35 @@ # author: terlar - https://github.com/terlar function fish_prompt --description 'Write out the prompt' - set -l last_status $status + set -l last_status $status - # User - set_color $fish_color_user - echo -n (whoami) - set_color normal + # User + set_color $fish_color_user + echo -n (whoami) + set_color normal - echo -n '@' + echo -n '@' - # Host - set_color $fish_color_host - echo -n (prompt_hostname) - set_color normal + # Host + set_color $fish_color_host + echo -n (prompt_hostname) + set_color normal - echo -n ':' + echo -n ':' - # PWD - set_color $fish_color_cwd - echo -n (prompt_pwd) - set_color normal + # PWD + set_color $fish_color_cwd + echo -n (prompt_pwd) + set_color normal - __terlar_git_prompt - __fish_hg_prompt - echo + __terlar_git_prompt + __fish_hg_prompt + echo - if not test $last_status -eq 0 - set_color $fish_color_error - end + if not test $last_status -eq 0 + set_color $fish_color_error + end - echo -n '➤ ' - set_color normal + echo -n '➤ ' + set_color normal end diff --git a/share/tools/web_config/sample_prompts/user_host_path.fish b/share/tools/web_config/sample_prompts/user_host_path.fish index c7483b6a0..4082610a6 100644 --- a/share/tools/web_config/sample_prompts/user_host_path.fish +++ b/share/tools/web_config/sample_prompts/user_host_path.fish @@ -2,12 +2,14 @@ # author: Jon Clayden function fish_prompt -d "Write out the prompt" - set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g') - set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g') - set -l prompt_symbol '' - switch $USER - case root toor; set prompt_symbol '#' - case '*'; set prompt_symbol '$' - end - printf "[%s@%s %s%s%s]%s " $USER (prompt_hostname) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol + set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g') + set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g') + set -l prompt_symbol '' + switch $USER + case root toor + set prompt_symbol '#' + case '*' + set prompt_symbol '$' + end + printf "[%s@%s %s%s%s]%s " $USER (prompt_hostname) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol end From 60c47deca94e3db02f7822697cf54657e7a3aff4 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 20:00:09 -0700 Subject: [PATCH 069/112] lint: avoid branching statement as last in loop --- src/autoload.cpp | 5 +- src/builtin_string.cpp | 106 +++++++++++++++++++++-------------------- src/parse_tree.cpp | 4 +- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/autoload.cpp b/src/autoload.cpp index d4f84a503..a10de1364 100644 --- a/src/autoload.cpp +++ b/src/autoload.cpp @@ -233,7 +233,7 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_ if (!has_script_source) { // Iterate over path searching for suitable completion files. - for (size_t i = 0; i < path_list.size(); i++) { + for (size_t i = 0; i < path_list.size() && !found_file; i++) { wcstring next = path_list.at(i); wcstring path = next + L"/" + cmd + L".fish"; @@ -242,7 +242,6 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_ continue; } - found_file = true; // Now we're actually going to take the lock. scoped_lock locker(lock); autoload_function_t *func = this->get_node(cmd); @@ -279,7 +278,7 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_ // Unconditionally record our access time. func->access = access; - break; + found_file = true; } // If no file or builtin script was found we insert a placeholder function. Later we only diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp index af7cfae27..b19ad38e8 100644 --- a/src/builtin_string.cpp +++ b/src/builtin_string.cpp @@ -685,59 +685,63 @@ class regex_replacer_t : public string_replacer_t { regex(argv0, pattern, opts.ignore_case, streams), replacement(interpret_escapes(replacement_)) {} - bool replace_matches(const wchar_t *arg) { - // A return value of true means all is well (even if no replacements were performed), false - // indicates an unrecoverable error. - if (regex.code == 0) { - // pcre2_compile() failed - return false; - } - - uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED | - (opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0); - size_t arglen = wcslen(arg); - PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen; - wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize); - int pcre2_rc = 0; - for (;;) { - if (output == NULL) { - DIE_MEM(); - } - PCRE2_SIZE outlen = bufsize; - pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen, - 0, // start offset - options, regex.match, - 0, // match context - PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED, - (PCRE2_UCHAR *)output, &outlen); - - if (pcre2_rc == PCRE2_ERROR_NOMEMORY && bufsize < outlen) { - bufsize = outlen; - // cppcheck-suppress memleakOnRealloc - output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize); - continue; - } - break; - } - - bool rc = true; - if (pcre2_rc < 0) { - string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0, - pcre2_strerror(pcre2_rc).c_str()); - rc = false; - } else { - if (!opts.quiet) { - streams.out.append(output); - streams.out.append(L'\n'); - } - total_replaced += pcre2_rc; - } - - free(output); - return rc; - } + bool replace_matches(const wchar_t *arg); }; +/// A return value of true means all is well (even if no replacements were performed), false +/// indicates an unrecoverable error. +bool regex_replacer_t::replace_matches(const wchar_t *arg) { + if (regex.code == 0) { + // pcre2_compile() failed + return false; + } + + uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED | + (opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0); + size_t arglen = wcslen(arg); + PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen; + wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize); + int pcre2_rc; + + bool done = false; + while (!done) { + if (output == NULL) { + DIE_MEM(); + } + PCRE2_SIZE outlen = bufsize; + pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen, + 0, // start offset + options, regex.match, + 0, // match context + PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED, + (PCRE2_UCHAR *)output, &outlen); + + if (pcre2_rc != PCRE2_ERROR_NOMEMORY || bufsize >= outlen) { + done = true; + } else { + bufsize = outlen; + // cppcheck-suppress memleakOnRealloc + output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize); + } + } + + bool rc = true; + if (pcre2_rc < 0) { + string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0, + pcre2_strerror(pcre2_rc).c_str()); + rc = false; + } else { + if (!opts.quiet) { + streams.out.append(output); + streams.out.append(L'\n'); + } + total_replaced += pcre2_rc; + } + + free(output); + return rc; +} + static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) { const wchar_t *short_options = L"aiqr"; const struct woption long_options[] = {{L"all", no_argument, 0, 'a'}, diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 407c1dae2..071f51f7c 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -1386,7 +1386,7 @@ const parse_node_t *parse_node_tree_t::find_node_matching_source_location( const parse_node_t *result = NULL; // Find nodes of the given type in the tree, working backwards. const size_t len = this->size(); - for (size_t idx = 0; idx < len; idx++) { + for (size_t idx = 0; idx < len && result == NULL; idx++) { const parse_node_t &node = this->at(idx); // Types must match. @@ -1400,8 +1400,8 @@ const parse_node_t *parse_node_tree_t::find_node_matching_source_location( // Found it. result = &node; - break; } + return result; } From 71e69b6d7566700d3c2496c95d17ace8c8d8c5e8 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 20:42:02 -0700 Subject: [PATCH 070/112] lint: empty if statement --- src/common.cpp | 7 +++---- src/complete.cpp | 10 +++++----- src/env_universal_common.cpp | 7 ++----- src/expand.cpp | 2 +- src/parse_tree.cpp | 2 +- src/proc.cpp | 3 +++ src/reader.cpp | 2 +- src/wildcard.cpp | 4 +--- 8 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index bdf327018..d5647d9a8 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -287,11 +287,10 @@ std::string wcs2string(const wcstring &input) { for (size_t i = 0; i < input.size(); i++) { wchar_t wc = input[i]; if (wc == INTERNAL_SEPARATOR) { - // Do nothing. + ; // do nothing } else if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) { result.push_back(wc - ENCODE_DIRECT_BASE); - } else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) - { + } else if (MB_CUR_MAX == 1) { // single-byte locale (C/POSIX/ISO-8859) // If `wc` contains a wide character we emit a question-mark. if (wc & ~0xFF) { wc = '?'; @@ -328,7 +327,7 @@ static char *wcs2str_internal(const wchar_t *in, char *out) { while (in[in_pos]) { if (in[in_pos] == INTERNAL_SEPARATOR) { - // Do nothing. + ; // do nothing } else if (in[in_pos] >= ENCODE_DIRECT_BASE && in[in_pos] < ENCODE_DIRECT_BASE + 256) { out[out_pos++] = in[in_pos] - ENCODE_DIRECT_BASE; } else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) diff --git a/src/complete.cpp b/src/complete.cpp index 2f750f412..5d54463ec 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -679,11 +679,11 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool } } - // WTF? This seems to be a noop. - if (use_implicit_cd && - !expand_string(str_cmd, &this->completions, - EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), NULL)) { - // Not valid as implicit cd. + if (use_implicit_cd) { + // We don't really care if this succeeds or fails. If it succeeds this->completions will be + // updated with choices for the user. + (void)expand_string(str_cmd, &this->completions, + EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), NULL); } if (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~') { diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index ed70a54d5..69d0a2d3e 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -979,11 +979,8 @@ wcstring get_machine_identifier() { for (size_t i = 0; i < MAC_ADDRESS_MAX_LEN; i++) { append_format(result, L"%02x", mac_addr[i]); } - } else if (get_hostname_identifier(&result)) { - // Hooray - } else { - // Fallback - result.assign(L"nohost"); + } else if (!get_hostname_identifier(&result)) { + result.assign(L"nohost"); // fallback to a dummy value } return result; } diff --git a/src/expand.cpp b/src/expand.cpp index 26d2a5f6d..946f537f2 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -1386,7 +1386,7 @@ static expand_error_t expand_stage_wildcards(const wcstring &input, std::vector< const bool has_wildcard = wildcard_has(path_to_expand, true /* internal, i.e. ANY_CHAR */); if (has_wildcard && (flags & EXECUTABLES_ONLY)) { - // Don't do wildcard expansion for executables. See #785. Make them expand to nothing here. + ; // don't do wildcard expansion for executables, see issue #785 } else if (((flags & EXPAND_FOR_COMPLETIONS) && (!(flags & EXPAND_SKIP_WILDCARDS))) || has_wildcard) { // We either have a wildcard, or we don't have a wildcard but we're doing completion diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 071f51f7c..213eb9a75 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -988,7 +988,7 @@ bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) { } else if (stack_top.keyword == parse_keyword_end && token.type == parse_token_type_terminate && this->report_error_for_unclosed_block()) { - // Handled by report_error_for_unclosed_block. + ; // handled by report_error_for_unclosed_block } else { const wcstring expected = stack_top.user_presentable_description(); this->parse_error_unexpected_token(expected.c_str(), token); diff --git a/src/proc.cpp b/src/proc.cpp index 00b1db12d..6fdebdc15 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -336,10 +336,13 @@ static void handle_child_status(pid_t pid, int status) { } } +#if 0 + // TODO: decide whether to eliminate this block or have it emit a warning message. if (!found_proc) { // A child we lost track of? There have been bugs in both subshell handling and in builtin // handling that have caused this previously... } +#endif return; } diff --git a/src/reader.cpp b/src/reader.cpp index 0d981be16..e7e046236 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2205,7 +2205,7 @@ static void reader_super_highlight_me_plenty(int match_highlight_pos_adjust, boo const wcstring &cmd = el->text, &suggest = data->autosuggestion; if (can_autosuggest() && !suggest.empty() && string_prefixes_string_case_insensitive(cmd, suggest)) { - // The autosuggestion is still reasonable, so do nothing. + ; // the autosuggestion is still reasonable, so do nothing } else { update_autosuggestion(); } diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 38f226a1b..11bd751b3 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -385,9 +385,7 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc int stat_res = -1; int stat_errno = 0; int lstat_res = lwstat(filepath, &lstat_buf); - if (lstat_res < 0) { - // lstat failed. - } else { + if (lstat_res >= 0) { if (S_ISLNK(lstat_buf.st_mode)) { stat_res = wstat(filepath, &stat_buf); From f6047f02d699275dcb94e6c15cc6611433bb0501 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 21:19:34 -0700 Subject: [PATCH 071/112] lint: constant conditional operator --- src/builtin.cpp | 6 +++--- src/builtin_test.cpp | 4 ++-- src/complete.cpp | 2 +- src/env.cpp | 2 +- src/env_universal_common.cpp | 12 ++++++------ src/exec.cpp | 21 +++++++-------------- src/fish.cpp | 5 ----- src/pager.cpp | 8 ++++---- src/parse_tree.cpp | 7 +++---- src/parser.cpp | 2 +- src/tokenizer.cpp | 4 ++-- src/wildcard.cpp | 2 +- 12 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index e173d157f..61572fdb4 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -1360,8 +1360,8 @@ static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv) break; } default: { - assert(0 && "Unexpected character in builtin_echo argument"); - break; + DIE("unexpected character in builtin_echo argument"); + abort(); } } } @@ -2853,7 +2853,7 @@ static const wcstring hist_cmd_to_string(hist_cmd_t hist_cmd) { case HIST_SAVE: return L"save"; default: - assert(0 && "Unhandled hist_cmd_t constant!"); + DIE("unhandled hist_cmd_t constant"); abort(); } } diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp index 942ddc2f7..b18e35707 100644 --- a/src/builtin_test.cpp +++ b/src/builtin_test.cpp @@ -518,8 +518,8 @@ expression *test_parser::parse_expression(unsigned int start, unsigned int end) unsigned int argc = end - start; switch (argc) { case 0: { - assert(0); // should have been caught by the above test - return NULL; + DIE("argc should not be zero"); // should have been caught by the above test + abort(); } case 1: { return error(L"Missing argument at index %u", start + 1); diff --git a/src/complete.cpp b/src/complete.cpp index 5d54463ec..f557146c1 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -119,7 +119,7 @@ typedef struct complete_entry_opt { case option_type_double_long: return 2; } - assert(0 && "Unreachable"); + DIE("unreachable"); } } complete_entry_opt_t; diff --git a/src/env.cpp b/src/env.cpp index 2ac7fe2ba..5c773bb70 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -284,7 +284,7 @@ static void universal_callback(fish_message_type_t type, const wchar_t *name) { break; } default: { - assert(0 && "Unhandled fish_message_type_t constant!"); + DIE("unhandled fish_message_type_t constant"); abort(); } } diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 69d0a2d3e..d0fcdab3c 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -1071,7 +1071,7 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t { void post_notification() { if (region != NULL) { /* Read off the seed */ - uint32_t seed = ntohl(region->universal_variable_seed); + uint32_t seed = ntohl(region->universal_variable_seed); //!OCLINT(constant cond op) // Increment it. Don't let it wrap to zero. do { @@ -1080,9 +1080,9 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t { last_seed = seed; // Write out our data. - region->magic = htonl(SHMEM_MAGIC_NUMBER); - region->version = htonl(SHMEM_VERSION_CURRENT); - region->universal_variable_seed = htonl(seed); + region->magic = htonl(SHMEM_MAGIC_NUMBER); //!OCLINT(constant cond op) + region->version = htonl(SHMEM_VERSION_CURRENT); //!OCLINT(constant cond op) + region->universal_variable_seed = htonl(seed); //!OCLINT(constant cond op) } } @@ -1103,7 +1103,7 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t { bool poll() { bool result = false; if (region != NULL) { - uint32_t seed = ntohl(region->universal_variable_seed); + uint32_t seed = ntohl(region->universal_variable_seed); //!OCLINT(constant cond op) if (seed != last_seed) { result = true; last_seed = seed; @@ -1313,7 +1313,7 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { if (pipe_fd >= 0) { // We need to write some data (any data) to the pipe, then wait for a while, then read // it back. Nobody is expected to read it except us. - int pid_nbo = htonl(getpid()); + int pid_nbo = htonl(getpid()); //!OCLINT(constant cond op) ssize_t amt_written = write(this->pipe_fd, &pid_nbo, sizeof pid_nbo); if (amt_written < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { // Very unsual: the pipe is full! diff --git a/src/exec.cpp b/src/exec.cpp index 89f395faf..d28917dcc 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -283,8 +283,7 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain, break; } default: { - // Unknown type, should never happen. - assert(0 && "Unhandled io_mode constant"); + DIE("unhandled io_mode constant"); abort(); } } @@ -442,7 +441,7 @@ void exec_job(parser_t &parser, job_t *j) { j->first_process->completed = 1; return; } - assert(0 && "This should be unreachable"); + DIE("this should be unreachable"); } // We may have block IOs that conflict with fd redirections. For example, we may have a command @@ -827,10 +826,8 @@ void exec_job(parser_t &parser, job_t *j) { case INTERNAL_EXEC: // We should have handled exec up above. - assert( - 0 && - "INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); - break; + DIE("INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); + abort(); } if (exec_error) { @@ -1071,7 +1068,7 @@ void exec_job(parser_t &parser, job_t *j) { setup_child_process(j, p, process_net_io_chain); safe_launch_process(p, actual_cmd, argv, envv); // safe_launch_process _never_ returns... - assert(0 && "safe_launch_process should not have returned"); + DIE("safe_launch_process should not have returned"); } else { debug(2, L"Fork #%d, pid %d: external command '%s' from '%ls'\n", g_fork_count, pid, p->argv0(), file ? file : L""); @@ -1085,18 +1082,14 @@ void exec_job(parser_t &parser, job_t *j) { // This is the parent process. Store away information on the child, and possibly // fice it control over the terminal. p->pid = pid; - set_child_group(j, p, 0); - break; } case INTERNAL_EXEC: { // We should have handled exec up above. - assert( - 0 && - "INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); - break; + DIE("INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); + abort(); } } diff --git a/src/fish.cpp b/src/fish.cpp index 644e62a6f..5a135b396 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -424,11 +424,6 @@ int main(int argc, char **argv) { int res = 1; int my_optind = 0; - // We can't do this at compile time due to the use of enum symbols. - assert(EXPAND_SENTINAL >= EXPAND_RESERVED_BASE && EXPAND_SENTINAL <= EXPAND_RESERVED_END); - assert(ANY_SENTINAL >= WILDCARD_RESERVED_BASE && ANY_SENTINAL <= WILDCARD_RESERVED_END); - assert(R_SENTINAL >= INPUT_COMMON_BASE && R_SENTINAL <= INPUT_COMMON_END); - program_name = L"fish"; set_main_thread(); setup_fork_guards(); diff --git a/src/pager.cpp b/src/pager.cpp index 9bea536e2..6036e7ca9 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -615,7 +615,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio return false; } default: { - assert(0 && "Unhandled selection_direction_t constant"); + DIE("unhandled selection_direction_t constant"); abort(); } } @@ -639,7 +639,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio new_selected_completion_idx = selected_completion_idx - 1; } } else { - assert(0 && "Unknown non-cardinal direction"); + DIE("unknown non-cardinal direction"); } } else { // Cardinal directions. We have a completion index; we wish to compute its row and column. @@ -711,8 +711,8 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio break; } default: { - assert(0 && "Unknown cardinal direction"); - break; + DIE("unknown cardinal direction"); + abort(); } } diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 213eb9a75..2d11c1d61 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -332,8 +332,8 @@ static inline parse_token_type_t parse_token_type_from_tokenizer_token( default: { fprintf(stderr, "Bad token type %d passed to %s\n", (int)tokenizer_token_type, __FUNCTION__); - assert(0); - break; + DIE("bad token type"); + abort(); } } return result; @@ -1311,8 +1311,7 @@ const parse_node_t &parse_node_tree_t::find_child(const parse_node_t &parent, return *child; } } - PARSE_ASSERT(0); - return *(parse_node_t *)(NULL); // unreachable + DIE("failed to find child node"); } const parse_node_t *parse_node_tree_t::get_parent(const parse_node_t &node, diff --git a/src/parser.cpp b/src/parser.cpp index 9e71ae062..f3a9111dc 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -869,7 +869,7 @@ wcstring block_t::description() const { break; } default: { - assert(0 && "Unhandled block_type_t constant"); + DIE("unhandled block_type_t constant"); abort(); } } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 61ea9e349..2f871645d 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -318,8 +318,8 @@ void tokenizer_t::read_string() { break; } default: { - assert(0 && "Unexpected mode in read_string"); - break; + DIE("unexpected mode in read_string"); + abort(); } } return; diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 11bd751b3..cd8cb226d 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -297,7 +297,7 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc, } } - assert(0 && "Unreachable code reached"); + DIE("unreachable code reached"); } bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, From 4f4d34e664d1273cbde55c27169c31645258a1db Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 1 Nov 2016 22:36:30 -0700 Subject: [PATCH 072/112] lint: missing break in switch statement --- src/builtin.cpp | 16 ++++++++++++---- src/builtin_printf.cpp | 35 ++++++++++++++++++++++------------- src/builtin_test.cpp | 2 +- src/env.cpp | 2 +- src/event.cpp | 5 ++++- src/exec.cpp | 6 +++--- src/expand.cpp | 1 + src/fish.cpp | 3 +++ src/pager.cpp | 9 +++++---- src/parse_tree.cpp | 2 +- src/parser.cpp | 2 +- src/path.cpp | 1 + src/tokenizer.cpp | 8 ++++++-- 13 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 61572fdb4..2740c119e 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -665,6 +665,7 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv } case GLOBAL: { block = NULL; + break; } case UNSET: { while (block != NULL && block->type() != FUNCTION_CALL && @@ -672,6 +673,7 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv // Set it in function scope block = parser.block_at_index(++block_idx); } + break; } default: { DIE("unexpected scope"); @@ -962,7 +964,10 @@ static wcstring functions_def(const wcstring &name) { append_format(out, L" --on-event %ls", next->str_param1.c_str()); break; } - default: { DIE("unexpected next->type"); } + default: { + DIE("unexpected next->type"); + break; + } } } @@ -1361,7 +1366,7 @@ static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv) } default: { DIE("unexpected character in builtin_echo argument"); - abort(); + break; } } } @@ -2854,7 +2859,7 @@ static const wcstring hist_cmd_to_string(hist_cmd_t hist_cmd) { return L"save"; default: DIE("unhandled hist_cmd_t constant"); - abort(); + break; } } @@ -3014,7 +3019,10 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar w.nextchar = NULL; break; } - default: { DIE("unexpected retval from wgetopt_long"); } + default: { + DIE("unexpected retval from wgetopt_long"); + break; + } } } diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp index d43927250..e2d2d14ad 100644 --- a/src/builtin_printf.cpp +++ b/src/builtin_printf.cpp @@ -508,42 +508,45 @@ void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wc case L'G': { long double arg = string_to_scalar_type(argument, this); if (!have_field_width) { - if (!have_precision) + if (!have_precision) { this->append_format_output(fmt.c_str(), arg); - else + } else { this->append_format_output(fmt.c_str(), precision, arg); + } } else { - if (!have_precision) + if (!have_precision) { this->append_format_output(fmt.c_str(), field_width, arg); - else + } else { this->append_format_output(fmt.c_str(), field_width, precision, arg); + } } break; } case L'c': { - if (!have_field_width) + if (!have_field_width) { this->append_format_output(fmt.c_str(), *argument); - else + } else { this->append_format_output(fmt.c_str(), field_width, *argument); + } break; } case L's': { if (!have_field_width) { if (!have_precision) { this->append_format_output(fmt.c_str(), argument); - } else + } else { this->append_format_output(fmt.c_str(), precision, argument); + } } else { - if (!have_precision) + if (!have_precision) { this->append_format_output(fmt.c_str(), field_width, argument); - else + } else { this->append_format_output(fmt.c_str(), field_width, precision, argument); + } } break; } default: { - // TODO: Determine if this should call DIE() - // WTF DIE("unexpected opt"); break; } @@ -615,7 +618,10 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch modify_allowed_format_specifiers(ok, "cs", false); break; } - default: { goto no_more_flag_characters; } + default: { + goto no_more_flag_characters; + break; + } } } no_more_flag_characters:; @@ -693,7 +699,10 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch f += print_esc(f, false); break; } - default: { this->append_output(*f); } + default: { + this->append_output(*f); + break; + } } } return save_argc - argc; diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp index b18e35707..cc2fcea23 100644 --- a/src/builtin_test.cpp +++ b/src/builtin_test.cpp @@ -519,7 +519,7 @@ expression *test_parser::parse_expression(unsigned int start, unsigned int end) switch (argc) { case 0: { DIE("argc should not be zero"); // should have been caught by the above test - abort(); + break; } case 1: { return error(L"Missing argument at index %u", start + 1); diff --git a/src/env.cpp b/src/env.cpp index 5c773bb70..e5c61eb7b 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -285,7 +285,7 @@ static void universal_callback(fish_message_type_t type, const wchar_t *name) { } default: { DIE("unhandled fish_message_type_t constant"); - abort(); + break; } } diff --git a/src/event.cpp b/src/event.cpp index c215d81fd..31651054c 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -230,7 +230,10 @@ static wcstring event_desc_compact(const event_t &event) { res = format_string(L"EVENT_GENERIC(%ls)", event.str_param1.c_str()); break; } - default: { res = format_string(L"unknown/illegal event(%x)", event.type); } + default: { + res = format_string(L"unknown/illegal event(%x)", event.type); + break; + } } if (event.function_name.size()) { return format_string(L"%ls: \"%ls\"", res.c_str(), event.function_name.c_str()); diff --git a/src/exec.cpp b/src/exec.cpp index d28917dcc..b3d3f5cc1 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -284,7 +284,7 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain, } default: { DIE("unhandled io_mode constant"); - abort(); + break; } } @@ -827,7 +827,7 @@ void exec_job(parser_t &parser, job_t *j) { case INTERNAL_EXEC: // We should have handled exec up above. DIE("INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); - abort(); + break; } if (exec_error) { @@ -1089,7 +1089,7 @@ void exec_job(parser_t &parser, job_t *j) { case INTERNAL_EXEC: { // We should have handled exec up above. DIE("INTERNAL_EXEC process found in pipeline, where it should never be. Aborting."); - abort(); + break; } } diff --git a/src/expand.cpp b/src/expand.cpp index 946f537f2..bee4c3ad7 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -982,6 +982,7 @@ static expand_error_t expand_brackets(const wcstring &instr, expand_flags_t flag } case BRACKET_SEP: { if (bracket_count == 1) last_sep = pos; + break; } } } diff --git a/src/fish.cpp b/src/fish.cpp index 5a135b396..cc84686c0 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -314,6 +314,7 @@ static int fish_parse_opt(int argc, char **argv, std::vector *cmds) case 0: { fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n")); exit(127); + break; } case 'c': { cmds->push_back(optarg); @@ -358,6 +359,7 @@ static int fish_parse_opt(int argc, char **argv, std::vector *cmds) case 'v': { fwprintf(stdout, _(L"%s, version %s\n"), PACKAGE_NAME, get_fish_version()); exit(0); + break; } case 'D': { char *end; @@ -377,6 +379,7 @@ static int fish_parse_opt(int argc, char **argv, std::vector *cmds) default: { // We assume getopt_long() has already emitted a diagnostic msg. exit(1); + break; } } } diff --git a/src/pager.cpp b/src/pager.cpp index 6036e7ca9..0b33ae21a 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -616,7 +616,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio } default: { DIE("unhandled selection_direction_t constant"); - abort(); + break; } } } @@ -649,10 +649,11 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio switch (direction) { case direction_page_north: { - if (current_row > page_height) + if (current_row > page_height) { current_row = current_row - page_height; - else + } else { current_row = 0; + } break; } case direction_north: { @@ -712,7 +713,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio } default: { DIE("unknown cardinal direction"); - abort(); + break; } } diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 2d11c1d61..cb197ae26 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -333,7 +333,7 @@ static inline parse_token_type_t parse_token_type_from_tokenizer_token( fprintf(stderr, "Bad token type %d passed to %s\n", (int)tokenizer_token_type, __FUNCTION__); DIE("bad token type"); - abort(); + break; } } return result; diff --git a/src/parser.cpp b/src/parser.cpp index f3a9111dc..da5680a75 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -870,7 +870,7 @@ wcstring block_t::description() const { } default: { DIE("unhandled block_type_t constant"); - abort(); + break; } } diff --git a/src/path.cpp b/src/path.cpp index 2a71680ca..e4775cec5 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -84,6 +84,7 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path, default: { debug(1, MISSING_COMMAND_ERR_MSG, nxt_path.c_str()); wperror(L"access"); + break; } } } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 2f871645d..41743d7ae 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -219,6 +219,7 @@ void tokenizer_t::read_string() { if (!tok_is_string_character(*(this->buff), is_first)) { do_loop = 0; } + break; } } break; @@ -319,7 +320,7 @@ void tokenizer_t::read_string() { } default: { DIE("unexpected mode in read_string"); - abort(); + break; } } return; @@ -760,7 +761,10 @@ bool move_word_state_machine_t::consume_char(wchar_t c) { case move_word_style_whitespace: { return consume_char_whitespace(c); } - default: { abort(); } + default: { + DIE("unhandled style"); + break; + } } } From e35b91d38c70ba65898d387e7af3edab5c4367da Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 2 Nov 2016 14:17:26 -0700 Subject: [PATCH 073/112] lint: empty else block --- src/input.cpp | 1 - src/pager.cpp | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index f0febb7c7..c35ee82c3 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -372,7 +372,6 @@ int input_init() { } else { debug(0, _(L"Using fallback terminal type '%ls'"), DEFAULT_TERM); } - } else { } input_terminfo_init(); diff --git a/src/pager.cpp b/src/pager.cpp index 0b33ae21a..73256c4eb 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -214,8 +214,7 @@ static void mangle_1_completion_description(wcstring *str) { str->at(trailing++) = wc; } else if (!was_space) { // initial space in a run str->at(trailing++) = L' '; - } else { // non-initial space in a run, do nothing - } + } // else non-initial space in a run, do nothing was_space = is_space; } From 5709c81fe0a7335803a367e5335d22cc2a11c3c0 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 2 Nov 2016 14:22:34 -0700 Subject: [PATCH 074/112] lint: empty while statement --- src/input.cpp | 5 +++-- src/reader.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index c35ee82c3..a593a282d 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -607,8 +607,9 @@ wint_t input_readch(bool allow_commands) { if (input_function_status) { return input_readch(); } - while ((c = input_common_readch(0)) && c >= R_MIN && c <= R_MAX) { - // do nothing + c = input_common_readch(0); + while (c >= R_MIN && c <= R_MAX) { + c = input_common_readch(0); } input_common_next_ch(c); return input_readch(); diff --git a/src/reader.cpp b/src/reader.cpp index e7e046236..dc610a8c7 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2373,7 +2373,7 @@ static bool text_ends_in_comment(const wcstring &text) { tokenizer_t tok(text.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SHOW_COMMENTS | TOK_SQUASH_ERRORS); tok_t token; while (tok.next(&token)) { - // pass + ; // pass } return token.type == TOK_COMMENT; } From 9b0d45d4fa55d7e2e3dd7c467850d48949665d0a Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 2 Nov 2016 14:42:33 -0700 Subject: [PATCH 075/112] lint: unnecessary else statement --- src/history.cpp | 5 ++-- src/output.cpp | 76 ++++++++++++++++++++++++------------------------- src/parser.cpp | 8 +++--- src/reader.cpp | 6 ++-- src/wutil.cpp | 8 +++--- 5 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/history.cpp b/src/history.cpp index 554d521bf..0f07f566f 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -794,11 +794,10 @@ void history_t::add(const wcstring &str, history_identifier_t ident, bool pendin bool icompare_pred(wchar_t a, wchar_t b) { return std::tolower(a) == std::tolower(b); } bool icompare(wcstring const &a, wcstring const &b) { - if (a.length() == b.length()) { - return std::equal(b.begin(), b.end(), a.begin(), icompare_pred); - } else { + if (a.length() != b.length()) { return false; } + return std::equal(b.begin(), b.end(), a.begin(), icompare_pred); } // Remove matching history entries from our list of new items. This only supports literal, diff --git a/src/output.cpp b/src/output.cpp index 271ddae5f..039d32ce5 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -66,33 +66,32 @@ static bool write_color_escape(char *todo, unsigned char idx, bool is_fg) { if (term_supports_color_natively(idx)) { // Use tparm to emit color escape. writembs(tparm(todo, idx)); - return true; - } else { - // We are attempting to bypass the term here. Generate the ANSI escape sequence ourself. - char buff[16] = ""; - if (idx < 16) { - // this allows the non-bright color to happen instead of no color working at all when - // a bright is attempted when only colors 0-7 are supported. - // TODO: enter bold mode in builtin_set_color in the same circumstance- doing that - // combined - // with what we do here, will make the brights actually work for virtual - // consoles/ancient emulators. - if (max_colors == 8 && idx > 8) idx -= 8; - - snprintf(buff, sizeof buff, "\x1b[%dm", ((idx > 7) ? 82 : 30) + idx + !is_fg * 10); - } else { - snprintf(buff, sizeof buff, "\x1b[%d;5;%dm", is_fg ? 38 : 48, idx); - } - - int (*writer)(char) = output_get_writer(); - if (writer) { - for (size_t i = 0; buff[i]; i++) { - writer(buff[i]); - } - } - return true; } + + // We are attempting to bypass the term here. Generate the ANSI escape sequence ourself. + char buff[16] = ""; + if (idx < 16) { + // this allows the non-bright color to happen instead of no color working at all when a + // bright is attempted when only colors 0-7 are supported. + // + // TODO: enter bold mode in builtin_set_color in the same circumstance- doing that combined + // with what we do here, will make the brights actually work for virtual consoles/ancient + // emulators. + if (max_colors == 8 && idx > 8) idx -= 8; + snprintf(buff, sizeof buff, "\x1b[%dm", ((idx > 7) ? 82 : 30) + idx + !is_fg * 10); + } else { + snprintf(buff, sizeof buff, "\x1b[%d;5;%dm", is_fg ? 38 : 48, idx); + } + + int (*writer)(char) = output_get_writer(); + if (writer) { + for (size_t i = 0; buff[i]; i++) { + writer(buff[i]); + } + } + + return true; } static bool write_foreground_color(unsigned char idx) { @@ -121,21 +120,22 @@ bool write_color(rgb_color_t color, bool is_fg) { // Indexed or non-24 bit color. unsigned char idx = index_for_color(color); return (is_fg ? write_foreground_color : write_background_color)(idx); - } else { - // 24 bit! No tparm here, just ANSI escape sequences. - // Foreground: ^[38;2;;;m - // Background: ^[48;2;;;m - color24_t rgb = color.to_color24(); - char buff[128]; - snprintf(buff, sizeof buff, "\x1b[%d;2;%u;%u;%um", is_fg ? 38 : 48, rgb.rgb[0], rgb.rgb[1], - rgb.rgb[2]); - int (*writer)(char) = output_get_writer(); - if (writer) { - for (size_t i = 0; buff[i]; i++) { - writer(buff[i]); - } + } + + // 24 bit! No tparm here, just ANSI escape sequences. + // Foreground: ^[38;2;;;m + // Background: ^[48;2;;;m + color24_t rgb = color.to_color24(); + char buff[128]; + snprintf(buff, sizeof buff, "\x1b[%d;2;%u;%u;%um", is_fg ? 38 : 48, rgb.rgb[0], rgb.rgb[1], + rgb.rgb[2]); + int (*writer)(char) = output_get_writer(); + if (writer) { + for (size_t i = 0; buff[i]; i++) { + writer(buff[i]); } } + return true; } diff --git a/src/parser.cpp b/src/parser.cpp index da5680a75..8a7eefe01 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -564,11 +564,11 @@ bool parser_t::job_remove(job_t *j) { if (iter != my_job_list.end()) { my_job_list.erase(iter); return true; - } else { - debug(1, _(L"Job inconsistency")); - sanity_lose(); - return false; } + + debug(1, _(L"Job inconsistency")); + sanity_lose(); + return false; } void parser_t::job_promote(job_t *job) { diff --git a/src/reader.cpp b/src/reader.cpp index dc610a8c7..2fd5a3b77 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2212,10 +2212,10 @@ static void reader_super_highlight_me_plenty(int match_highlight_pos_adjust, boo } bool shell_is_exiting() { - if (shell_is_interactive()) + if (shell_is_interactive()) { return job_list_is_empty() && data != NULL && data->end_loop; - else - return end_loop; + } + return end_loop; } /// This function is called when the main loop notices that end_loop has been set while in diff --git a/src/wutil.cpp b/src/wutil.cpp index 572f8e510..25556c92f 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -185,11 +185,11 @@ bool set_cloexec(int fd) { int flags = fcntl(fd, F_GETFD, 0); if (flags < 0) { return false; - } else if (flags & FD_CLOEXEC) { - return true; - } else { - return fcntl(fd, F_SETFD, flags | FD_CLOEXEC) >= 0; } + if (flags & FD_CLOEXEC) { + return true; + } + return fcntl(fd, F_SETFD, flags | FD_CLOEXEC) >= 0; } static int wopen_internal(const wcstring &pathname, int flags, mode_t mode, bool cloexec) { From b9b66791c1b6eb2226df301be916f2b2d1e042d0 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Thu, 3 Nov 2016 08:27:48 +0100 Subject: [PATCH 076/112] fish_vi_cursor: Ignore errors from tput Fixes #3519. --- share/functions/fish_vi_cursor.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/fish_vi_cursor.fish b/share/functions/fish_vi_cursor.fish index c1eef1bfe..1ab8ef25f 100644 --- a/share/functions/fish_vi_cursor.fish +++ b/share/functions/fish_vi_cursor.fish @@ -16,7 +16,7 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' # We use the `tput` here just to see if terminfo thinks we can change the cursor. # We cannot use that sequence directly as it's not the correct one for konsole and iTerm, # and because we may want to change the cursor even though terminfo says we can't (tmux). - if not tput Ss > /dev/null + if not tput Ss > /dev/null ^/dev/null # Whitelist tmux... and not begin set -q TMUX From 72e687296b17fdd75188427a0e41df533bfaff55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20H=C3=A4cker?= Date: Thu, 3 Nov 2016 12:25:39 +0100 Subject: [PATCH 077/112] Create autocompletion for dpkg-reconfigure The dpkg-reconfigure command is used on Debian and Ubuntu based systems to reconfigure packages. According to the relevant manpage's the commited completion file should be complete. --- share/completions/dpkg-reconfigure.fish | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 share/completions/dpkg-reconfigure.fish diff --git a/share/completions/dpkg-reconfigure.fish b/share/completions/dpkg-reconfigure.fish new file mode 100644 index 000000000..144fe734f --- /dev/null +++ b/share/completions/dpkg-reconfigure.fish @@ -0,0 +1,14 @@ +# Completions for the `dpkg-reconfigure` command + +complete -f -c dpkg-reconfigure -a '(__fish_print_packages)' --description 'Package' + +# Support flags +complete -x -f -c dpkg-reconfigure -s h -l help --description 'Display help' + +# General options +complete -f -c dpkg-reconfigure -s f -l frontend -r -a "dialog readline noninteractive gnome kde editor web" --description 'Set configuration frontend' +complete -f -c dpkg-reconfigure -s p -l priority -r -a "low medium high critical" --description 'Set priority threshold' +complete -f -c dpkg-reconfigure -l default-priority --description 'Use default priority threshold' +complete -f -c dpkg-reconfigure -s u -l unseen-only --description 'Show only unseen question' +complete -f -c dpkg-reconfigure -l force --description 'Reconfigure also inconsistent packages' +complete -f -c dpkg-reconfigure -l no-reload --description 'Prevent reloading templates' From f05fe4e2928317d04d7c6fe0a5edb5879ba394c3 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 2 Nov 2016 18:29:14 -0700 Subject: [PATCH 078/112] lint: problems with default in switch statements --- src/builtin.cpp | 3 --- src/complete.cpp | 18 +++++++++++------- src/env.cpp | 4 ---- src/exec.cpp | 4 ---- src/expand.cpp | 10 ++++++++++ src/highlight.cpp | 9 +++++++++ src/pager.cpp | 4 ---- src/parser.cpp | 4 ---- src/proc.cpp | 6 ++++-- src/reader.cpp | 6 +++--- src/tokenizer.cpp | 15 +++++++-------- 11 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 2740c119e..a3a167963 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -2857,9 +2857,6 @@ static const wcstring hist_cmd_to_string(hist_cmd_t hist_cmd) { return L"merge"; case HIST_SAVE: return L"save"; - default: - DIE("unhandled hist_cmd_t constant"); - break; } } diff --git a/src/complete.cpp b/src/complete.cpp index f557146c1..1ed733258 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -1146,31 +1146,35 @@ bool completer_t::try_complete_variable(const wcstring &str) { } switch (c) { - case L'\\': + case L'\\': { in_pos++; break; - - case L'$': + } + case L'$': { if (mode == e_unquoted || mode == e_double_quoted) { variable_start = in_pos; } break; - - case L'\'': + } + case L'\'': { if (mode == e_single_quoted) { mode = e_unquoted; } else if (mode == e_unquoted) { mode = e_single_quoted; } break; - - case L'"': + } + case L'"': { if (mode == e_double_quoted) { mode = e_unquoted; } else if (mode == e_unquoted) { mode = e_double_quoted; } break; + } + default: { + break; // all other chars ignored here + } } } diff --git a/src/env.cpp b/src/env.cpp index e5c61eb7b..7d84992d0 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -283,10 +283,6 @@ static void universal_callback(fish_message_type_t type, const wchar_t *name) { str = L"ERASE"; break; } - default: { - DIE("unhandled fish_message_type_t constant"); - break; - } } if (str) { diff --git a/src/exec.cpp b/src/exec.cpp index b3d3f5cc1..bd6ae4560 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -282,10 +282,6 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain, out.reset(new io_fd_t(in->fd, fd, false)); break; } - default: { - DIE("unhandled io_mode constant"); - break; - } } if (out.get() != NULL) result_chain.push_back(out); diff --git a/src/expand.cpp b/src/expand.cpp index bee4c3ad7..4bb30bdd4 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -984,6 +984,9 @@ static expand_error_t expand_brackets(const wcstring &instr, expand_flags_t flag if (bracket_count == 1) last_sep = pos; break; } + default: { + break; // we ignore all other characters here + } } } @@ -1072,6 +1075,10 @@ static int expand_cmdsubst(const wcstring &input, std::vector *out case 1: { break; } + default: { + DIE("unhandled parse_ret value"); + break; + } } const wcstring subcmd(paran_begin + 1, paran_end - paran_begin - 1); @@ -1295,6 +1302,9 @@ static void remove_internal_separator(wcstring *str, bool conv) { str->at(idx) = L'*'; break; } + default: { + break; // we ignore all other characters + } } } } diff --git a/src/highlight.cpp b/src/highlight.cpp index 0558d9336..260a8cac4 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -579,6 +579,9 @@ static void color_argument_internal(const wcstring &buffstr, mode = e_double_quoted; break; } + default: { + break; // we ignore all other characters + } } } break; @@ -632,6 +635,9 @@ static void color_argument_internal(const wcstring &buffstr, in_pos -= 1; break; } + default: { + break; // we ignore all other characters + } } break; } @@ -1247,6 +1253,9 @@ static void highlight_universal_internal(const wcstring &buffstr, } break; } + default: { + break; // we ignore all other characters + } } if ((*str == L'\0')) break; str++; diff --git a/src/pager.cpp b/src/pager.cpp index 73256c4eb..4a952c205 100644 --- a/src/pager.cpp +++ b/src/pager.cpp @@ -613,10 +613,6 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio // These do nothing. return false; } - default: { - DIE("unhandled selection_direction_t constant"); - break; - } } } diff --git a/src/parser.cpp b/src/parser.cpp index 8a7eefe01..914fcf036 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -868,10 +868,6 @@ wcstring block_t::description() const { result.append(L"breakpoint"); break; } - default: { - DIE("unhandled block_type_t constant"); - break; - } } if (this->src_lineno >= 0) { diff --git a/src/proc.cpp b/src/proc.cpp index 6fdebdc15..0a2439cd8 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -900,13 +900,11 @@ void job_continue(job_t *j, bool cont) { process_mark_finished_children(false); break; } - case 0: { // No FDs are ready. Look for finished processes. process_mark_finished_children(false); break; } - case -1: { // If there is no funky IO magic, we can use waitpid instead of handling // child deaths through signals. This gives a rather large speed boost (A @@ -917,6 +915,10 @@ void job_continue(job_t *j, bool cont) { process_mark_finished_children(true); break; } + default: { + DIE("unexpected return value from select_try()"); + break; + } } } } diff --git a/src/reader.cpp b/src/reader.cpp index 2fd5a3b77..11b091282 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -882,9 +882,8 @@ static bool command_ends_paging(wchar_t c, bool focused_on_search_field) { case R_REPAINT: case R_SUPPRESS_AUTOSUGGESTION: case R_BEGINNING_OF_HISTORY: - case R_END_OF_HISTORY: - default: { - // These commands never do. + case R_END_OF_HISTORY: { + // These commands never end paging. return false; } case R_EXECUTE: { @@ -923,6 +922,7 @@ static bool command_ends_paging(wchar_t c, bool focused_on_search_field) { // These commands operate on the search field if that's where the focus is. return !focused_on_search_field; } + default: { return false; } } } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 41743d7ae..a8b2886b1 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -266,6 +266,9 @@ void tokenizer_t::read_string() { do_loop = 0; break; } + default: { + break; // ignore other chars + } } break; } @@ -286,6 +289,9 @@ void tokenizer_t::read_string() { do_loop = 0; break; } + default: { + break; // ignore other chars + } } break; } @@ -707,10 +713,7 @@ bool move_word_state_machine_t::consume_char_path_components(wchar_t c) { break; } case s_end: - default: { - // We won't get here, but keep the compiler happy. - break; - } + default: { break; } } } return consumed; @@ -761,10 +764,6 @@ bool move_word_state_machine_t::consume_char(wchar_t c) { case move_word_style_whitespace: { return consume_char_whitespace(c); } - default: { - DIE("unhandled style"); - break; - } } } From b7d910a941afa90c698bdc5160d16326d1a175c4 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 2 Nov 2016 21:54:57 -0700 Subject: [PATCH 079/112] lint: long variable name --- src/builtin_set.cpp | 18 ++++++++---------- src/common.cpp | 18 ++++++++---------- src/input.cpp | 4 ++-- src/iothread.cpp | 18 +++++++++--------- src/proc.cpp | 33 +++++++++++++++------------------ src/reader.cpp | 22 +++++++++++----------- 6 files changed, 53 insertions(+), 60 deletions(-) diff --git a/src/builtin_set.cpp b/src/builtin_set.cpp index 643a08bd0..a210cbb75 100644 --- a/src/builtin_set.cpp +++ b/src/builtin_set.cpp @@ -77,12 +77,10 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, struct stat buff; if (wstat(dir, &buff) == -1) { error = true; - } - else if (!S_ISDIR(buff.st_mode)) { + } else if (!S_ISDIR(buff.st_mode)) { error = true; errno = ENOTDIR; - } - else if (waccess(dir, X_OK) == -1) { + } else if (waccess(dir, X_OK) == -1) { error = true; } @@ -90,7 +88,7 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, any_success = true; } else { streams.err.append_format(_(BUILTIN_SET_PATH_ERROR), L"set", key, dir.c_str(), - strerror(errno)); + strerror(errno)); const wchar_t *colon = wcschr(dir.c_str(), L':'); if (colon && *(colon + 1)) { @@ -338,7 +336,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) { int erase = 0, list = 0, unexport = 0; int universal = 0, query = 0; bool shorten_ok = true; - bool preserve_incoming_failure_exit_status = true; + bool preserve_failure_exit_status = true; const int incoming_exit_status = proc_get_last_status(); // Variables used for performing the actual work. @@ -364,12 +362,12 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } case 'e': { erase = 1; - preserve_incoming_failure_exit_status = false; + preserve_failure_exit_status = false; break; } case 'n': { list = 1; - preserve_incoming_failure_exit_status = false; + preserve_failure_exit_status = false; break; } case 'x': { @@ -398,7 +396,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } case 'q': { query = 1; - preserve_incoming_failure_exit_status = false; + preserve_failure_exit_status = false; break; } case 'h': { @@ -629,7 +627,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) { free(dest); - if (retcode == STATUS_BUILTIN_OK && preserve_incoming_failure_exit_status) + if (retcode == STATUS_BUILTIN_OK && preserve_failure_exit_status) retcode = incoming_exit_status; return retcode; } diff --git a/src/common.cpp b/src/common.cpp index d5647d9a8..b54f58bf0 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -43,7 +43,7 @@ struct termios shell_modes; // Note we foolishly assume that pthread_t is just a primitive. But it might be a struct. static pthread_t main_thread_id = 0; -static bool thread_assertions_configured_for_testing = false; +static bool thread_asserts_cfg_for_testing = false; wchar_t ellipsis_char; wchar_t omitted_newline_char; @@ -56,7 +56,7 @@ int debug_stack_frames = 0; // default number of stack frames to show on debug( static pid_t initial_pid = 0; /// Be able to restore the term's foreground process group. -static pid_t initial_foreground_process_group = -1; +static pid_t initial_fg_process_group = -1; /// This struct maintains the current state of the terminal size. It is updated on demand after /// receiving a SIGWINCH. Do not touch this struct directly, it's managed with a rwlock. Use @@ -1671,9 +1671,7 @@ __attribute__((noinline)) void debug_thread_error(void) { void set_main_thread() { main_thread_id = pthread_self(); } -void configure_thread_assertions_for_testing(void) { - thread_assertions_configured_for_testing = true; -} +void configure_thread_assertions_for_testing(void) { thread_asserts_cfg_for_testing = true; } bool is_forked_child(void) { // Just bail if nobody's called setup_fork_guards, e.g. some of our tools. @@ -1693,14 +1691,14 @@ void setup_fork_guards(void) { } void save_term_foreground_process_group(void) { - initial_foreground_process_group = tcgetpgrp(STDIN_FILENO); + initial_fg_process_group = tcgetpgrp(STDIN_FILENO); } void restore_term_foreground_process_group(void) { - if (initial_foreground_process_group != -1) { + if (initial_fg_process_group != -1) { // This is called during shutdown and from a signal handler. We don't bother to complain on // failure. - tcsetpgrp(STDIN_FILENO, initial_foreground_process_group); + tcsetpgrp(STDIN_FILENO, initial_fg_process_group); } } @@ -1710,7 +1708,7 @@ bool is_main_thread() { } void assert_is_main_thread(const char *who) { - if (!is_main_thread() && !thread_assertions_configured_for_testing) { + if (!is_main_thread() && !thread_asserts_cfg_for_testing) { fprintf(stderr, "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n", who); @@ -1728,7 +1726,7 @@ void assert_is_not_forked_child(const char *who) { } void assert_is_background_thread(const char *who) { - if (is_main_thread() && !thread_assertions_configured_for_testing) { + if (is_main_thread() && !thread_asserts_cfg_for_testing) { fprintf(stderr, "Warning: %s called on the main thread (may block!). Break on debug_thread_error " "to debug.\n", diff --git a/src/input.cpp b/src/input.cpp index a593a282d..971a6a9c8 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -56,8 +56,8 @@ struct input_mapping_t { input_mapping_t(const wcstring &s, const std::vector &c, const wcstring &m = DEFAULT_BIND_MODE, const wcstring &sm = DEFAULT_BIND_MODE) : seq(s), commands(c), mode(m), sets_mode(sm) { - static unsigned int s_last_input_mapping_specification_order = 0; - specification_order = ++s_last_input_mapping_specification_order; + static unsigned int s_last_input_map_spec_order = 0; + specification_order = ++s_last_input_map_spec_order; } }; diff --git a/src/iothread.cpp b/src/iothread.cpp index ca9e50a41..e9279dae9 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -57,9 +57,9 @@ static pthread_mutex_t s_result_queue_lock; static std::queue s_result_queue; // "Do on main thread" support. -static pthread_mutex_t s_main_thread_performer_lock; // protects the main thread requests -static pthread_cond_t s_main_thread_performer_condition; // protects the main thread requests -static pthread_mutex_t s_main_thread_request_queue_lock; // protects the queue +static pthread_mutex_t s_main_thread_performer_lock; // protects the main thread requests +static pthread_cond_t s_main_thread_performer_cond; // protects the main thread requests +static pthread_mutex_t s_main_thread_request_q_lock; // protects the queue static std::queue s_main_thread_request_queue; // Notifying pipes. @@ -73,9 +73,9 @@ static void iothread_init(void) { // Initialize some locks. VOMIT_ON_FAILURE(pthread_mutex_init(&s_spawn_queue_lock, NULL)); VOMIT_ON_FAILURE(pthread_mutex_init(&s_result_queue_lock, NULL)); - VOMIT_ON_FAILURE(pthread_mutex_init(&s_main_thread_request_queue_lock, NULL)); + VOMIT_ON_FAILURE(pthread_mutex_init(&s_main_thread_request_q_lock, NULL)); VOMIT_ON_FAILURE(pthread_mutex_init(&s_main_thread_performer_lock, NULL)); - VOMIT_ON_FAILURE(pthread_cond_init(&s_main_thread_performer_condition, NULL)); + VOMIT_ON_FAILURE(pthread_cond_init(&s_main_thread_performer_cond, NULL)); // Initialize the completion pipes. int pipes[2] = {0, 0}; @@ -287,7 +287,7 @@ static void iothread_service_main_thread_requests(void) { // Move the queue to a local variable. std::queue request_queue; { - scoped_lock queue_lock(s_main_thread_request_queue_lock); + scoped_lock queue_lock(s_main_thread_request_q_lock); std::swap(request_queue, s_main_thread_request_queue); } @@ -311,7 +311,7 @@ static void iothread_service_main_thread_requests(void) { // Because the waiting thread performs step 1 under the lock, if we take the lock, we avoid // posting before the waiting thread is waiting. scoped_lock broadcast_lock(s_main_thread_performer_lock); - VOMIT_ON_FAILURE(pthread_cond_broadcast(&s_main_thread_performer_condition)); + VOMIT_ON_FAILURE(pthread_cond_broadcast(&s_main_thread_performer_cond)); } } @@ -351,7 +351,7 @@ int iothread_perform_on_main_base(int (*handler)(void *), void *context) { // Append it. Do not delete the nested scope as it is crucial to the proper functioning of this // code by virtue of the lock management. { - scoped_lock queue_lock(s_main_thread_request_queue_lock); + scoped_lock queue_lock(s_main_thread_request_q_lock); s_main_thread_request_queue.push(&req); } @@ -365,7 +365,7 @@ int iothread_perform_on_main_base(int (*handler)(void *), void *context) { // It would be nice to support checking for cancellation here, but the clients need a // deterministic way to clean up to avoid leaks VOMIT_ON_FAILURE( - pthread_cond_wait(&s_main_thread_performer_condition, &s_main_thread_performer_lock)); + pthread_cond_wait(&s_main_thread_performer_cond, &s_main_thread_performer_lock)); } // Ok, the request must now be done. diff --git a/src/proc.cpp b/src/proc.cpp index 0a2439cd8..d2ef46757 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -388,7 +388,7 @@ typedef unsigned int process_generation_count_t; /// A static value tracking how many SIGCHLDs we have seen. This is only ever modified from within /// the SIGCHLD signal handler, and therefore does not need atomics or locks. -static volatile process_generation_count_t s_sigchld_generation_count = 0; +static volatile process_generation_count_t s_sigchld_generation_cnt = 0; /// If we have received a SIGCHLD signal, process any children. If await is false, this returns /// immediately if no SIGCHLD has been received. If await is true, this waits for one. Returns true @@ -397,10 +397,10 @@ static int process_mark_finished_children(bool wants_await) { ASSERT_IS_MAIN_THREAD(); // A static value tracking the SIGCHLD gen count at the time we last processed it. When this is - // different from s_sigchld_generation_count, it indicates there may be unreaped processes. + // different from s_sigchld_generation_cnt, it indicates there may be unreaped processes. // There may not be if we reaped them via the other waitpid path. This is only ever modified // from the main thread, and not from a signal handler. - static process_generation_count_t s_last_processed_sigchld_generation_count = 0; + static process_generation_count_t s_last_sigchld_generation_cnt = 0; int processed_count = 0; bool got_error = false; @@ -409,12 +409,12 @@ static int process_mark_finished_children(bool wants_await) { // needs to be an atomic read (we'd use sig_atomic_t, if we knew that were unsigned - // fortunately aligned unsigned int is atomic on pretty much any modern chip.) It also needs to // occur before we start reaping, since the signal handler can be invoked at any point. - const process_generation_count_t local_count = s_sigchld_generation_count; + const process_generation_count_t local_count = s_sigchld_generation_cnt; // Determine whether we have children to process. Note that we can't reliably use the difference // because a single SIGCHLD may be delivered for multiple children - see #1768. Also if we are // awaiting, we always process. - bool wants_waitpid = wants_await || local_count != s_last_processed_sigchld_generation_count; + bool wants_waitpid = wants_await || local_count != s_last_sigchld_generation_cnt; if (wants_waitpid) { for (;;) { @@ -448,7 +448,7 @@ static int process_mark_finished_children(bool wants_await) { if (got_error) { return -1; } - s_last_processed_sigchld_generation_count = local_count; + s_last_sigchld_generation_cnt = local_count; return processed_count; } @@ -458,7 +458,7 @@ void job_handle_signal(int signal, siginfo_t *info, void *context) { UNUSED(info); UNUSED(context); // This is the only place that this generation count is modified. It's OK if it overflows. - s_sigchld_generation_count += 1; + s_sigchld_generation_cnt += 1; } /// Given a command like "cat file", truncate it to a reasonable length. @@ -594,20 +594,17 @@ int job_reap(bool allow_interactive) { const wcstring job_number_desc = (job_count == 1) ? wcstring() : format_string(L"Job %d, ", j->job_id); fwprintf(stdout, _(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"), - program_name, job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); + program_name, job_number_desc.c_str(), + truncate_command(j->command()).c_str(), sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); } else { const wcstring job_number_desc = - (job_count == 1) ? wcstring() - : format_string(L"from job %d, ", j->job_id); + (job_count == 1) ? wcstring() : format_string(L"from job %d, ", j->job_id); fwprintf(stdout, _(L"%ls: Process %d, \'%ls\' %ls\'%ls\' " - L"terminated by signal %ls (%ls)"), - program_name, p->pid, p->argv0(), job_number_desc.c_str(), - truncate_command(j->command()).c_str(), - sig2wcs(WTERMSIG(p->status)), - signal_get_desc(WTERMSIG(p->status))); + L"terminated by signal %ls (%ls)"), + program_name, p->pid, p->argv0(), job_number_desc.c_str(), + truncate_command(j->command()).c_str(), sig2wcs(WTERMSIG(p->status)), + signal_get_desc(WTERMSIG(p->status))); } if (cur_term != NULL) { diff --git a/src/reader.cpp b/src/reader.cpp index 11b091282..00ffe9231 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -300,7 +300,7 @@ static wchar_t unescaped_quote(const wcstring &str, size_t pos); static struct termios terminal_mode_on_startup; /// Mode we use to execute programs. -static struct termios terminal_mode_for_executing_programs; +static struct termios tty_modes_for_external_cmds; static void reader_super_highlight_me_plenty(int highlight_pos_adjust = 0, bool no_io = false); @@ -312,7 +312,7 @@ static void term_donate() { set_color(rgb_color_t::normal(), rgb_color_t::normal()); while (1) { - if (tcsetattr(0, TCSANOW, &terminal_mode_for_executing_programs)) { + if (tcsetattr(0, TCSANOW, &tty_modes_for_external_cmds)) { if (errno != EINTR) { debug(1, _(L"Could not set terminal mode for new job")); wperror(L"tcsetattr"); @@ -773,10 +773,10 @@ void reader_init() { tcgetattr(STDIN_FILENO, &terminal_mode_on_startup); // Set the mode used for program execution, initialized to the current mode. - memcpy(&terminal_mode_for_executing_programs, &terminal_mode_on_startup, - sizeof terminal_mode_for_executing_programs); - terminal_mode_for_executing_programs.c_iflag &= ~IXON; // disable flow control - terminal_mode_for_executing_programs.c_iflag &= ~IXOFF; // disable flow control + memcpy(&tty_modes_for_external_cmds, &terminal_mode_on_startup, + sizeof tty_modes_for_external_cmds); + tty_modes_for_external_cmds.c_iflag &= ~IXON; // disable flow control + tty_modes_for_external_cmds.c_iflag &= ~IXOFF; // disable flow control // Set the mode used for the terminal, initialized to the current mode. memcpy(&shell_modes, &terminal_mode_on_startup, sizeof shell_modes); @@ -1362,12 +1362,12 @@ static fuzzy_match_type_t get_best_match_type(const std::vector &c /// through the completions. /// /// \param comp the list of completion strings -/// \param continue_after_prefix_insertion If we have a shared prefix, whether to print the list of +/// \param cont_after_prefix_insertion If we have a shared prefix, whether to print the list of /// completions after inserting it. /// /// Return true if we inserted text into the command line, false if we did not. static bool handle_completions(const std::vector &comp, - bool continue_after_prefix_insertion) { + bool cont_after_prefix_insertion) { bool done = false; bool success = false; const editable_line_t *el = &data->command_line; @@ -1486,7 +1486,7 @@ static bool handle_completions(const std::vector &comp, } } - if (!continue_after_prefix_insertion && use_prefix) { + if (!cont_after_prefix_insertion && use_prefix) { return success; } @@ -2624,8 +2624,8 @@ const wchar_t *reader_readline(int nchars) { data->cycle_command_line = el->text; data->cycle_cursor_pos = el->position; - bool continue_after_prefix_insertion = (c == R_COMPLETE_AND_SEARCH); - comp_empty = handle_completions(comp, continue_after_prefix_insertion); + bool cont_after_prefix_insertion = (c == R_COMPLETE_AND_SEARCH); + comp_empty = handle_completions(comp, cont_after_prefix_insertion); // Show the search field if requested and if we printed a list of completions. if (c == R_COMPLETE_AND_SEARCH && !comp_empty && !data->pager.empty()) { From 4e505efc508248bf77a7bbf9193d5ed784d61115 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 3 Nov 2016 16:32:27 -0700 Subject: [PATCH 080/112] lint: redundant if statement --- src/highlight.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/highlight.cpp b/src/highlight.cpp index 260a8cac4..6033de4d4 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -337,17 +337,10 @@ bool autosuggest_validate_from_history(const history_item_t &item, handled = true; bool is_help = string_prefixes_string(dir, L"--help") || string_prefixes_string(dir, L"-h"); - if (is_help) { - suggestionOK = false; - } else { + if (!is_help) { wcstring path; bool can_cd = path_get_cdpath(dir, &path, working_directory.c_str(), vars); - if (!can_cd) { - suggestionOK = false; - } else if (paths_are_same_file(working_directory, path)) { - // Don't suggest the working directory as the path! - suggestionOK = false; - } else { + if (can_cd && !paths_are_same_file(working_directory, path)) { suggestionOK = true; } } From de87419df92326a85910b2211975855e0bcf6b8a Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 3 Nov 2016 16:37:26 -0700 Subject: [PATCH 081/112] lint: multiple unary operator --- src/builtin.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index a3a167963..caca9928d 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -908,7 +908,7 @@ static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **ar /// Return a definition of the specified function. Used by the functions builtin. static wcstring functions_def(const wcstring &name) { - CHECK(!name.empty(), L""); + CHECK(!name.empty(), L""); //!OCLINT(multiple unary operator) wcstring out; wcstring desc, def; function_get_desc(name, &desc); @@ -1090,7 +1090,8 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t ** } // Erase, desc, query, copy and list are mutually exclusive. - if ((erase + (!!desc) + list + query + copy) > 1) { + int describe = desc ? 1 : 0; + if (erase + describe + list + query + copy > 1) { streams.err.append_format(_(L"%ls: Invalid combination of options\n"), argv[0]); builtin_print_help(parser, streams, argv[0], streams.err); From 003ea8341094a7b3d7988aa003f80d704d8365a6 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 3 Nov 2016 16:41:51 -0700 Subject: [PATCH 082/112] lint: too few branches in switch statement --- src/parse_util.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 184dcd1f3..5e84f2fcf 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -1171,21 +1171,16 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src, break; } - switch (parse_node_tree_t::statement_boolean_type(*spec_statement)) { - case parse_bool_and: { // this is not allowed + parse_bool_statement_type_t bool_type = + parse_node_tree_t::statement_boolean_type(*spec_statement); + if (bool_type == parse_bool_and) { // this is not allowed errored = append_syntax_error( &parse_errors, spec_statement->source_start, BOOL_AFTER_BACKGROUND_ERROR_MSG, L"and"); - break; - } - case parse_bool_or: { // this is not allowed + } else if (bool_type == parse_bool_or) { // this is not allowed errored = append_syntax_error( &parse_errors, spec_statement->source_start, BOOL_AFTER_BACKGROUND_ERROR_MSG, L"or"); - break; - } - // All others are OK. - default: { break; } } break; } From 23c3101440684f87f49420d1ef664b868fb86d69 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 3 Nov 2016 16:53:58 -0700 Subject: [PATCH 083/112] lint: goto and dead code --- src/builtin_printf.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp index e2d2d14ad..645dd982b 100644 --- a/src/builtin_printf.cpp +++ b/src/builtin_printf.cpp @@ -597,8 +597,7 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch } modify_allowed_format_specifiers(ok, "aAcdeEfFgGiosuxX", true); - - for (;; f++, direc_length++) { + for (bool continue_looking_for_flags = true; continue_looking_for_flags;) { switch (*f) { case L'I': case L'\'': { @@ -619,12 +618,15 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch break; } default: { - goto no_more_flag_characters; + continue_looking_for_flags = false; break; } } + if (continue_looking_for_flags) { + f++; + direc_length++; + } } - no_more_flag_characters:; if (*f == L'*') { ++f; From 097d2246c2f9ee438230d8b5772f3a531256b979 Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Wed, 26 Oct 2016 14:02:30 +0200 Subject: [PATCH 084/112] add dig completion --- share/completions/dig.fish | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 share/completions/dig.fish diff --git a/share/completions/dig.fish b/share/completions/dig.fish new file mode 100644 index 000000000..7a8b11031 --- /dev/null +++ b/share/completions/dig.fish @@ -0,0 +1,64 @@ +# completion for dig + +function __fish_complete_dig + set -l token (commandline -ct) + switch $token + case '+tries=*' '+retry=*' '+time=*' '+bufsize=*' '+ndots=*' '+edns=*' + printf '%s\n' $token(seq 0 50) + end +end + +complete -f -c dig -s 4 -d 'Use IPv4 query transport only' +complete -f -c dig -s 6 -d 'Use IPv6 query transport only' +complete -f -c dig -s m -d 'Enable memory usage debugging' +complete -c dig -s b -x -d 'Bind to source address/port' +complete -c dig -s f -r -d 'Specify batch mode file' +complete -c dig -s c -x -a 'IN CH HS QCLASS' -d 'Specify query class' +complete -c dig -s k -r -d 'Specify TSIG key file' +complete -c dig -s y -x -d 'specify named base64 TSIG key' +complete -c dig -s p -x -d 'Specify port number' +complete -c dig -s q -x -d 'Specify query name' +complete -c dig -s t -x -a 'A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT URI' -d 'Specify query type' +complete -c dig -s x -x -d 'Reverse lookup' +complete -f -c dig -s h -d 'Print help and exit' +complete -f -c dig -s v -d 'Print version and exit' + +complete -f -c dig -a '+vc +novc' -d 'TCP mode' +complete -f -c dig -a '+tcp +notcp' -d 'TCP mode, alternate syntax' +complete -f -c dig -a '+search +nosearch' -d 'Set whether to use searchlist' +complete -f -c dig -a '+showsearch +noshowsearch' -d 'Search with intermediate results' +complete -f -c dig -a '+defname +nodefname' -d 'Deprecated, treated as a synonym for +[no]search' +complete -f -c dig -a '+recurse +norecurse' -d 'Recursive mode' +complete -f -c dig -a '+ignore +noignore' -d 'Dont revert to TCP for TC responses.' +complete -f -c dig -a '+fail +nofail' -d 'Dont try next server on SERVFAIL' +complete -f -c dig -a '+besteffort +nobesteffort' -d 'Try to parse even illegal messages' +complete -f -c dig -a '+aaonly +noaaonly' -d 'Set AA flag in query (+[no]aaflag)' +complete -f -c dig -a '+adflag +noadflag' -d 'Set AD flag in query' +complete -f -c dig -a '+cdflag +nocdflag' -d 'Set CD flag in query' +complete -f -c dig -a '+cl +nocl' -d 'Control display of class in records' +complete -f -c dig -a '+cmd +nocmd' -d 'Control display of command line' +complete -f -c dig -a '+comments +nocomments' -d 'Control display of comment lines' +complete -f -c dig -a '+question +noquestion' -d 'Control display of question' +complete -f -c dig -a '+answer +noanswer' -d 'Control display of answer' +complete -f -c dig -a '+authority +noauthority' -d 'Control display of authority' +complete -f -c dig -a '+additional +noadditional' -d 'Control display of additional' +complete -f -c dig -a '+stats +nostats' -d 'Control display of statistics' +complete -f -c dig -a '+short +noshort' -d 'Disable everything except short form of answer' +complete -f -c dig -a '+ttlid +nottlid' -d 'Control display of ttls in records' +complete -f -c dig -a '+all +noall' -d 'Set or clear all display flags' +complete -f -c dig -a '+qr +noqr' -d 'Print question before sending' +complete -f -c dig -a '+nssearch +nonssearch' -d 'Search all authoritative nameservers' +complete -f -c dig -a '+identify +noidentify' -d 'ID responders in short answers' +complete -f -c dig -a '+trace +notrace' -d 'Trace delegation down from root' +complete -f -c dig -a '+dnssec +nodnssec' -d 'Request DNSSEC records' +complete -f -c dig -a '+nsid +nonsid' -d 'Request Name Server ID' +complete -f -c dig -a '+multiline +nomultiline' -d 'Print records in an expanded format' +complete -f -c dig -a '+onesoa +noonesoa' -d 'AXFR prints only one soa record' + +complete -f -c dig -a '+tries=' -d 'Set number of UDP attempts' +complete -f -c dig -a '+retry=' -d 'Set number of UDP retries' +complete -f -c dig -a '+time=' -d 'Set query timeout' +complete -f -c dig -a '+bufsize=' -d 'Set EDNS0 Max UDP packet size' +complete -f -c dig -a '+ndots=' -d 'Set NDOTS value' +complete -f -c dig -a '+edns=' -d 'Set EDNS version' +complete -c dig -a '(__fish_complete_dig)' From 00a8766635bf800a99ca02aefaebe9da1e298643 Mon Sep 17 00:00:00 2001 From: Manzur Mukhitdinov Date: Tue, 25 Oct 2016 18:44:17 +0200 Subject: [PATCH 085/112] auto-complete for sysbench (0.4.12) SysBench is a modular, cross-platform and multi-threaded benchmark tool for evaluating OS parameters that are important for a system running a database under intensive load --- share/completions/sysbench.fish | 111 ++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 share/completions/sysbench.fish diff --git a/share/completions/sysbench.fish b/share/completions/sysbench.fish new file mode 100644 index 000000000..36b1d1bc5 --- /dev/null +++ b/share/completions/sysbench.fish @@ -0,0 +1,111 @@ +### Auto-complete for sysbench (cross-platform and multi-threaded benchmark tool) ### + +### sub commands specification ### +complete -c sysbench -f -a "run\t'Run the test'" +complete -c sysbench -n "__fish_contains_opt test=fileio" -a " + prepare\t'Prepare and create test file' + cleanup\t'Cleanup test files' + " +complete -c sysbench -n "__fish_contains_opt test=oltp" -a " + prepare\t'Prepare test table' + cleanup\t'Cleanup test table' + " + +### generic long options specification ### +complete -c sysbench -x -l num-threads -d 'The total number of worker threads to create (default: 1)' +complete -c sysbench -x -l max-requests -d 'Limit for total number of requests. 0 means unlimited (default: 10000)' +complete -c sysbench -x -l max-time -d 'Limit for total execution time in seconds. 0 means unlimited (default: 0)' +complete -c sysbench -x -l thread-stack-size -d 'Size of stack for each thread (defaut: 32K)' +complete -c sysbench -f -l init-rng -d 'Specifies if random numbers generator should be initialized from timer (defaut: off)' -a 'on off' +complete -c sysbench -x -l test -d 'Name of the test mode to run(required)' -a " + cpu\t'Benchmark cpu by calculating prime numbers' + threads\t'Benchmark scheduler performance' + mutex\t'Benchmark mutex implementation' + fileio\t'Benchmark various file I/O workloads' + oltp\t'Benchmark a real database performance' + " +complete -c sysbench -f -l debug -d 'Print more debug info (default: off)' -a 'on off' +complete -c sysbench -f -l validate -d 'Perform validation of test results where possible (default: off)' -a 'on off' +complete -c sysbench -l help -d 'Print help on general syntax' +complete -c sysbench -l version -d 'Show version of program' +complete -c sysbench -x -l percentile -d 'A percentile rank of query execution times to count (default: 95)' +complete -c sysbench -f -l batch -d 'Dump current results periodically (default: off)' -a 'on off' +complete -c sysbench -x -l batch-delay -d 'Delay between batch dumps in secods (default: 300)' + +### options for test=`cpu` mode ### +complete -c sysbench -n "__fish_contains_opt test=cpu" -x -l cpu-max-prime -d 'Calculation of prime numbers up to the specified value' + +### options for test=`threads` mode ### +complete -c sysbench -n "__fish_contains_opt test=threads" -x -l thread-yields -d 'Number of lock/yield/unlock loops to execute per each request (default: 1000)' +complete -c sysbench -n "__fish_contains_opt test=threads" -x -l thread-locks -d 'Number of mutexes to create (default: 8)' + +### options for test=`mutex` mode ### +complete -c sysbench -n "__fish_contains_opt test=mutex" -x -l mutex-num -d 'Number of mutexes to create (default: 4096)' +complete -c sysbench -n "__fish_contains_opt test=mutex" -x -l memory-scope -d 'Specifies whether each thread uses a global or local allocation (default:global)' -a " + local\t'Allocate memory locally' + global\t'Allocate memory globally' + " +complete -c sysbench -n "__fish_contains_opt test=mutex" -x -l memory-total-size -d 'Total size of data to transfer (default: 100G)' +complete -c sysbench -n "__fish_contains_opt test=mutex" -x -l memory-oper -d 'Type of memory operations' -a 'read write' + +### options for test=`fileio` mode ### +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-num -d 'Number of files to create (default: 128)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-block-size -d 'Block size to use in all I/O operations (default: 16K)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-total-size -d 'Total size of files (default: 2G)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-test-mode -d 'Type of workload to produce' -a " + seqwr\t'Sequential write' + seqrewr\t'Sequential rewrite' + seqrd\t'Sequential read' + rndrd\t'Random read' + rndwr\t'Random write' + rndrw\t'Random read/write' + " +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-io-mode -d 'I/O mode (default: sync)' -a 'sync async fastmmap slowmmap' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-async-backlog -d 'Number of asynchronous operations to queue per thread (default: 128)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-extra-flags -d 'Additional flags to use with open(2)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-fsync-freq -d 'Do fsync() after this number of requests (default: 0)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -f -l file-fsync-all -d 'Do fsync() after each write operation (default: no)' -a 'yes no' +complete -c sysbench -n "__fish_contains_opt test=fileio" -f -l file-fsync-end -d 'Do fsync() at the end of the test (default: yes)' -a 'yes no' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-fsync-mode -d 'Method used for synchronization: fsync, fdatasync (default: fsync)' -a 'fsync fdatasync' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-merged-requests -d 'Upper limit of I/O requests merge (default: 0)' +complete -c sysbench -n "__fish_contains_opt test=fileio" -x -l file-rw-ratio -d 'reads/writes ratio for combined random read/write test (default: 1.5)' + +### options for test=`oltp` mode ### +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-test-mode -d 'Execution mode: simple, complex and nontrx(non-transactional)(default: complex)' -a " + simple\t'Simple' + complex\t'Advanced transactional' + nontrx\t'Non-transactional' + " +complete -c sysbench -n "__fish_contains_opt test=oltp" -f -l oltp-read-only -d 'Read-only mode. No UPDATE, DELETE or INSERT queries will be performed. (default: off)' -a 'on off' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-range-size -d 'Range size for range queries (default: 100)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-point-selects -d 'Number of point select queries in a single transaction (default: 10)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-simple-ranges -d 'Number of simple range queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-sum-ranges -d 'Number of SUM range queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-order-ranges -d 'Number of ORDER range queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-distinct-ranges -d 'Number of DISTINCT range queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-index-updates -d 'Number of index UPDATE queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-non-index-updates -d 'Number of non-index UPDATE queries in a single transaction (default: 1)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-nontrx-mode -d 'Type of queries for non-transactional execution mode (default: select)' -a 'select update_key update_nokey insert delete' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-connect-delay -d 'Time to sleep(in microseconds) after each connection to database (default: 10000)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-user-delay-min -d 'Minimum time to sleep(in microseconds) after each request (default: 0)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-user-delay-max -d 'Maximum time to sleep(in microseconds) after each request (default: 0)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-table-name -d 'Name of the test table (default: sbtest)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-table-size -d 'Number of rows in the test table (default: 10000)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l oltp-dist-type -d 'Distribution type of random numbers (default: special)' -a " + uniform\t'Uniform distribution' + gauss\t'Gaussian distribution' + special\t'Specified percent of numbers is generated in a specified percent of cases' + " +complete -c sysbench -n "__fish_contains_opt oltp-dist-type=special" -x -l oltp-dist-pct -d 'Percentage of values to be treated as \'special\'(default: 1)' +complete -c sysbench -n "__fish_contains_opt oltp-dist-type=special" -x -l oltp-dist-res -d 'Percentage of cases when \'special\' values are generated (default: 75)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l db-ps-mode -d 'Use "Prepared Statements" API if supported, otherwise - use clientside statements: disable, auto (default: auto)' -a 'disable auto' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-host -d 'MySQL server host (default: localhost)' -a "(__fish_print_hostnames)" +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-port -d 'MySQL server port (default: 3306)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -l mysql-socket -d 'Unix socket file to communicate with the MySQL server' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-user -d 'MySQL user (default: sbtest)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-password -d 'MySQL password' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-db -d 'MySQL database name (default: sbtest)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-table-engine -d 'Type of the test table to use' -a 'myisam innodb heap ndbcluster bdb maria falcon pbxt' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l mysql-ssl -d 'Use SSL connections. (default: no)' -a 'yes no' +complete -c sysbench -n "__fish_contains_opt test=oltp" -x -l myisam-max-rows -d 'MAX_ROWS option for MyISAM tables (required for big tables) (default: 1000000)' +complete -c sysbench -n "__fish_contains_opt test=oltp" -l mysql-create-options -d 'Additional options passed to CREATE TABLE.' From 2f28e96956e78e052041c9ea00b5d59c961863c5 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 17:55:51 -0700 Subject: [PATCH 086/112] Fix fish_tests xcode target --- fish.xcodeproj/project.pbxproj | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 5aa3fa599..f27f0fa3a 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -67,6 +67,15 @@ /* Begin PBXBuildFile section */ 63A2C0E91CC60F3B00973404 /* pcre2_find_bracket.c in Sources */ = {isa = PBXBuildFile; fileRef = 63A2C0E81CC5F9FB00973404 /* pcre2_find_bracket.c */; }; + 9C7A55271DCD651F0049C25D /* fallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853E13B3ACEE0099B651 /* fallback.cpp */; }; + 9C7A55281DCD65540049C25D /* builtin_commandline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853013B3ACEE0099B651 /* builtin_commandline.cpp */; }; + 9C7A55291DCD65540049C25D /* builtin_complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853113B3ACEE0099B651 /* builtin_complete.cpp */; }; + 9C7A552A1DCD65540049C25D /* builtin_jobs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853213B3ACEE0099B651 /* builtin_jobs.cpp */; }; + 9C7A552B1DCD65540049C25D /* builtin_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853313B3ACEE0099B651 /* builtin_set.cpp */; }; + 9C7A552C1DCD65540049C25D /* builtin_set_color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C861EA16CC7054003B5A04 /* builtin_set_color.cpp */; }; + 9C7A552D1DCD65540049C25D /* builtin_ulimit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853413B3ACEE0099B651 /* builtin_ulimit.cpp */; }; + 9C7A552E1DCD65540049C25D /* builtin_printf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0CA63F316FC275F00093BD4 /* builtin_printf.cpp */; }; + 9C7A552F1DCD65820049C25D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855E13B3ACEE0099B651 /* util.cpp */; }; D00769121990137800CA4627 /* autoload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C6FCC914CFA4B0004CE8AD /* autoload.cpp */; }; D00769131990137800CA4627 /* builtin_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0F3373A1506DE3C00ECEFC0 /* builtin_test.cpp */; }; D00769141990137800CA4627 /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B6B0FE14E88BA400AD6C10 /* color.cpp */; }; @@ -1230,6 +1239,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C7A552F1DCD65820049C25D /* util.cpp in Sources */, + 9C7A55281DCD65540049C25D /* builtin_commandline.cpp in Sources */, + 9C7A55291DCD65540049C25D /* builtin_complete.cpp in Sources */, + 9C7A552A1DCD65540049C25D /* builtin_jobs.cpp in Sources */, + 9C7A552B1DCD65540049C25D /* builtin_set.cpp in Sources */, + 9C7A552C1DCD65540049C25D /* builtin_set_color.cpp in Sources */, + 9C7A552D1DCD65540049C25D /* builtin_ulimit.cpp in Sources */, + 9C7A552E1DCD65540049C25D /* builtin_printf.cpp in Sources */, + 9C7A55271DCD651F0049C25D /* fallback.cpp in Sources */, D00769121990137800CA4627 /* autoload.cpp in Sources */, D00769131990137800CA4627 /* builtin_test.cpp in Sources */, D00769141990137800CA4627 /* color.cpp in Sources */, From d437a84828429d7fad541d94c839da3b9d08764a Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 18:11:37 -0700 Subject: [PATCH 087/112] Fix two xcode warnings An unused macro and a documentation error. --- src/env.cpp | 2 +- src/fish_tests.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/env.cpp b/src/env.cpp index 7d84992d0..5a9770f92 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -479,7 +479,7 @@ static env_node_t *env_get_node(const wcstring &key) { /// /// \param key The key /// \param val The value -/// \param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, +/// \param var_mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, /// ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current /// mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed. /// diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 9b82ded00..99a0741ae 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -95,8 +95,6 @@ static bool should_test_function(const char *func_name) { #define ESCAPE_TEST_LENGTH 100 /// The higest character number of character to try and escape. #define ESCAPE_TEST_CHAR 4000 -/// Number of laps to run performance testing loop. -#define LAPS 50 /// Number of encountered errors. static int err_count = 0; From 294e78205c3302eaac547966e7ee8917c5605054 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 18:50:37 -0700 Subject: [PATCH 088/112] Allow xcode to build fish_key_reader --- fish.xcodeproj/project.pbxproj | 234 +++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index f27f0fa3a..48f5f0156 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -76,6 +76,62 @@ 9C7A552D1DCD65540049C25D /* builtin_ulimit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853413B3ACEE0099B651 /* builtin_ulimit.cpp */; }; 9C7A552E1DCD65540049C25D /* builtin_printf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0CA63F316FC275F00093BD4 /* builtin_printf.cpp */; }; 9C7A552F1DCD65820049C25D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855E13B3ACEE0099B651 /* util.cpp */; }; + 9C7A55361DCD71330049C25D /* autoload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C6FCC914CFA4B0004CE8AD /* autoload.cpp */; }; + 9C7A55371DCD71330049C25D /* builtin_commandline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853013B3ACEE0099B651 /* builtin_commandline.cpp */; }; + 9C7A55381DCD71330049C25D /* builtin_complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853113B3ACEE0099B651 /* builtin_complete.cpp */; }; + 9C7A55391DCD71330049C25D /* builtin_jobs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853213B3ACEE0099B651 /* builtin_jobs.cpp */; }; + 9C7A553A1DCD71330049C25D /* builtin_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853313B3ACEE0099B651 /* builtin_set.cpp */; }; + 9C7A553B1DCD71330049C25D /* builtin_set_color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C861EA16CC7054003B5A04 /* builtin_set_color.cpp */; }; + 9C7A553C1DCD71330049C25D /* builtin_ulimit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853413B3ACEE0099B651 /* builtin_ulimit.cpp */; }; + 9C7A553D1DCD71330049C25D /* builtin_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0F3373A1506DE3C00ECEFC0 /* builtin_test.cpp */; }; + 9C7A553E1DCD71330049C25D /* builtin_printf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0CA63F316FC275F00093BD4 /* builtin_printf.cpp */; }; + 9C7A553F1DCD71330049C25D /* builtin_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D04F7F7B1BA4BF4000B0F227 /* builtin_string.cpp */; }; + 9C7A55401DCD71330049C25D /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B6B0FE14E88BA400AD6C10 /* color.cpp */; }; + 9C7A55411DCD71330049C25D /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; }; + 9C7A55421DCD71330049C25D /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853B13B3ACEE0099B651 /* event.cpp */; }; + 9C7A55431DCD71330049C25D /* input_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854913B3ACEE0099B651 /* input_common.cpp */; }; + 9C7A55441DCD71330049C25D /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854C13B3ACEE0099B651 /* io.cpp */; }; + 9C7A55451DCD71330049C25D /* iothread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854D13B3ACEE0099B651 /* iothread.cpp */; }; + 9C7A55461DCD71330049C25D /* parse_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855213B3ACEE0099B651 /* parse_util.cpp */; }; + 9C7A55471DCD71330049C25D /* path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855513B3ACEE0099B651 /* path.cpp */; }; + 9C7A55481DCD71330049C25D /* parse_execution.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D052D8091868F7FC003ABCBD /* parse_execution.cpp */; }; + 9C7A55491DCD71330049C25D /* postfork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D09B1C1914FC7B5B00F91077 /* postfork.cpp */; }; + 9C7A554A1DCD71330049C25D /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855A13B3ACEE0099B651 /* screen.cpp */; }; + 9C7A554B1DCD71330049C25D /* signal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855C13B3ACEE0099B651 /* signal.cpp */; }; + 9C7A554C1DCD71330049C25D /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; }; + 9C7A554D1DCD71330049C25D /* builtin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853513B3ACEE0099B651 /* builtin.cpp */; }; + 9C7A554E1DCD71330049C25D /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854413B3ACEE0099B651 /* function.cpp */; }; + 9C7A554F1DCD71330049C25D /* complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853713B3ACEE0099B651 /* complete.cpp */; }; + 9C7A55501DCD71330049C25D /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853A13B3ACEE0099B651 /* env.cpp */; }; + 9C7A55511DCD71330049C25D /* exec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853C13B3ACEE0099B651 /* exec.cpp */; }; + 9C7A55521DCD71330049C25D /* wcstringutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0F5B46319CFCDE80090665E /* wcstringutil.cpp */; }; + 9C7A55531DCD71330049C25D /* expand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853D13B3ACEE0099B651 /* expand.cpp */; }; + 9C7A55541DCD71330049C25D /* fallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853E13B3ACEE0099B651 /* fallback.cpp */; }; + 9C7A55551DCD71330049C25D /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; settings = {COMPILER_FLAGS = "-I$(DERIVED_FILE_DIR)"; }; }; + 9C7A55561DCD71330049C25D /* highlight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854713B3ACEE0099B651 /* highlight.cpp */; }; + 9C7A55571DCD71330049C25D /* history.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854813B3ACEE0099B651 /* history.cpp */; }; + 9C7A55581DCD71330049C25D /* kill.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854F13B3ACEE0099B651 /* kill.cpp */; }; + 9C7A55591DCD71330049C25D /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855413B3ACEE0099B651 /* parser.cpp */; }; + 9C7A555A1DCD71330049C25D /* parser_keywords.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */; }; + 9C7A555B1DCD71330049C25D /* proc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855713B3ACEE0099B651 /* proc.cpp */; }; + 9C7A555C1DCD71330049C25D /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855813B3ACEE0099B651 /* reader.cpp */; }; + 9C7A555D1DCD71330049C25D /* sanity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855913B3ACEE0099B651 /* sanity.cpp */; }; + 9C7A555E1DCD71330049C25D /* tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855D13B3ACEE0099B651 /* tokenizer.cpp */; }; + 9C7A555F1DCD71330049C25D /* wildcard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0856013B3ACEE0099B651 /* wildcard.cpp */; }; + 9C7A55601DCD71330049C25D /* wgetopt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855F13B3ACEE0099B651 /* wgetopt.cpp */; }; + 9C7A55611DCD71330049C25D /* wutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0856113B3ACEE0099B651 /* wutil.cpp */; }; + 9C7A55621DCD71330049C25D /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854A13B3ACEE0099B651 /* input.cpp */; }; + 9C7A55631DCD71330049C25D /* output.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855113B3ACEE0099B651 /* output.cpp */; }; + 9C7A55641DCD71330049C25D /* intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854B13B3ACEE0099B651 /* intern.cpp */; }; + 9C7A55651DCD71330049C25D /* env_universal_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */; }; + 9C7A55661DCD71330049C25D /* pager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D03238891849D1980032CF2C /* pager.cpp */; }; + 9C7A55681DCD71330049C25D /* parse_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C52F351765284C00BFAB82 /* parse_tree.cpp */; }; + 9C7A55691DCD71330049C25D /* parse_productions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FE8EE7179FB75F008C9F21 /* parse_productions.cpp */; }; + 9C7A556A1DCD71330049C25D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855E13B3ACEE0099B651 /* util.cpp */; }; + 9C7A556C1DCD71330049C25D /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; }; + 9C7A556D1DCD71330049C25D /* libpcre2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D04F7FD01BA4E29300B0F227 /* libpcre2.a */; }; + 9C7A557D1DCD71890049C25D /* fish_key_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A557C1DCD717C0049C25D /* fish_key_reader.cpp */; }; + 9C7A557E1DCD71CD0049C25D /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; }; D00769121990137800CA4627 /* autoload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C6FCC914CFA4B0004CE8AD /* autoload.cpp */; }; D00769131990137800CA4627 /* builtin_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0F3373A1506DE3C00ECEFC0 /* builtin_test.cpp */; }; D00769141990137800CA4627 /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B6B0FE14E88BA400AD6C10 /* color.cpp */; }; @@ -295,6 +351,20 @@ /* End PBXBuildRule section */ /* Begin PBXContainerItemProxy section */ + 9C7A55321DCD71330049C25D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D0A084F213B3AC130099B651 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D008D0C41BC58F8800841177; + remoteInfo = "generate-version-header"; + }; + 9C7A55341DCD71330049C25D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D0A084F213B3AC130099B651 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D04F7FCF1BA4E29300B0F227; + remoteInfo = libpcre2.a; + }; D008D0CA1BC58FDD00841177 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D0A084F213B3AC130099B651 /* Project object */; @@ -477,6 +547,17 @@ /* Begin PBXFileReference section */ 4E142D731B56B5D7008783C8 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../osx/config.h; sourceTree = ""; }; 63A2C0E81CC5F9FB00973404 /* pcre2_find_bracket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pcre2_find_bracket.c; sourceTree = ""; }; + 9C7A55721DCD71330049C25D /* fish_key_reader */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_key_reader; sourceTree = BUILT_PRODUCTS_DIR; }; + 9C7A55731DCD716F0049C25D /* builtin_commandline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_commandline.h; sourceTree = ""; }; + 9C7A55741DCD716F0049C25D /* builtin_complete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_complete.h; sourceTree = ""; }; + 9C7A55751DCD716F0049C25D /* builtin_jobs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_jobs.h; sourceTree = ""; }; + 9C7A55761DCD716F0049C25D /* builtin_printf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_printf.h; sourceTree = ""; }; + 9C7A55771DCD716F0049C25D /* builtin_set_color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_set_color.h; sourceTree = ""; }; + 9C7A55781DCD716F0049C25D /* builtin_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_set.h; sourceTree = ""; }; + 9C7A55791DCD716F0049C25D /* builtin_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_string.h; sourceTree = ""; }; + 9C7A557A1DCD716F0049C25D /* builtin_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_test.h; sourceTree = ""; }; + 9C7A557B1DCD716F0049C25D /* builtin_ulimit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtin_ulimit.h; sourceTree = ""; }; + 9C7A557C1DCD717C0049C25D /* fish_key_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_key_reader.cpp; sourceTree = ""; }; D00769421990137800CA4627 /* fish_tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_tests; sourceTree = BUILT_PRODUCTS_DIR; }; D00F63F019137E9D00FCCDEC /* fish_version.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_version.cpp; sourceTree = ""; }; D01A2D23169B730A00767098 /* man1 */ = {isa = PBXFileReference; lastKnownFileType = text; name = man1; path = pages_for_manpath/man1; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -627,6 +708,15 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 9C7A556B1DCD71330049C25D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C7A556C1DCD71330049C25D /* libncurses.dylib in Frameworks */, + 9C7A556D1DCD71330049C25D /* libpcre2.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D007693C1990137800CA4627 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -752,6 +842,16 @@ D0D02A91159845EF008E62BD /* Sources */ = { isa = PBXGroup; children = ( + 9C7A557C1DCD717C0049C25D /* fish_key_reader.cpp */, + 9C7A55731DCD716F0049C25D /* builtin_commandline.h */, + 9C7A55741DCD716F0049C25D /* builtin_complete.h */, + 9C7A55751DCD716F0049C25D /* builtin_jobs.h */, + 9C7A55761DCD716F0049C25D /* builtin_printf.h */, + 9C7A55771DCD716F0049C25D /* builtin_set_color.h */, + 9C7A55781DCD716F0049C25D /* builtin_set.h */, + 9C7A55791DCD716F0049C25D /* builtin_string.h */, + 9C7A557A1DCD716F0049C25D /* builtin_test.h */, + 9C7A557B1DCD716F0049C25D /* builtin_ulimit.h */, 4E142D731B56B5D7008783C8 /* config.h */, D0C6FCCB14CFA4B7004CE8AD /* autoload.h */, D0C6FCC914CFA4B0004CE8AD /* autoload.cpp */, @@ -897,6 +997,7 @@ D0D02AD01598642A008E62BD /* fish_indent */, D00769421990137800CA4627 /* fish_tests */, D04F7FD01BA4E29300B0F227 /* libpcre2.a */, + 9C7A55721DCD71330049C25D /* fish_key_reader */, ); name = Products; sourceTree = ""; @@ -914,6 +1015,24 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 9C7A55301DCD71330049C25D /* fish_key_reader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9C7A556E1DCD71330049C25D /* Build configuration list for PBXNativeTarget "fish_key_reader" */; + buildPhases = ( + 9C7A55351DCD71330049C25D /* Sources */, + 9C7A556B1DCD71330049C25D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9C7A55311DCD71330049C25D /* PBXTargetDependency */, + 9C7A55331DCD71330049C25D /* PBXTargetDependency */, + ); + name = fish_key_reader; + productName = fish_Xcode; + productReference = 9C7A55721DCD71330049C25D /* fish_key_reader */; + productType = "com.apple.product-type.tool"; + }; D00769101990137800CA4627 /* fish_tests */ = { isa = PBXNativeTarget; buildConfigurationList = D007693E1990137800CA4627 /* Build configuration list for PBXNativeTarget "fish_tests" */; @@ -1040,6 +1159,7 @@ D00769101990137800CA4627 /* fish_tests */, D04F7FCF1BA4E29300B0F227 /* pcre2 */, D008D0C41BC58F8800841177 /* generate-version-header */, + 9C7A55301DCD71330049C25D /* fish_key_reader */, ); }; /* End PBXProject section */ @@ -1235,6 +1355,67 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 9C7A55351DCD71330049C25D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9C7A557E1DCD71CD0049C25D /* print_help.cpp in Sources */, + 9C7A557D1DCD71890049C25D /* fish_key_reader.cpp in Sources */, + 9C7A55361DCD71330049C25D /* autoload.cpp in Sources */, + 9C7A55371DCD71330049C25D /* builtin_commandline.cpp in Sources */, + 9C7A55381DCD71330049C25D /* builtin_complete.cpp in Sources */, + 9C7A55391DCD71330049C25D /* builtin_jobs.cpp in Sources */, + 9C7A553A1DCD71330049C25D /* builtin_set.cpp in Sources */, + 9C7A553B1DCD71330049C25D /* builtin_set_color.cpp in Sources */, + 9C7A553C1DCD71330049C25D /* builtin_ulimit.cpp in Sources */, + 9C7A553D1DCD71330049C25D /* builtin_test.cpp in Sources */, + 9C7A553E1DCD71330049C25D /* builtin_printf.cpp in Sources */, + 9C7A553F1DCD71330049C25D /* builtin_string.cpp in Sources */, + 9C7A55401DCD71330049C25D /* color.cpp in Sources */, + 9C7A55411DCD71330049C25D /* common.cpp in Sources */, + 9C7A55421DCD71330049C25D /* event.cpp in Sources */, + 9C7A55431DCD71330049C25D /* input_common.cpp in Sources */, + 9C7A55441DCD71330049C25D /* io.cpp in Sources */, + 9C7A55451DCD71330049C25D /* iothread.cpp in Sources */, + 9C7A55461DCD71330049C25D /* parse_util.cpp in Sources */, + 9C7A55471DCD71330049C25D /* path.cpp in Sources */, + 9C7A55481DCD71330049C25D /* parse_execution.cpp in Sources */, + 9C7A55491DCD71330049C25D /* postfork.cpp in Sources */, + 9C7A554A1DCD71330049C25D /* screen.cpp in Sources */, + 9C7A554B1DCD71330049C25D /* signal.cpp in Sources */, + 9C7A554C1DCD71330049C25D /* utf8.cpp in Sources */, + 9C7A554D1DCD71330049C25D /* builtin.cpp in Sources */, + 9C7A554E1DCD71330049C25D /* function.cpp in Sources */, + 9C7A554F1DCD71330049C25D /* complete.cpp in Sources */, + 9C7A55501DCD71330049C25D /* env.cpp in Sources */, + 9C7A55511DCD71330049C25D /* exec.cpp in Sources */, + 9C7A55521DCD71330049C25D /* wcstringutil.cpp in Sources */, + 9C7A55531DCD71330049C25D /* expand.cpp in Sources */, + 9C7A55541DCD71330049C25D /* fallback.cpp in Sources */, + 9C7A55551DCD71330049C25D /* fish_version.cpp in Sources */, + 9C7A55561DCD71330049C25D /* highlight.cpp in Sources */, + 9C7A55571DCD71330049C25D /* history.cpp in Sources */, + 9C7A55581DCD71330049C25D /* kill.cpp in Sources */, + 9C7A55591DCD71330049C25D /* parser.cpp in Sources */, + 9C7A555A1DCD71330049C25D /* parser_keywords.cpp in Sources */, + 9C7A555B1DCD71330049C25D /* proc.cpp in Sources */, + 9C7A555C1DCD71330049C25D /* reader.cpp in Sources */, + 9C7A555D1DCD71330049C25D /* sanity.cpp in Sources */, + 9C7A555E1DCD71330049C25D /* tokenizer.cpp in Sources */, + 9C7A555F1DCD71330049C25D /* wildcard.cpp in Sources */, + 9C7A55601DCD71330049C25D /* wgetopt.cpp in Sources */, + 9C7A55611DCD71330049C25D /* wutil.cpp in Sources */, + 9C7A55621DCD71330049C25D /* input.cpp in Sources */, + 9C7A55631DCD71330049C25D /* output.cpp in Sources */, + 9C7A55641DCD71330049C25D /* intern.cpp in Sources */, + 9C7A55651DCD71330049C25D /* env_universal_common.cpp in Sources */, + 9C7A55661DCD71330049C25D /* pager.cpp in Sources */, + 9C7A55681DCD71330049C25D /* parse_tree.cpp in Sources */, + 9C7A55691DCD71330049C25D /* parse_productions.cpp in Sources */, + 9C7A556A1DCD71330049C25D /* util.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D00769111990137800CA4627 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1458,6 +1639,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 9C7A55311DCD71330049C25D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D008D0C41BC58F8800841177 /* generate-version-header */; + targetProxy = 9C7A55321DCD71330049C25D /* PBXContainerItemProxy */; + }; + 9C7A55331DCD71330049C25D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D04F7FCF1BA4E29300B0F227 /* pcre2 */; + targetProxy = 9C7A55341DCD71330049C25D /* PBXContainerItemProxy */; + }; D008D0CB1BC58FDD00841177 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D008D0C41BC58F8800841177 /* generate-version-header */; @@ -1521,6 +1712,39 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 9C7A556F1DCD71330049C25D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 9C7A55701DCD71330049C25D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 9C7A55711DCD71330049C25D /* Release_C++11 */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = "Release_C++11"; + }; D007693F1990137800CA4627 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2014,6 +2238,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 9C7A556E1DCD71330049C25D /* Build configuration list for PBXNativeTarget "fish_key_reader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9C7A556F1DCD71330049C25D /* Debug */, + 9C7A55701DCD71330049C25D /* Release */, + 9C7A55711DCD71330049C25D /* Release_C++11 */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; D007693E1990137800CA4627 /* Build configuration list for PBXNativeTarget "fish_tests" */ = { isa = XCConfigurationList; buildConfigurations = ( From 4ba1f9e398ce37fbb71f595a8624f8849de136a0 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 18:56:57 -0700 Subject: [PATCH 089/112] Include fkk with fish.app --- fish.xcodeproj/project.pbxproj | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 48f5f0156..1ba1e2c12 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ D01A2C9B16964C8200767098 /* Copy Files */, ); dependencies = ( + 9C7A55801DCD73930049C25D /* PBXTargetDependency */, D0F01A1315AA36280034B3B1 /* PBXTargetDependency */, D0F01A1715AA36300034B3B1 /* PBXTargetDependency */, D0A564EF168D09C000AF6161 /* PBXTargetDependency */, @@ -132,6 +133,7 @@ 9C7A556D1DCD71330049C25D /* libpcre2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D04F7FD01BA4E29300B0F227 /* libpcre2.a */; }; 9C7A557D1DCD71890049C25D /* fish_key_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A557C1DCD717C0049C25D /* fish_key_reader.cpp */; }; 9C7A557E1DCD71CD0049C25D /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; }; + 9C7A55811DCD739C0049C25D /* fish_key_reader in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9C7A55721DCD71330049C25D /* fish_key_reader */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D00769121990137800CA4627 /* autoload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C6FCC914CFA4B0004CE8AD /* autoload.cpp */; }; D00769131990137800CA4627 /* builtin_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0F3373A1506DE3C00ECEFC0 /* builtin_test.cpp */; }; D00769141990137800CA4627 /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B6B0FE14E88BA400AD6C10 /* color.cpp */; }; @@ -365,6 +367,13 @@ remoteGlobalIDString = D04F7FCF1BA4E29300B0F227; remoteInfo = libpcre2.a; }; + 9C7A557F1DCD73930049C25D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D0A084F213B3AC130099B651 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9C7A55301DCD71330049C25D; + remoteInfo = fish_key_reader; + }; D008D0CA1BC58FDD00841177 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D0A084F213B3AC130099B651 /* Project object */; @@ -517,6 +526,7 @@ dstPath = base/bin; dstSubfolderSpec = 1; files = ( + 9C7A55811DCD739C0049C25D /* fish_key_reader in CopyFiles */, D0F019F115A977140034B3B1 /* fish in CopyFiles */, D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */, ); @@ -1649,6 +1659,11 @@ target = D04F7FCF1BA4E29300B0F227 /* pcre2 */; targetProxy = 9C7A55341DCD71330049C25D /* PBXContainerItemProxy */; }; + 9C7A55801DCD73930049C25D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9C7A55301DCD71330049C25D /* fish_key_reader */; + targetProxy = 9C7A557F1DCD73930049C25D /* PBXContainerItemProxy */; + }; D008D0CB1BC58FDD00841177 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D008D0C41BC58F8800841177 /* generate-version-header */; From c02f5ceb0fed2e0ce7676a4460e2220961cc6661 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 19:05:10 -0700 Subject: [PATCH 090/112] Add a fish_key_reader wrapper This will be necessary for fkk to work when one is using the .app bundle and has not installed fish otherwise. I just copied fish_indent.fish. --- share/functions/fish_indent.fish | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/functions/fish_indent.fish b/share/functions/fish_indent.fish index a97e1c2e8..5a955e13f 100644 --- a/share/functions/fish_indent.fish +++ b/share/functions/fish_indent.fish @@ -1,7 +1,7 @@ -# check if command fish_indent works and is the same version that +# check if command fish_key_reader works and is the same version that # came with this fish. This will happen one time. -command -s fish_indent > /dev/null -and command fish_indent --version 2>&1 | string match -rq $FISH_VERSION +command -s fish_key_reader > /dev/null +and command fish_key_reader --version 2>&1 | string match -rq $FISH_VERSION # if alias doesn't define the function here, this is an autoloaded "nothing". # the command (if there is one) will be used by default. -or alias fish_indent=(string escape $__fish_bin_dir/fish_indent) +or alias fish_key_reader=(string escape $__fish_bin_dir/fish_key_reader) From 95385eda80ec2fbabd05ee0f01fac42a70cf6dad Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 19:07:37 -0700 Subject: [PATCH 091/112] Create a fish_key_reader wrapper ala fish_indent Needed for fish_key_reader to work in a .app bundle without fish previously installed. I just copied fish_indent.fish and s/indent/key_reader --- share/functions/fish_key_reader.fish | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 share/functions/fish_key_reader.fish diff --git a/share/functions/fish_key_reader.fish b/share/functions/fish_key_reader.fish new file mode 100644 index 000000000..5a955e13f --- /dev/null +++ b/share/functions/fish_key_reader.fish @@ -0,0 +1,7 @@ +# check if command fish_key_reader works and is the same version that +# came with this fish. This will happen one time. +command -s fish_key_reader > /dev/null +and command fish_key_reader --version 2>&1 | string match -rq $FISH_VERSION +# if alias doesn't define the function here, this is an autoloaded "nothing". +# the command (if there is one) will be used by default. +or alias fish_key_reader=(string escape $__fish_bin_dir/fish_key_reader) From 87bfd1a01e622c9b7b00f309b177998412c91860 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 4 Nov 2016 19:08:48 -0700 Subject: [PATCH 092/112] Revert "Add a fish_key_reader wrapper" This reverts commit c02f5ceb0fed2e0ce7676a4460e2220961cc6661. --- share/functions/fish_indent.fish | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/functions/fish_indent.fish b/share/functions/fish_indent.fish index 5a955e13f..a97e1c2e8 100644 --- a/share/functions/fish_indent.fish +++ b/share/functions/fish_indent.fish @@ -1,7 +1,7 @@ -# check if command fish_key_reader works and is the same version that +# check if command fish_indent works and is the same version that # came with this fish. This will happen one time. -command -s fish_key_reader > /dev/null -and command fish_key_reader --version 2>&1 | string match -rq $FISH_VERSION +command -s fish_indent > /dev/null +and command fish_indent --version 2>&1 | string match -rq $FISH_VERSION # if alias doesn't define the function here, this is an autoloaded "nothing". # the command (if there is one) will be used by default. -or alias fish_key_reader=(string escape $__fish_bin_dir/fish_key_reader) +or alias fish_indent=(string escape $__fish_bin_dir/fish_indent) From 98863541c3130192c10031559a3989ec21a1e530 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 3 Nov 2016 19:42:25 -0700 Subject: [PATCH 093/112] lint: prefer early exits and continue Fix a location I missed in my earlier cleanup regarding early exits. --- src/proc.cpp | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/proc.cpp b/src/proc.cpp index d2ef46757..42850f6b7 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -318,26 +318,29 @@ static void handle_child_status(pid_t pid, int status) { } } - if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGQUIT)) { - if (!is_interactive_session) { - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - act.sa_handler = SIG_DFL; - sigaction(SIGINT, &act, 0); - sigaction(SIGQUIT, &act, 0); - kill(getpid(), WTERMSIG(status)); - } else { - // In an interactive session, tell the principal parser to skip all blocks we're - // executing so control-C returns control to the user. - if (p && found_proc) { - parser_t::skip_all_blocks(); - } - } + // If the child process was not killed by a signal or other than SIGINT or SIGQUIT we're done. + if (!WIFSIGNALED(status) || (WTERMSIG(status) != SIGINT && WTERMSIG(status) != SIGQUIT)) { + return; + } + + if (is_interactive_session) { + // In an interactive session, tell the principal parser to skip all blocks we're executing + // so control-C returns control to the user. + if (p && found_proc) parser_t::skip_all_blocks(); + } else { + // Deliver the SIGINT or SIGQUIT signal to ourself since we're not interactive. + struct sigaction act; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = SIG_DFL; + sigaction(SIGINT, &act, 0); + sigaction(SIGQUIT, &act, 0); + kill(getpid(), WTERMSIG(status)); } #if 0 - // TODO: decide whether to eliminate this block or have it emit a warning message. + // TODO: Decide whether to eliminate this block or have it emit a warning message. + // WARNING: See the special short-circuit logic above vis-a-vis signals. if (!found_proc) { // A child we lost track of? There have been bugs in both subshell handling and in builtin // handling that have caused this previously... From 1fb8f4e277cf6430a1128095e650526a912daf79 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 4 Nov 2016 18:40:22 -0700 Subject: [PATCH 094/112] lint: misc cleanups Earlier lint cleanups overlooked a couple of modules because on macOS at the moment oclint ignores them. I noticed this when I ran `make lint-all` on Ubuntu. --- osx/osx_fish_launcher.m | 19 +++--- src/builtin.cpp | 6 +- src/env.cpp | 5 +- src/fallback.cpp | 9 +-- src/fish_key_reader.cpp | 19 +++--- src/fish_tests.cpp | 134 +++++++++++++++++++++------------------- src/highlight.cpp | 13 +++- src/output.cpp | 3 +- src/parse_tree.cpp | 3 +- 9 files changed, 116 insertions(+), 95 deletions(-) diff --git a/osx/osx_fish_launcher.m b/osx/osx_fish_launcher.m index 20b6e61b0..875ae75f7 100644 --- a/osx/osx_fish_launcher.m +++ b/osx/osx_fish_launcher.m @@ -18,11 +18,11 @@ static void die(const char *format, ...) { vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); - + if (s_command_path[0] != '\0') { unlink(s_command_path); } - + exit(EXIT_FAILURE); } @@ -31,14 +31,14 @@ static void launch_fish_with_applescript(NSString *fish_binary_path) // load the script from a resource by fetching its URL from within our bundle NSString *path = [[NSBundle mainBundle] pathForResource:@"launch_fish" ofType:@"scpt"]; if (! path) die("Couldn't get path to launch_fish.scpt"); - + NSURL *url = [NSURL fileURLWithPath:path isDirectory:NO]; if (! url) die("Couldn't get URL to launch_fish.scpt"); - + NSDictionary *errors = nil; NSAppleScript *appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors]; if (! appleScript) die("Couldn't load AppleScript"); - + // create the first parameter NSAppleEventDescriptor *firstParameter = [NSAppleEventDescriptor descriptorWithString:fish_binary_path]; @@ -84,16 +84,17 @@ static void launch_fish_with_applescript(NSString *fish_binary_path) /* This approach asks Terminal to open a script that we control */ int main(void) { - + @autoreleasepool { /* Get the fish executable. Make sure it's absolute. */ - NSURL *fish_executable = [[NSBundle mainBundle] URLForResource:@"fish" withExtension:@"" subdirectory:@"base/bin"]; + NSURL *fish_executable = [[NSBundle mainBundle] URLForResource:@"fish" withExtension:@"" + subdirectory:@"base/bin"]; if (! fish_executable) die("Could not find fish executable in bundle"); - + launch_fish_with_applescript([fish_executable path]); } - + /* If we succeeded, it will clean itself up */ return 0; } diff --git a/src/builtin.cpp b/src/builtin.cpp index caca9928d..b7d12352c 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -3132,7 +3132,8 @@ int builtin_parse(parser_t &parser, io_streams_t &streams, wchar_t **argv) const wcstring src = str2wcstring(&txt.at(0), txt.size()); parse_node_tree_t parse_tree; parse_error_list_t errors; - bool success = parse_tree_from_string(src, parse_flag_include_comments, &parse_tree, &errors); + bool success = parse_tree_from_string(src, parse_flag_include_comments, &parse_tree, + &errors); if (! success) { streams.out.append(L"Parsing failed:\n"); @@ -3145,7 +3146,8 @@ int builtin_parse(parser_t &parser, io_streams_t &streams, wchar_t **argv) streams.out.append(L"(Reparsed with continue after error)\n"); parse_tree.clear(); errors.clear(); - parse_tree_from_string(src, parse_flag_continue_after_error | parse_flag_include_comments, &parse_tree, &errors); + parse_tree_from_string(src, parse_flag_continue_after_error | + parse_flag_include_comments, &parse_tree, &errors); } const wcstring dump = parse_dump_tree(parse_tree, src); streams.out.append(dump); diff --git a/src/env.cpp b/src/env.cpp index 5a9770f92..0fcee01c5 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -581,11 +581,10 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) node = top; } else if (preexisting_node != NULL) { node = preexisting_node; - if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) { // use existing entry's exportv - var_mode = - preexisting_entry_exportv ? ENV_EXPORT : 0; //!OCLINT(parameter reassignment) + var_mode = //!OCLINT(parameter reassignment) + preexisting_entry_exportv ? ENV_EXPORT : 0; } } else { if (!get_proc_had_barrier()) { diff --git a/src/fallback.cpp b/src/fallback.cpp index a9e9140f3..255d8d95f 100644 --- a/src/fallback.cpp +++ b/src/fallback.cpp @@ -203,13 +203,10 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) { // Not enough room in dst, add NUL and traverse rest of src. if (n == 0) { - if (siz != 0) *d = '\0'; - // NUL-terminate dst. - while (*s++) - ; + if (siz != 0) *d = '\0'; // NUL-terminate dst + while (*s++) ; // ignore rest of src } - return s - src - 1; - // Count does not include NUL. + return s - src - 1; // count does not include NUL } #endif diff --git a/src/fish_key_reader.cpp b/src/fish_key_reader.cpp index c2deb5076..281396638 100644 --- a/src/fish_key_reader.cpp +++ b/src/fish_key_reader.cpp @@ -206,9 +206,8 @@ static void process_input(bool continuous_mode) { output_bind_command(bind_chars); if (first_char_seen && !continuous_mode) { return; - } else { - continue; } + continue; } prev_tstamp = output_elapsed_time(prev_tstamp, first_char_seen); @@ -307,11 +306,13 @@ int main(int argc, char **argv) { {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}}; int opt; - while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { + bool error = false; + while (!error && (opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch (opt) { case 0: { fprintf(stderr, "getopt_long() unexpectedly returned zero\n"); - exit(1); + error = true; + break; } case 'c': { continuous_mode = true; @@ -320,6 +321,7 @@ int main(int argc, char **argv) { case 'h': { print_help("fish_key_reader", 0); exit(0); + break; } case 'd': { char *end; @@ -332,7 +334,7 @@ int main(int argc, char **argv) { debug_level = (int)tmp; } else { fwprintf(stderr, _(L"Invalid value '%s' for debug-level flag"), optarg); - exit(1); + error = true; } break; } @@ -347,16 +349,19 @@ int main(int argc, char **argv) { debug_stack_frames = (int)tmp; } else { fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg); - exit(1); + error = true; + break; } break; } default: { // We assume getopt_long() has already emitted a diagnostic msg. - exit(1); + error = true; + break; } } } + if (error) return 1; argc -= optind; if (argc != 0) { diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 99a0741ae..f08eeecbf 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -154,19 +154,22 @@ static int chdir_set_pwd(const char *path) { return ret; } +// The odd formulation of these macros is to avoid "multiple unary operator" warnings from oclint +// were we to use the more natural "if (!(e)) err(..." form. We have to do this because the rules +// for the C preprocessor make it practically impossible to embed a comment in the body of a macro. #define do_test(e) \ do { \ - if (!(e)) err(L"Test failed on line %lu: %s", __LINE__, #e); \ + if (e) { ; } else { err(L"Test failed on line %lu: %s", __LINE__, #e); } \ } while (0) -#define do_test_from(e, from_line) \ +#define do_test_from(e, from) \ do { \ - if (!(e)) err(L"Test failed on line %lu (from %lu): %s", __LINE__, from_line, #e); \ + if (e) { ; } else { err(L"Test failed on line %lu (from %lu): %s", __LINE__, from, #e); } \ } while (0) #define do_test1(e, msg) \ do { \ - if (!(e)) err(L"Test failed on line %lu: %ls", __LINE__, (msg)); \ + if (e) { ; } else { err(L"Test failed on line %lu: %ls", __LINE__, (msg)); } \ } while (0) /// Test sane escapes. @@ -199,7 +202,7 @@ static void test_unescape_sane() { err(L"Should not have been able to unescape \\U110000\n"); } if (is_wchar_ucs2()) { - // TODO: Make this work on MS Windows. + ; // TODO: Make this work on MS Windows. } else { if (!unescape_string(L"echo \\U10FFFF", &output, UNESCAPE_DEFAULT)) { err(L"Should have been able to unescape \\U10FFFF\n"); @@ -484,7 +487,7 @@ static parser_test_error_bits_t detect_argument_errors(const wcstring &src) { return PARSER_TEST_ERROR; } - assert(!tree.empty()); + assert(!tree.empty()); //!OCLINT(multiple unary operator) const parse_node_t *first_arg = tree.next_node_in_node_list(tree.at(0), symbol_argument, NULL); assert(first_arg != NULL); return parse_util_detect_errors_in_argument(*first_arg, first_arg->get_source(src)); @@ -493,7 +496,6 @@ static parser_test_error_bits_t detect_argument_errors(const wcstring &src) { /// Test the parser. static void test_parser() { say(L"Testing parser"); - parser_t parser; say(L"Testing block nesting"); if (!parse_util_detect_errors(L"if; end")) { @@ -627,7 +629,8 @@ static void test_parser() { #if 0 // This is disabled since it produces a long backtrace. We should find a way to either visually // compress the backtrace, or disable error spewing. - parser_t::principal_parser().eval(L"function recursive1 ; recursive2 ; end ; function recursive2 ; recursive1 ; end ; recursive1; ", io_chain_t(), TOP); + parser_t::principal_parser().eval(L"function recursive1 ; recursive2 ; end ; " + L"function recursive2 ; recursive1 ; end ; recursive1; ", io_chain_t(), TOP); #endif say(L"Testing empty function name"); @@ -840,8 +843,8 @@ static void test_utf82wchar(const char *src, size_t slen, const wchar_t *dst, si const unsigned char astral_mask = 0xF0; for (size_t i = 0; i < slen; i++) { if ((src[i] & astral_mask) == astral_mask) { - // Astral char. We expect this conversion to just fail. - res = 0; + // Astral char. We want this conversion to fail. + res = 0; //!OCLINT(parameter reassignment) break; } } @@ -888,8 +891,8 @@ static void test_wchar2utf8(const wchar_t *src, size_t slen, const char *dst, si const uint32_t astral_mask = 0xFFFF0000U; for (size_t i = 0; i < slen; i++) { if ((src[i] & astral_mask) != 0) { - /* astral char */ - res = 0; + // Astral char. We want this conversion to fail. + res = 0; //!OCLINT(parameter reassignment) break; } } @@ -1137,7 +1140,8 @@ static bool expand_test(const wchar_t *in, expand_flags_t flags, ...) { } if (!res) { - if ((arg = va_arg(va, wchar_t *)) != 0) { + arg = va_arg(va, wchar_t *); + if (arg) { wcstring msg = L"Expected ["; bool first = true; for (wcstring_list_t::const_iterator it = expected.begin(), end = expected.end(); @@ -2207,7 +2211,6 @@ static void test_history_matches(history_search_t &search, size_t matches, unsig size_t i; for (i = 0; i < matches; i++) { do_test(search.go_backwards()); - wcstring item = search.current_string(); } // do_test_from(!search.go_backwards(), from_line); bool result = search.go_backwards(); @@ -2403,7 +2406,7 @@ static void trigger_or_wait_for_notification(universal_notifier_t *notifier, universal_notifier_t::notifier_strategy_t strategy) { switch (strategy) { case universal_notifier_t::strategy_default: { - assert(0 && "strategy_default should be passed"); + DIE("strategy_default should be passed"); break; } case universal_notifier_t::strategy_shmem_polling: { @@ -3061,35 +3064,36 @@ static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *o out_joined_args->clear(); *out_deco = parse_statement_decoration_none; - bool result = false; parse_node_tree_t tree; - if (parse_tree_from_string(src, parse_flag_none, &tree, NULL)) { - // Get the statement. Should only have one. - const parse_node_tree_t::parse_node_list_t stmt_nodes = - tree.find_nodes(tree.at(0), symbol_plain_statement); - if (stmt_nodes.size() != 1) { - say(L"Unexpected number of statements (%lu) found in '%ls'", stmt_nodes.size(), - src.c_str()); - return false; - } - const parse_node_t &stmt = *stmt_nodes.at(0); - - // Return its decoration. - *out_deco = tree.decoration_for_plain_statement(stmt); - - // Return its command. - tree.command_for_plain_statement(stmt, src, out_cmd); - - // Return arguments separated by spaces. - const parse_node_tree_t::parse_node_list_t arg_nodes = - tree.find_nodes(stmt, symbol_argument); - for (size_t i = 0; i < arg_nodes.size(); i++) { - if (i > 0) out_joined_args->push_back(L' '); - out_joined_args->append(arg_nodes.at(i)->get_source(src)); - } - result = true; + if (!parse_tree_from_string(src, parse_flag_none, &tree, NULL)) { + return false; } - return result; + + // Get the statement. Should only have one. + const parse_node_tree_t::parse_node_list_t stmt_nodes = + tree.find_nodes(tree.at(0), symbol_plain_statement); + if (stmt_nodes.size() != 1) { + say(L"Unexpected number of statements (%lu) found in '%ls'", stmt_nodes.size(), + src.c_str()); + return false; + } + const parse_node_t &stmt = *stmt_nodes.at(0); + + // Return its decoration. + *out_deco = tree.decoration_for_plain_statement(stmt); + + // Return its command. + tree.command_for_plain_statement(stmt, src, out_cmd); + + // Return arguments separated by spaces. + const parse_node_tree_t::parse_node_list_t arg_nodes = + tree.find_nodes(stmt, symbol_argument); + for (size_t i = 0; i < arg_nodes.size(); i++) { + if (i > 0) out_joined_args->push_back(L' '); + out_joined_args->append(arg_nodes.at(i)->get_source(src)); + } + + return true; } // Test the LL2 (two token lookahead) nature of the parser by exercising the special builtin and @@ -3253,29 +3257,31 @@ static wcstring_list_t separate_by_format_specifiers(const wchar_t *format) { // Walk over the format specifier (if any). cursor = next_specifier; - if (*cursor == '%') { - cursor++; - // Flag - if (wcschr(L"#0- +'", *cursor)) cursor++; - // Minimum field width - while (iswdigit(*cursor)) cursor++; - // Precision - if (*cursor == L'.') { - cursor++; - while (iswdigit(*cursor)) cursor++; - } - // Length modifier - if (!wcsncmp(cursor, L"ll", 2) || !wcsncmp(cursor, L"hh", 2)) { - cursor += 2; - } else if (wcschr(L"hljtzqL", *cursor)) { - cursor++; - } - // The format specifier itself. We allow any character except NUL. - if (*cursor != L'\0') { - cursor += 1; - } - assert(cursor <= end); + if (*cursor != '%') { + continue; } + + cursor++; + // Flag + if (wcschr(L"#0- +'", *cursor)) cursor++; + // Minimum field width + while (iswdigit(*cursor)) cursor++; + // Precision + if (*cursor == L'.') { + cursor++; + while (iswdigit(*cursor)) cursor++; + } + // Length modifier + if (!wcsncmp(cursor, L"ll", 2) || !wcsncmp(cursor, L"hh", 2)) { + cursor += 2; + } else if (wcschr(L"hljtzqL", *cursor)) { + cursor++; + } + // The format specifier itself. We allow any character except NUL. + if (*cursor != L'\0') { + cursor += 1; + } + assert(cursor <= end); } return result; } diff --git a/src/highlight.cpp b/src/highlight.cpp index 6033de4d4..85844dc1c 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -52,11 +52,15 @@ static const wchar_t *const highlight_var[] = { }; -/// Determine if the filesystem containing the given fd is case insensitive. +/// Determine if the filesystem containing the given fd is case insensitive for lookups regardless +/// of whether it preserves the case when saving a pathname. +/// +/// Returns: +/// false: the filesystem is not case insensitive +/// true: the file system is case insensitive typedef std::map case_sensitivity_cache_t; bool fs_is_case_insensitive(const wcstring &path, int fd, case_sensitivity_cache_t &case_sensitivity_cache) { - // If _PC_CASE_SENSITIVE is not defined, assume case sensitive. bool result = false; #ifdef _PC_CASE_SENSITIVE // Try the cache first. @@ -71,6 +75,11 @@ bool fs_is_case_insensitive(const wcstring &path, int fd, result = (ret == 0); case_sensitivity_cache[path] = result; } +#else + // Silence lint tools about the unused parameters. + UNUSED(path); + UNUSED(fd); + UNUSED(case_sensitivity_cache); #endif return result; } diff --git a/src/output.cpp b/src/output.cpp index 039d32ce5..707a922aa 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -440,7 +440,8 @@ rgb_color_t parse_color(const wcstring &val, bool is_background) { #if 0 wcstring desc = result.description(); - printf("Parsed %ls from %ls (%s)\n", desc.c_str(), val.c_str(), is_background ? "background" : "foreground"); + printf("Parsed %ls from %ls (%s)\n", desc.c_str(), val.c_str(), + is_background ? "background" : "foreground"); #endif return result; diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index cb197ae26..3a0ceb168 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -1276,7 +1276,8 @@ bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t parse_flags, #if 0 //wcstring result = dump_tree(this->parser->nodes, str); //fprintf(stderr, "Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str()); - fprintf(stderr, "%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t), output->size() * sizeof(parse_node_t)); + fprintf(stderr, "%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t), + output->size() * sizeof(parse_node_t)); #endif // Indicate if we had a fatal error. From 7cca963b8f2ec34fe48aec6f0d169d70b464ed47 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 4 Nov 2016 19:15:55 -0700 Subject: [PATCH 095/112] lint all programs on macOS --- build_tools/lint.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/lint.fish b/build_tools/lint.fish index 5d9e4443d..a5323e2c0 100755 --- a/build_tools/lint.fish +++ b/build_tools/lint.fish @@ -105,7 +105,7 @@ if set -q c_files[1] # output will expect those messages to be written to stdout. if test "$kernel_name" = "Darwin" if not test -f compile_commands.json - xcodebuild >xcodebuild.log + xcodebuild -alltargets >xcodebuild.log oclint-xcodebuild xcodebuild.log >/dev/null end if test $all = yes From 6d1c1276872b80828015a49112cab64267fbf3c8 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 5 Nov 2016 12:20:14 -0700 Subject: [PATCH 096/112] Enable LTO for fish.app release builds. Shaves 2MB off app bundle size --- fish.xcodeproj/project.pbxproj | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 1ba1e2c12..f31cdf263 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -1734,6 +1734,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -1745,6 +1746,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -1756,6 +1758,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = "Release_C++11"; @@ -1768,6 +1771,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = NO; PRODUCT_NAME = fish_tests; }; name = Debug; @@ -1780,6 +1784,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = fish_tests; }; name = Release; @@ -1792,6 +1797,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = fish_tests; }; name = "Release_C++11"; @@ -1876,6 +1882,7 @@ GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; INFOPLIST_FILE = osx/Info.plist; + LLVM_LTO = YES_THIN; PRODUCT_BUNDLE_IDENTIFIER = "com.ridiculousfish.fish-shell"; PRODUCT_NAME = fish; WRAPPER_EXTENSION = app; @@ -1889,6 +1896,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = fish; }; name = "Release_C++11"; @@ -1901,6 +1909,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = "Release_C++11"; @@ -1951,6 +1960,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_UNUSED_VARIABLE = NO; + LLVM_LTO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; @@ -1976,6 +1986,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_UNUSED_VARIABLE = NO; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; @@ -2001,6 +2012,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_UNUSED_VARIABLE = NO; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; @@ -2157,6 +2169,7 @@ ); GCC_WARN_UNINITIALIZED_AUTOS = YES; INFOPLIST_FILE = osx/Info.plist; + LLVM_LTO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.ridiculousfish.fish-shell"; PRODUCT_NAME = fish; WRAPPER_EXTENSION = app; @@ -2174,6 +2187,7 @@ GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; INFOPLIST_FILE = osx/Info.plist; + LLVM_LTO = YES_THIN; PRODUCT_BUNDLE_IDENTIFIER = "com.ridiculousfish.fish-shell"; PRODUCT_NAME = fish; WRAPPER_EXTENSION = app; @@ -2192,6 +2206,7 @@ "$(inherited)", ); GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -2204,6 +2219,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -2215,6 +2231,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = NO; PRODUCT_NAME = fish; }; name = Debug; @@ -2226,6 +2243,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + LLVM_LTO = YES_THIN; PRODUCT_NAME = fish; }; name = Release; From adba0550d5316b94881223854be74d4e7da400e9 Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 5 Nov 2016 15:37:19 -0700 Subject: [PATCH 097/112] lint.fish: colorize cppcheck output --- build_tools/lint.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/lint.fish b/build_tools/lint.fish index a5323e2c0..dde1393fd 100755 --- a/build_tools/lint.fish +++ b/build_tools/lint.fish @@ -92,7 +92,7 @@ if set -q c_files[1] # The stderr to stdout redirection is because cppcheck, incorrectly IMHO, writes its # diagnostic messages to stderr. Anyone running this who wants to capture its output will # expect those messages to be written to stdout. - cppcheck -q --verbose --std=posix --language=c++ --template "[{file}:{line}]: {severity} ({id}): {message}" --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks --rule-file=.cppcheck.rule $cppcheck_args $c_files 2>&1 + cppcheck -q --verbose --std=posix --language=c++ --template \[(set_color --bold)(set_color --underline)"{file}"(set_color normal)(set_color --bold)"{line}"(set_color normal)"]:"(set_color brmagenta)" {severity}"(set_color magenta)" ({id}):"\n(set_color normal)" {message}" --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks --rule-file=.cppcheck.rule $cppcheck_args $c_files 2>&1 end if type -q oclint From 839cd2a1c7a24e74ee4086a18703299de962399c Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sat, 5 Nov 2016 15:38:49 -0700 Subject: [PATCH 098/112] lint.fish: fix line number display --- build_tools/lint.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/lint.fish b/build_tools/lint.fish index dde1393fd..7fb72e790 100755 --- a/build_tools/lint.fish +++ b/build_tools/lint.fish @@ -92,7 +92,7 @@ if set -q c_files[1] # The stderr to stdout redirection is because cppcheck, incorrectly IMHO, writes its # diagnostic messages to stderr. Anyone running this who wants to capture its output will # expect those messages to be written to stdout. - cppcheck -q --verbose --std=posix --language=c++ --template \[(set_color --bold)(set_color --underline)"{file}"(set_color normal)(set_color --bold)"{line}"(set_color normal)"]:"(set_color brmagenta)" {severity}"(set_color magenta)" ({id}):"\n(set_color normal)" {message}" --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks --rule-file=.cppcheck.rule $cppcheck_args $c_files 2>&1 + cppcheck -q --verbose --std=posix --language=c++ --template \[(set_color --bold)(set_color --underline)"{file}"(set_color normal)(set_color --bold)":{line}"(set_color normal)"] "(set_color brmagenta)"{severity}"(set_color magenta)" ({id}):"\n(set_color normal)" {message}" --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks --rule-file=.cppcheck.rule $cppcheck_args $c_files 2>&1 end if type -q oclint From 034aaaa62bfff85b0f5843cbd2e09a122c7dd7dd Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Sun, 6 Nov 2016 04:29:47 -0800 Subject: [PATCH 099/112] cppcheck: incorrect printf specifiers --- src/fish_indent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp index 7f8df7cab..8605e4ead 100644 --- a/src/fish_indent.cpp +++ b/src/fish_indent.cpp @@ -102,7 +102,7 @@ static void dump_node(indent_t node_indent, const parse_node_t &node, const wcst nextc_str[1] = L'c'; nextc_str[2] = nextc + '@'; } - fwprintf(stderr, L"{off %4d, len %4d, indent %2u, kw %ls, %ls} [%ls|%ls|%ls]\n", + fwprintf(stderr, L"{off %4u, len %4u, indent %2u, kw %ls, %ls} [%ls|%ls|%ls]\n", node.source_start, node.source_length, node_indent, keyword_description(node.keyword), token_type_description(node.type), prevc_str, source_txt.c_str(), nextc_str); } From 0c4ede56272ada6d3ec67406e3f9aca91c5abd0f Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 19:23:38 +0100 Subject: [PATCH 100/112] add nvram completion --- share/completions/nvram.fish | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 share/completions/nvram.fish diff --git a/share/completions/nvram.fish b/share/completions/nvram.fish new file mode 100644 index 000000000..1b5e501b5 --- /dev/null +++ b/share/completions/nvram.fish @@ -0,0 +1,12 @@ +# completion for nvram (macOS) + +function __fish_nvram_variables + command nvram -p +end + +complete -c nvram -s x -f -d 'Use XML format for reading and writing variables' +complete -c nvram -s p -f -d 'Print all of the firmware variables' +complete -c nvram -s f -r -d 'Set firmware variables from a text file' +complete -c nvram -s d -x -a '(__fish_nvram_variables)' -d 'Deletes the named firmware variable' +complete -c nvram -s c -f -d 'Delete all of the firmware variable' +complete -c nvram -x -a '(__fish_nvram_variables)' From 313cb0d2488be6191ae1ee2a67ef717f9e6facc1 Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 19:24:08 +0100 Subject: [PATCH 101/112] add mdutil completion --- share/completions/mdutil.fish | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 share/completions/mdutil.fish diff --git a/share/completions/mdutil.fish b/share/completions/mdutil.fish new file mode 100644 index 000000000..ec3e626be --- /dev/null +++ b/share/completions/mdutil.fish @@ -0,0 +1,24 @@ +# completion for mdutil (macOS) + +function __fish_mdutil_volumes + command mdutil -a -s | while read -l line + if string match -q \t"*" -- $line + printf "%s\n" $line + else + # Use printf to not output a newline so indented lines are joined + # to non-indented ones + printf "%s" (string replace -r ':$' '' -- $line) + end + end +end + +complete -c mdutil -s p -f -d 'Publish metadata' +complete -c mdutil -s i -f -a 'on off' -d 'Turn indexing on or off' +complete -c mdutil -s d -f -d 'Disable Spotlight activity for volume' +complete -c mdutil -s E -f -d 'Erase and rebuild index' +complete -c mdutil -s s -f -d 'Print indexing status' +complete -c mdutil -s t -x -a '(__fish_mdutil_volumes)' -d 'Resolve files from file id with an optional volume path or device id' +complete -c mdutil -s a -f -d 'Apply command to all volumes' +complete -c mdutil -s V -x -a '(__fish_mdutil_volumes)' -d 'Apply command to all stores on the specified volume' +complete -c mdutil -s v -f -d 'Display verbose information' +complete -c mdutil -x -a '(__fish_mdutil_volumes)' From 71e835feecb35dea5c6d33706136481bc204691a Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 19:24:19 +0100 Subject: [PATCH 102/112] add mdls completion --- share/completions/mdls.fish | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 share/completions/mdls.fish diff --git a/share/completions/mdls.fish b/share/completions/mdls.fish new file mode 100644 index 000000000..4aaf59c7e --- /dev/null +++ b/share/completions/mdls.fish @@ -0,0 +1,6 @@ +# completion for mdls (macOS) + +complete -c mdls -s n -o name -x -d 'Print only the matching metadata attribute value' +complete -c mdls -s r -o raw -f -d 'Print raw attribute data' +complete -c mdls -n '__fish_seen_subcommand_from -raw -r' -o nullMarker -x -d 'Sets a marker string to be used when a requested attribute is null' +complete -c mdls -s p -o plist -r -d 'Output attributes in XML format to file' From b41fced0627bb24c65ad9a69e04ebf42ef16c968 Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 19:24:30 +0100 Subject: [PATCH 103/112] add mdfind completion --- share/completions/mdfind.fish | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 share/completions/mdfind.fish diff --git a/share/completions/mdfind.fish b/share/completions/mdfind.fish new file mode 100644 index 000000000..b5598621f --- /dev/null +++ b/share/completions/mdfind.fish @@ -0,0 +1,12 @@ +# completion for mdfind (macOS) + +complete -c mdfind -o attr -x -d 'Fetches the value of the specified attribute' +complete -c mdfind -o count -f -d 'Query only reports matching items count' +complete -c mdfind -o onlyin -x -a '(__fish_complete_directories (commandline -ct))' -d 'Search only within given directory' +complete -c mdfind -o live -f -d 'Query should stay active' +complete -c mdfind -o name -x -d 'Search on file name only' +complete -c mdfind -o reprint -f -d 'Reprint results on live update' +complete -c mdfind -s s -x -d 'Show contents of smart folder' +complete -c mdfind -s 0 -f -d 'Use NUL (\0) as a path separator, for use with xargs -0' +complete -c mdfind -o literal -f -d 'Force the provided query string to be taken as a literal' +complete -c mdfind -o interpret -f -d 'Interprete query string as Spotlight query' From 87c51f2c1074952d5ef893eb9cc996c9aaee72db Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 19:24:43 +0100 Subject: [PATCH 104/112] add tmutil completion --- share/completions/tmutil.fish | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 share/completions/tmutil.fish diff --git a/share/completions/tmutil.fish b/share/completions/tmutil.fish new file mode 100644 index 000000000..5553567e3 --- /dev/null +++ b/share/completions/tmutil.fish @@ -0,0 +1,56 @@ +# completion for tmutil (macOS) + +complete -f -c tmutil -n '__fish_use_subcommand' -a addexclusion -d 'Add an exclusion not to back up a file' +complete -f -c tmutil -n '__fish_seen_subcommand_from addexclusion' -s v -d 'Volume exclusion' +complete -f -c tmutil -n '__fish_seen_subcommand_from addexclusion' -s p -d 'Path exclusion' +complete -r -c tmutil -n '__fish_use_subcommand' -a associatedisk -d 'Bind a snapshot volume directory to the specified local disk' +complete -r -c tmutil -n '__fish_use_subcommand' -a calculatedrift -d 'Determine the amount of change between snapshots' +complete -r -c tmutil -n '__fish_use_subcommand' -a compare -d 'Perform a backup diff' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s a -d 'Compare all supported metadata' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s n -d 'No metadata comparison' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s @ -d 'Compare extended attributes' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s c -d 'Compare creation times' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s d -d 'Compare file data forks' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s e -d 'Compare ACLs' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s f -d 'Compare file flags' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s g -d 'Compare GIDs' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s m -d 'Compare file modes' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s s -d 'Compare sizes' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s t -d 'Compare modification times' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s u -d 'Compare UIDs' +complete -r -c tmutil -n '__fish_seen_subcommand_from compare' -s D -d 'Limit traversal depth to depth levels from the beginning of iteration' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s E -d 'Dont take exclusions into account' +complete -r -c tmutil -n '__fish_seen_subcommand_from compare' -s I -d 'Ignore path' +complete -f -c tmutil -n '__fish_seen_subcommand_from compare' -s U -d 'Ignore logical volume identity' +complete -r -c tmutil -n '__fish_use_subcommand' -a delete -d 'Delete one or more snapshots' +complete -f -c tmutil -n '__fish_use_subcommand' -a destinationinfo -d 'Print information about destinations' +complete -f -c tmutil -n '__fish_use_subcommand' -a disable -d 'Turn off automatic backups' +complete -f -c tmutil -n '__fish_use_subcommand' -a disablelocal -d 'Turn off local Time Machine snapshots' +complete -f -c tmutil -n '__fish_use_subcommand' -a enable -d 'Turn on automatic backups' +complete -f -c tmutil -n '__fish_use_subcommand' -a enablelocal -d 'Turn on local Time Machine snapshots' +complete -r -c tmutil -n '__fish_use_subcommand' -a inheritbackup -d 'Claim a machine directory or sparsebundle for use by the current machine' +complete -f -c tmutil -n '__fish_use_subcommand' -a isexcluded -d 'Determine if a file, directory, or volume are excluded from backups' +complete -f -c tmutil -n '__fish_use_subcommand' -a latestbackup -d 'Print the path to the latest snapshot' +complete -f -c tmutil -n '__fish_use_subcommand' -a listbackups -d 'Print paths for all snapshots' +complete -f -c tmutil -n '__fish_use_subcommand' -a machinedirectory -d 'Print the path to the current machine directory' +complete -f -c tmutil -n '__fish_use_subcommand' -a removedestination -d 'Removes a backup destination' +complete -f -c tmutil -n '__fish_use_subcommand' -a removeexclusion -d 'Remove an exclusion' +complete -f -c tmutil -n '__fish_seen_subcommand_from removeexclusion' -s v -d 'Volume exclusion' +complete -f -c tmutil -n '__fish_seen_subcommand_from removeexclusion' -s p -d 'Path exclusion' +complete -f -c tmutil -n '__fish_use_subcommand' -a restore -d 'Restore an item' +complete -r -c tmutil -n '__fish_seen_subcommand_from restore' -s v +complete -r -c tmutil -n '__fish_use_subcommand' -a setdestination -d 'Set a backup destination' +complete -f -c tmutil -n '__fish_seen_subcommand_from setdestination' -s a -d 'Add to the list of destinations' +complete -f -c tmutil -n '__fish_seen_subcommand_from setdestination' -s p -d 'Enter the password at a non-echoing interactive prompt' +complete -f -c tmutil -n '__fish_use_subcommand' -a snapshot -d 'Create new local Time Machine snapshot' +complete -f -c tmutil -n '__fish_use_subcommand' -a startbackup -d 'Begin a backup if one is not already running' +complete -f -c tmutil -n '__fish_seen_subcommand_from startbackup' -s a -l auto -d 'Automatic mode' +complete -f -c tmutil -n '__fish_seen_subcommand_from startbackup' -s b -l block -d 'Block until finished' +complete -f -c tmutil -n '__fish_seen_subcommand_from startbackup' -s r -l rotation -d 'Autmatic rotation' +complete -r -c tmutil -n '__fish_seen_subcommand_from startbackup' -s d -l destination -d 'Backup destination' +complete -f -c tmutil -n '__fish_use_subcommand' -a stopbackup -d 'Cancel a backup currently in progress' +complete -r -c tmutil -n '__fish_use_subcommand' -a uniquesize -d 'Analyze the specified path and determine its unique size' +complete -r -c tmutil -n '__fish_use_subcommand' -a verifychecksums -d 'Verify snapshot' +complete -f -c tmutil -n '__fish_use_subcommand' -a version -d 'Print version' + +complete -f -c tmutil -n '__fish_seen_subcommand_from destinationinfo isexcluded compare' -s X -d 'Print as XML' From 848495d4cff9c869ad6e500efb0dadc4ee5462ec Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 21:22:54 +0100 Subject: [PATCH 105/112] add mddiagnose completion --- share/completions/mddiagnose.fish | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 share/completions/mddiagnose.fish diff --git a/share/completions/mddiagnose.fish b/share/completions/mddiagnose.fish new file mode 100644 index 000000000..3a93426a6 --- /dev/null +++ b/share/completions/mddiagnose.fish @@ -0,0 +1,12 @@ +# completion for mddiagnose (macOS) + +complete -c mddiagnose -s h -f -d 'Display help' +complete -c mddiagnose -s d -f -d 'Ignore unknown options' +complete -c mddiagnose -s n -f -d 'Do not reveal the resulting package in the Finder' +complete -c mddiagnose -s r -f -d 'Avoid restricted operations such as heap' +complete -c mddiagnose -s s -f -d 'Skip gathering system.log' +complete -c mddiagnose -s v -f -d 'Prints version of mddiagnose' +complete -c mddiagnose -s m -f -d 'Minimal report' +complete -c mddiagnose -s e -r -d 'Evalute indexing information for path' +complete -c mddiagnose -s p -r -d 'Evalute permissions information for path' +complete -c mddiagnose -s f -r -d 'Write the diagnostic to the specified path' From 180c211dd21ee6cf54521dd3d13122ba74e2c48b Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 21:23:09 +0100 Subject: [PATCH 106/112] add mdimport completion --- share/completions/mdimport.fish | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 share/completions/mdimport.fish diff --git a/share/completions/mdimport.fish b/share/completions/mdimport.fish new file mode 100644 index 000000000..816958b1a --- /dev/null +++ b/share/completions/mdimport.fish @@ -0,0 +1,13 @@ +# completion for mdimport (macOS) + +complete -c mdimport -s g -r -d 'Import files using the listed plugin' +complete -c mdimport -s V -f -d 'Print timing information for this run' +complete -c mdimport -s A -f -d 'Print out the list of all of the attributes and exit' +complete -c mdimport -s X -f -d 'Print out the schema file and exit' +complete -c mdimport -s r -f -d 'Ask the server to reimport files for UTIs claimed by the listed plugin' +complete -c mdimport -s p -f -d 'Print out performance information gathered during the run' +complete -c mdimport -s L -f -d 'Print the list of installed importers and exit' +complete -c mdimport -s d -x -a '1 2 3 4' -d 'Print debugging information' +complete -c mdimport -s n -f -d 'Dont send the imported attributes to the data store' +complete -c mdimport -s w -x -d 'Wait for the specified interval between scanning files' +complete -c mdimport -s o -r -d 'Write the imported attributes to a file' From 7a1146ebb5037e3b8dd623bf72480c9320b6881e Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Sat, 5 Nov 2016 22:39:58 +0100 Subject: [PATCH 107/112] add caffeinate completion, see #3525 --- share/completions/caffeinate.fish | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 share/completions/caffeinate.fish diff --git a/share/completions/caffeinate.fish b/share/completions/caffeinate.fish new file mode 100644 index 000000000..bfcc708af --- /dev/null +++ b/share/completions/caffeinate.fish @@ -0,0 +1,11 @@ +# completion for caffeinate (macOS) + +complete -c caffeinate -s d -f -d 'Create an assertion to prevent the display from sleeping' +complete -c caffeinate -s i -f -d 'Create an assertion to prevent the system from idle sleeping' +complete -c caffeinate -s m -f -d 'Create an assertion to prevent the disk from idle sleeping' +complete -c caffeinate -s s -f -d 'Create an assertion to prevent the system from sleeping (AC power)' +complete -c caffeinate -s u -f -d 'Create an assertion to declare that user is active' +complete -c caffeinate -s t -x -a '10 60 300 600 1800 3600' -d 'Specifies the timeout value in seconds' +complete -c caffeinate -s w -x -a '(__fish_complete_pids)' -d 'Waits for the process with the specified PID to exit' + +complete -c caffeinate -x -a '(__fish_complete_subcommand)' From 1155c4b413b5c539f3b4d6919a92f20e598b8d18 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 6 Nov 2016 17:48:26 -0800 Subject: [PATCH 108/112] silence false positive errors from some compilers Fixes #3529 --- src/builtin.cpp | 2 ++ src/tokenizer.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/builtin.cpp b/src/builtin.cpp index b7d12352c..430d3e608 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -2859,6 +2859,8 @@ static const wcstring hist_cmd_to_string(hist_cmd_t hist_cmd) { case HIST_SAVE: return L"save"; } + + DIE("should not reach this statement"); // silence some compiler errors about not returning } /// Remember the history subcommand and disallow selecting more than one history subcommand. diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index a8b2886b1..29d11639c 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -765,6 +765,8 @@ bool move_word_state_machine_t::consume_char(wchar_t c) { return consume_char_whitespace(c); } } + + DIE("should not reach this statement"); // silence some compiler errors about not returning } move_word_state_machine_t::move_word_state_machine_t(move_word_style_t syl) From 83c7931afb28f093115966794fed24df41a3ac62 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sun, 6 Nov 2016 20:27:48 -0800 Subject: [PATCH 109/112] treat TERM "tmux" the same as "screen" To the extent that fish special-cases TERM values relevant to the `screen` program it should do the same for the `tmux` program. Fixes #3512 --- src/reader.cpp | 10 +++------- src/screen.cpp | 4 ++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/reader.cpp b/src/reader.cpp index 00ffe9231..f3886668a 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -668,20 +668,16 @@ void reader_write_title(const wcstring &cmd, bool reset_cursor_position) { if (term_str.missing()) return; const wchar_t *term = term_str.c_str(); - bool recognized = false; - recognized = recognized || contains(term, L"xterm", L"screen", L"nxterm", L"rxvt"); + bool recognized = contains(term, L"xterm", L"screen", L"tmux", L"nxterm", L"rxvt"); recognized = recognized || !wcsncmp(term, L"xterm-", wcslen(L"xterm-")); recognized = recognized || !wcsncmp(term, L"screen-", wcslen(L"screen-")); + recognized = recognized || !wcsncmp(term, L"tmux-", wcslen(L"tmux-")); if (!recognized) { char *n = ttyname(STDIN_FILENO); - if (contains(term, L"linux")) { - return; - } - + if (contains(term, L"linux")) return; if (contains(term, L"dumb")) return; - if (strstr(n, "tty") || strstr(n, "/vc/")) return; } diff --git a/src/screen.cpp b/src/screen.cpp index 8095f1a8f..54a1203f3 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -109,10 +109,14 @@ static bool is_screen_name_escape_seq(const wchar_t *code, size_t *resulting_len return false; } +#if 0 + // TODO: Decide if this should be removed or modified to also test for TERM values that begin + // with "tmux". See issue #3512. const env_var_t term_name = env_get_string(L"TERM"); if (term_name.missing() || !string_prefixes_string(L"screen", term_name)) { return false; } +#endif const wchar_t *const screen_name_end_sentinel = L"\x1b\\"; const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel); From a2756185895efb6435f2bbc43da2cefbb752eba5 Mon Sep 17 00:00:00 2001 From: Colin Marquardt Date: Mon, 7 Nov 2016 17:36:03 +0100 Subject: [PATCH 110/112] Typofix: shoe -> show --- share/completions/svn.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/completions/svn.fish b/share/completions/svn.fish index fd24a13d5..56b9082a0 100644 --- a/share/completions/svn.fish +++ b/share/completions/svn.fish @@ -165,7 +165,7 @@ for cmd in $blame $diff $log $merge _svn_cmpl_ $cmd -l extensions -s x -d 'Ignore changes in amount of whitespace' -xa '-b --ignore-space-change' _svn_cmpl_ $cmd -l extensions -s x -d 'Ignore all whitespace' -xa '-w --ignore-all-space' _svn_cmpl_ $cmd -l extensions -s x -d 'Ignore eol style' -xa '-w --ignore-eol-style' - _svn_cmpl_ $cmd -l extensions -s x -d 'Show C function name' -xa '-p --shoe-c-function' + _svn_cmpl_ $cmd -l extensions -s x -d 'Show C function name' -xa '-p --show-c-function' # Next completion doesn't work, since fish doesn't respect -x key #_svn_cmpl_ $cmd -l extensions -n '__fish_seen_subcommand_from --diff-cmd' -xa '(__fish_complete_svn_diff)' From 9e922a6e0281d1d093563f2b3dbce8764f2e4900 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Fri, 4 Nov 2016 22:32:43 -0700 Subject: [PATCH 111/112] make `status` saner vis-a-vis arg parsing The `status` command currently silently allows incompatible flags (i.e., subcommands). Too, using flags to specify subcommands misleads the user into thinking they can specify multiple subcommands. We recently modified the `history` command to deprecate using flags for subcommands. This change does the same for the `status` command. Fixes #3509 --- doc_src/history.txt | 5 +- doc_src/status.txt | 43 ++-- share/completions/status.fish | 35 ++- src/builtin.cpp | 404 ++++++++++++++++++++++++---------- tests/status.err | 6 + tests/status.in | 32 ++- tests/status.out | 2 - 7 files changed, 373 insertions(+), 154 deletions(-) diff --git a/doc_src/history.txt b/doc_src/history.txt index 388ded19a..cc8d311a3 100644 --- a/doc_src/history.txt +++ b/doc_src/history.txt @@ -14,8 +14,6 @@ history ( -h | --help ) `history` is used to search, delete, and otherwise manipulate the history of interactive commands. -Note that for backwards compatibility each subcommand can also be specified as a long option. For example, rather than `history search` you can type `history --search`. Those long options are deprecated and will be removed in a future release. - The following operations (sub-commands) are available: - `search` returns history items matching the search string. If no search string is provided it returns all history items. This is the default operation if no other operation is specified. You only have to explicitly say `history search` if you wish to search for one of the subcommands. The `--contains` search option will be used if you don't specify a different search option. Entries are ordered newest to oldest. If stdout is attached to a tty the output will be piped through your pager by the history function. The history builtin simply writes the results to stdout. @@ -60,9 +58,10 @@ history --search --contains "foo" history --delete --prefix "foo" # Interactively deletes commands which start with "foo" from the history. # You can select more than one entry by entering their IDs seperated by a space. +\endfish \subsection history-notes Notes If you specify both `--prefix` and `--contains` the last flag seen is used. -\endfish +Note that for backwards compatibility each subcommand can also be specified as a long option. For example, rather than `history search` you can type `history --search`. Those long options are deprecated and will be removed in a future release. diff --git a/doc_src/status.txt b/doc_src/status.txt index b939f6fe9..b93502059 100644 --- a/doc_src/status.txt +++ b/doc_src/status.txt @@ -2,33 +2,50 @@ \subsection status-synopsis Synopsis \fish{synopsis} -status [OPTION] +status +status is-login +status is-interactive +status is-block +status is-command-substitution +status is-no-job-control +status is-full-job-control +status is-interactive-job-control +status current-filename +status current-line-number +status print-stack-trace +status job-control CONTROL-TYPE \endfish \subsection status-description Description With no arguments, `status` displays a summary of the current login and job control status of the shell. -The following options are available: +The following operations (sub-commands) are available: -- `-c` or `--is-command-substitution` returns 0 if fish is currently executing a command substitution. +- `is-command-sub` returns 0 if fish is currently executing a command substitution. Also `-c` or `--is-command-substitution`. -- `-b` or `--is-block` returns 0 if fish is currently executing a block of code. +- `is-block` returns 0 if fish is currently executing a block of code. Also `-b` or `--is-block`. -- `-i` or `--is-interactive` returns 0 if fish is interactive - that is, connected to a keyboard. +- `is-interactive` returns 0 if fish is interactive - that is, connected to a keyboard. Also `-i` or `--is-interactive`. -- `-l` or `--is-login` returns 0 if fish is a login shell - that is, if fish should perform login tasks such as setting up the PATH. +- `is-login` returns 0 if fish is a login shell - that is, if fish should perform login tasks such as setting up the PATH. Also `-l` or `--is-login`. -- `--is-full-job-control` returns 0 if full job control is enabled. +- `is-full-job-control` returns 0 if full job control is enabled. Also `--is-full-job-control` (no short flag). -- `--is-interactive-job-control` returns 0 if interactive job control is enabled. +- `is-interactive-job-control` returns 0 if interactive job control is enabled. Also, `--is-interactive-job-control` (no short flag). -- `--is-no-job-control` returns 0 if no job control is enabled. +- `is-no-job-control` returns 0 if no job control is enabled. Also `--is-no-job-control` (no short flag). -- `-f` or `--current-filename` prints the filename of the currently running script. +- `current-filename` prints the filename of the currently running script. Also `-f` or `--current-filename`. -- `-n` or `--current-line-number` prints the line number of the currently running script. +- `current-line-number` prints the line number of the currently running script. Also `-n` or `--current-line-number`. -- `-j CONTROLTYPE` or `--job-control=CONTROLTYPE` sets the job control type, which can be `none`, `full`, or `interactive`. +- `job-control CONTROL-TYPE` sets the job control type, which can be `none`, `full`, or `interactive`. Also `-j CONTROL-TYPE` or `--job-control=CONTROL-TYPE`. -- `-t` or `--print-stack-trace` prints a stack trace of all function calls on the call stack. +- `print-stack-trace` prints a stack trace of all function calls on the call stack. Also `-t` or `--print-stack-trace`. + +\subsection status-notes Notes + +For backwards compatibility each subcommand can also be specified as a long or short option. For example, rather than `status is-login` you can type `status --is-login`. The flag forms are deprecated and may be removed in a future release (but not before fish 3.0). + +You can only specify one subcommand per invocation even if you use the flag form of the subcommand. diff --git a/share/completions/status.fish b/share/completions/status.fish index 56dabc86f..0b85406b9 100644 --- a/share/completions/status.fish +++ b/share/completions/status.fish @@ -1,14 +1,25 @@ +# Note that when a completion file is sourced a new block scope is created so `set -l` works. +set -l __fish_status_all_commands is-login is-interactive is-block is-command-substitution is-no-job-control is-interactive-job-control is-full-job-control current-filename current-line-number print-stack-trace job-control +# These are the recognized flags. complete -c status -s h -l help --description "Display help and exit" -complete -c status -l is-command-substitution --description "Test if a command substitution is currently evaluated" -complete -c status -l is-block --description "Test if a code block is currently evaluated" -complete -c status -l is-interactive --description "Test if this is an interactive shell" -complete -c status -l is-login --description "Test if this is a login shell" -complete -c status -l is-full-job-control --description "Test if all new jobs are put under job control" -complete -c status -l is-interactive-job-control --description "Test if only interactive new jobs are put under job control" -complete -c status -l is-no-job-control --description "Test if new jobs are never put under job control" -complete -c status -s j -l job-control -xa "full interactive none" --description "Set which jobs are out under job control" -complete -c status -s t -l print-stack-trace --description "Print a list of all function calls leading up to running the current command" -complete -c status -s f -l current-filename --description "Print the filename of the currently running script" -complete -c status -s n -l current-line-number --description "Print the line number of the currently running script" -complete -c status -s t -l print-stack-trace --description "Prints a trace of all function calls on the stack" + +# The "is-something" subcommands. +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-login -d "Test if this is a login shell" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-interactive -d "Test if this is an interactive shell" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-command-substitution -d "Test if a command substitution is currently evaluated" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-block -d "Test if a code block is currently evaluated" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-no-job-control -d "Test if new jobs are never put under job control" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-interactive-job-control -d "Test if only interactive new jobs are put under job control" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-full-job-control -d "Test if all new jobs are put under job control" + +# The subcommands that are not "is-something" which don't change the fish state. +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a current-filename -d "Print the filename of the currently running script" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a current-line-number -d "Print the line number of the currently running script" +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a print-stack-trace -d "Print a list of all function calls leading up to running the current command" + +# The job-control command changes fish state. +complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a job-control -d "Set which jobs are under job control" +complete -f -c status -n "__fish_seen_subcommand_from job-control" -a full -d "Set all jobs under job control" +complete -f -c status -n "__fish_seen_subcommand_from job-control" -a interactive -d "Set only interactive jobs under job control" +complete -f -c status -n "__fish_seen_subcommand_from job-control" -a none -d "Set no jobs under job control" diff --git a/src/builtin.cpp b/src/builtin.cpp index 430d3e608..6172222a1 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -2158,104 +2158,218 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) return exit_res; } +enum status_cmd_t { + STATUS_NOOP, + STATUS_IS_LOGIN, + STATUS_IS_INTERACTIVE, + STATUS_IS_BLOCK, + STATUS_IS_COMMAND_SUB, + STATUS_IS_FULL_JOB_CTRL, + STATUS_IS_INTERACTIVE_JOB_CTRL, + STATUS_IS_NO_JOB_CTRL, + STATUS_CURRENT_FILENAME, + STATUS_CURRENT_LINE_NUMBER, + STATUS_SET_JOB_CONTROL, + STATUS_PRINT_STACK_TRACE +}; + +static status_cmd_t status_string_to_cmd(const wchar_t *status_command) { + if (wcscmp(status_command, L"is-login") == 0) { + return STATUS_IS_LOGIN; + } else if (wcscmp(status_command, L"is-interactive") == 0) { + return STATUS_IS_INTERACTIVE; + } else if (wcscmp(status_command, L"is-block") == 0) { + return STATUS_IS_BLOCK; + } else if (wcscmp(status_command, L"is-command-sub") == 0) { + return STATUS_IS_COMMAND_SUB; + } else if (wcscmp(status_command, L"is-full-job-control") == 0) { + return STATUS_IS_FULL_JOB_CTRL; + } else if (wcscmp(status_command, L"is-interactive-job-control") == 0) { + return STATUS_IS_INTERACTIVE_JOB_CTRL; + } else if (wcscmp(status_command, L"is-no-job-control") == 0) { + return STATUS_IS_NO_JOB_CTRL; + } else if (wcscmp(status_command, L"current-filename") == 0) { + return STATUS_CURRENT_FILENAME; + } else if (wcscmp(status_command, L"current-line-number") == 0) { + return STATUS_CURRENT_LINE_NUMBER; + } else if (wcscmp(status_command, L"job-control") == 0) { + return STATUS_SET_JOB_CONTROL; + } else if (wcscmp(status_command, L"print-stack-trace") == 0) { + return STATUS_PRINT_STACK_TRACE; + } + return STATUS_NOOP; +} + +static const wcstring status_cmd_to_string(status_cmd_t status_cmd) { + switch (status_cmd) { + case STATUS_NOOP: + return L"no-op"; + case STATUS_IS_LOGIN: + return L"is-login"; + case STATUS_IS_INTERACTIVE: + return L"is-interactive"; + case STATUS_IS_BLOCK: + return L"is-block"; + case STATUS_IS_COMMAND_SUB: + return L"is-command-sub"; + case STATUS_IS_FULL_JOB_CTRL: + return L"is-full-job-control"; + case STATUS_IS_INTERACTIVE_JOB_CTRL: + return L"is-interactive-job-control"; + case STATUS_IS_NO_JOB_CTRL: + return L"is-no-job-control"; + case STATUS_CURRENT_FILENAME: + return L"current-filename"; + case STATUS_CURRENT_LINE_NUMBER: + return L"current-line-number"; + case STATUS_SET_JOB_CONTROL: + return L"job-control"; + case STATUS_PRINT_STACK_TRACE: + return L"print-stack-trace"; + } +} + +/// Remember the status subcommand and disallow selecting more than one status subcommand. +static bool set_status_cmd(wchar_t *const cmd, status_cmd_t *status_cmd, status_cmd_t sub_cmd, + io_streams_t &streams) { + if (*status_cmd != STATUS_NOOP) { + wchar_t err_text[1024]; + swprintf(err_text, sizeof(err_text) / sizeof(wchar_t), + _(L"you cannot do both '%ls' and '%ls' in the same invocation"), + status_cmd_to_string(*status_cmd).c_str(), status_cmd_to_string(sub_cmd).c_str()); + streams.err.append_format(BUILTIN_ERR_COMBO2, cmd, err_text); + return false; + } + + *status_cmd = sub_cmd; + return true; +} + +#define CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) \ + if (args.size() != 0) { \ + streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, \ + status_cmd_to_string(status_cmd).c_str(), 0, args.size()); \ + status = STATUS_BUILTIN_ERROR; \ + break; \ + } + +int job_control_str_to_mode(const wchar_t *mode, wchar_t *cmd, io_streams_t &streams) { + if (wcscmp(mode, L"full") == 0) { + return JOB_CONTROL_ALL; + } else if (wcscmp(mode, L"interactive") == 0) { + return JOB_CONTROL_INTERACTIVE; + } else if (wcscmp(mode, L"none") == 0) { + return JOB_CONTROL_NONE; + } + streams.err.append_format(L"%ls: Invalid job control mode '%ls'\n", cmd, mode); + return -1; +} + /// The status builtin. Gives various status information on fish. static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { - wgetopter_t w; - enum { - NORMAL, - IS_SUBST, - IS_BLOCK, - IS_INTERACTIVE, - IS_LOGIN, - IS_FULL_JOB_CONTROL, - IS_INTERACTIVE_JOB_CONTROL, - IS_NO_JOB_CONTROL, - STACK_TRACE, - DONE, - CURRENT_FILENAME, - CURRENT_LINE_NUMBER - }; - - int mode = NORMAL; + wchar_t *cmd = argv[0]; int argc = builtin_count_args(argv); - int res = STATUS_BUILTIN_OK; + status_cmd_t status_cmd = STATUS_NOOP; + int status = STATUS_BUILTIN_OK; + int new_job_control_mode = -1; - const struct woption long_options[] = { - {L"help", no_argument, 0, 'h'}, - {L"is-command-substitution", no_argument, 0, 'c'}, - {L"is-block", no_argument, 0, 'b'}, - {L"is-interactive", no_argument, 0, 'i'}, - {L"is-login", no_argument, 0, 'l'}, - {L"is-full-job-control", no_argument, &mode, IS_FULL_JOB_CONTROL}, - {L"is-interactive-job-control", no_argument, &mode, IS_INTERACTIVE_JOB_CONTROL}, - {L"is-no-job-control", no_argument, &mode, IS_NO_JOB_CONTROL}, - {L"current-filename", no_argument, 0, 'f'}, - {L"current-line-number", no_argument, 0, 'n'}, - {L"job-control", required_argument, 0, 'j'}, - {L"print-stack-trace", no_argument, 0, 't'}, - {0, 0, 0, 0}}; - - while (1) { - int opt_index = 0; - - int opt = w.wgetopt_long(argc, argv, L":cbilfnhj:t", long_options, &opt_index); - if (opt == -1) break; + /// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to + /// the non-flag subcommand form. While these flags are deprecated they must be supported at + /// least until fish 3.0 and possibly longer to avoid breaking everyones config.fish and other + /// scripts. + const wchar_t *short_options = L":cbilfnhj:t"; + const struct woption long_options[] = {{L"help", no_argument, 0, 'h'}, + {L"is-command-substitution", no_argument, 0, 'c'}, + {L"is-block", no_argument, 0, 'b'}, + {L"is-interactive", no_argument, 0, 'i'}, + {L"is-login", no_argument, 0, 'l'}, + {L"is-full-job-control", no_argument, 0, 1}, + {L"is-interactive-job-control", no_argument, 0, 2}, + {L"is-no-job-control", no_argument, 0, 3}, + {L"current-filename", no_argument, 0, 'f'}, + {L"current-line-number", no_argument, 0, 'n'}, + {L"job-control", required_argument, 0, 'j'}, + {L"print-stack-trace", no_argument, 0, 't'}, + {0, 0, 0, 0}}; + int opt; + wgetopter_t w; + while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (opt) { - case 0: { - if (long_options[opt_index].flag != 0) break; - streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0], - long_options[opt_index].name); - builtin_print_help(parser, streams, argv[0], streams.err); - return STATUS_BUILTIN_ERROR; + case 1: { + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_FULL_JOB_CTRL, streams)) { + return STATUS_BUILTIN_ERROR; + } + break; + } + case 2: { + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_INTERACTIVE_JOB_CTRL, streams)) { + return STATUS_BUILTIN_ERROR; + } + break; + } + case 3: { + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_NO_JOB_CTRL, streams)) { + return STATUS_BUILTIN_ERROR; + } + break; } case 'c': { - mode = IS_SUBST; + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_COMMAND_SUB, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'b': { - mode = IS_BLOCK; + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_BLOCK, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'i': { - mode = IS_INTERACTIVE; + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_INTERACTIVE, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'l': { - mode = IS_LOGIN; + if (!set_status_cmd(cmd, &status_cmd, STATUS_IS_LOGIN, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'f': { - mode = CURRENT_FILENAME; + if (!set_status_cmd(cmd, &status_cmd, STATUS_CURRENT_FILENAME, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'n': { - mode = CURRENT_LINE_NUMBER; + if (!set_status_cmd(cmd, &status_cmd, STATUS_CURRENT_LINE_NUMBER, streams)) { + return STATUS_BUILTIN_ERROR; + } + break; + } + case 'j': { + if (!set_status_cmd(cmd, &status_cmd, STATUS_SET_JOB_CONTROL, streams)) { + return STATUS_BUILTIN_ERROR; + } + new_job_control_mode = job_control_str_to_mode(w.woptarg, cmd, streams); + if (new_job_control_mode == -1) { + return STATUS_BUILTIN_ERROR; + } + break; + } + case 't': { + if (!set_status_cmd(cmd, &status_cmd, STATUS_PRINT_STACK_TRACE, streams)) { + return STATUS_BUILTIN_ERROR; + } break; } case 'h': { builtin_print_help(parser, streams, argv[0], streams.out); return STATUS_BUILTIN_OK; } - case 'j': { - if (wcscmp(w.woptarg, L"full") == 0) - job_control_mode = JOB_CONTROL_ALL; - else if (wcscmp(w.woptarg, L"interactive") == 0) - job_control_mode = JOB_CONTROL_INTERACTIVE; - else if (wcscmp(w.woptarg, L"none") == 0) - job_control_mode = JOB_CONTROL_NONE; - else { - streams.err.append_format(L"%ls: Invalid job control mode '%ls'\n", L"status", - w.woptarg); - res = STATUS_BUILTIN_ERROR; - } - mode = DONE; - break; - } - case 't': { - mode = STACK_TRACE; - break; - } case ':': { builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]); return STATUS_BUILTIN_ERROR; @@ -2265,57 +2379,30 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg return STATUS_BUILTIN_ERROR; } default: { - DIE("unexpected opt"); + DIE("unexpected retval from wgetopt_long"); break; } } } - if (res == STATUS_BUILTIN_ERROR) { - return res; + // If a status command hasn't already been specified via a flag check the first word. + // Note that this can be simplified after we eliminate allowing subcommands as flags. + if (w.woptind < argc) { + status_cmd_t subcmd = status_string_to_cmd(argv[w.woptind]); + if (subcmd != STATUS_NOOP) { + if (!set_status_cmd(cmd, &status_cmd, subcmd, streams)) { + return STATUS_BUILTIN_ERROR; + } + w.woptind++; + } } - switch (mode) { - case DONE: { - return STATUS_BUILTIN_OK; - } - case CURRENT_FILENAME: { - const wchar_t *fn = parser.current_filename(); + // Every argument that we haven't consumed already is an argument for a subcommand. + const wcstring_list_t args(argv + w.woptind, argv + argc); - if (!fn) fn = _(L"Standard input"); - streams.out.append_format(L"%ls\n", fn); - return STATUS_BUILTIN_OK; - } - case CURRENT_LINE_NUMBER: { - streams.out.append_format(L"%d\n", parser.get_lineno()); - return STATUS_BUILTIN_OK; - } - case IS_INTERACTIVE: { - return !is_interactive_session; - } - case IS_SUBST: { - return !is_subshell; - } - case IS_BLOCK: { - return !is_block; - } - case IS_LOGIN: { - return !is_login; - } - case IS_FULL_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_ALL; - } - case IS_INTERACTIVE_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_INTERACTIVE; - } - case IS_NO_JOB_CONTROL: { - return job_control_mode != JOB_CONTROL_NONE; - } - case STACK_TRACE: { - streams.out.append(parser.stack_trace()); - return STATUS_BUILTIN_OK; - } - case NORMAL: { + switch (status_cmd) { + case STATUS_NOOP: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) if (is_login) { streams.out.append_format(_(L"This is a login shell\n")); } else { @@ -2328,12 +2415,84 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg ? _(L"Only on interactive jobs") : (job_control_mode == JOB_CONTROL_NONE ? _(L"Never") : _(L"Always"))); streams.out.append(parser.stack_trace()); - return STATUS_BUILTIN_OK; + break; + } + case STATUS_SET_JOB_CONTROL: { + if (new_job_control_mode != -1) { + // Flag form was used. + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + } else { + if (args.size() != 1) { + streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, + status_cmd_to_string(status_cmd).c_str(), 1, + args.size()); + status = STATUS_BUILTIN_ERROR; + break; + } + new_job_control_mode = job_control_str_to_mode(args[0].c_str(), cmd, streams); + if (new_job_control_mode == -1) { + return STATUS_BUILTIN_ERROR; + } + } + job_control_mode = new_job_control_mode; + break; + } + case STATUS_CURRENT_FILENAME: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + const wchar_t *fn = parser.current_filename(); + + if (!fn) fn = _(L"Standard input"); + streams.out.append_format(L"%ls\n", fn); + break; + } + case STATUS_CURRENT_LINE_NUMBER: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + streams.out.append_format(L"%d\n", parser.get_lineno()); + break; + } + case STATUS_IS_INTERACTIVE: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = !is_interactive_session; + break; + } + case STATUS_IS_COMMAND_SUB: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = !is_subshell; + break; + } + case STATUS_IS_BLOCK: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = !is_block; + break; + } + case STATUS_IS_LOGIN: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = !is_login; + break; + } + case STATUS_IS_FULL_JOB_CTRL: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = job_control_mode != JOB_CONTROL_ALL; + break; + } + case STATUS_IS_INTERACTIVE_JOB_CTRL: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = job_control_mode != JOB_CONTROL_INTERACTIVE; + break; + } + case STATUS_IS_NO_JOB_CTRL: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + status = job_control_mode != JOB_CONTROL_NONE; + break; + } + case STATUS_PRINT_STACK_TRACE: { + CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd) + streams.out.append(parser.stack_trace()); + break; } - default: { break; } } - DIE("status subcommand not handled"); + return status; } /// The exit builtin. Calls reader_exit to exit and returns the value specified. @@ -2905,8 +3064,10 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar bool case_sensitive = false; bool null_terminate = false; - // TODO: Remove the long options that correspond to subcommands (e.g., '--delete') on or after - // 2017-10 (which will be a full year after these flags have been deprecated). + /// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to + /// the non-flag subcommand form. While many of these flags are deprecated they must be + /// supported at least until fish 3.0 and possibly longer to avoid breaking everyones + /// config.fish and other scripts. const wchar_t *short_options = L":Cmn:epchtz"; const struct woption long_options[] = {{L"prefix", no_argument, NULL, 'p'}, {L"contains", no_argument, NULL, 'c'}, @@ -3035,9 +3196,12 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar // If a history command hasn't already been specified via a flag check the first word. // Note that this can be simplified after we eliminate allowing subcommands as flags. // See the TODO above regarding the `long_options` array. - if (hist_cmd == HIST_NOOP && w.woptind < argc) { - hist_cmd = hist_string_to_cmd(argv[w.woptind]); - if (hist_cmd != HIST_NOOP) { + if (w.woptind < argc) { + hist_cmd_t subcmd = hist_string_to_cmd(argv[w.woptind]); + if (subcmd != HIST_NOOP) { + if (!set_hist_cmd(cmd, &hist_cmd, subcmd, streams)) { + return STATUS_BUILTIN_ERROR; + } w.woptind++; } } diff --git a/tests/status.err b/tests/status.err index b04178e47..d2b89daf6 100644 --- a/tests/status.err +++ b/tests/status.err @@ -1,2 +1,8 @@ fish: An error occurred while redirecting file '/' open: Is a directory +status: Invalid combination of options, +you cannot do both 'is-interactive' and 'is-login' in the same invocation +status: Invalid combination of options, +you cannot do both 'is-block' and 'is-interactive' in the same invocation +status: Invalid job control mode 'full1' +status: Invalid job control mode '1none' diff --git a/tests/status.in b/tests/status.in index 875f62f38..cdda0d76a 100644 --- a/tests/status.in +++ b/tests/status.in @@ -1,17 +1,41 @@ # vim: set filetype=fish: status -b -or echo 'top level' +and echo '"status -b" unexpectedly returned true at top level' begin status -b + or echo '"status -b" unexpectedly returned false inside a begin block' end -and echo 'block' # Issue #1728 # Bad file redirection on a block causes `status --is-block` to return 0 forever. begin; end >/ # / is a directory, it can't be opened for writing status -b -and echo 'unexpected block' +and echo '"status -b" unexpectedly returned true after bad redirect on a begin block' -true +status -l +and echo '"status -l" unexpectedly returned true for a non-login shell' + +status -i +and echo '"status -i" unexpectedly returned true for a non-interactive shell' + +status is-login +and echo '"status is-login" unexpectedly returned true for a non-login shell' + +status is-interactive +and echo '"status is-interactive" unexpectedly returned true for a non-interactive shell' + +# We should get an error message about an invalid combination of flags. +status --is-interactive --is-login + +# We should get an error message about an unexpected arg for `status +# is-block`. +status -b is-interactive + +# Try to set the job control to an invalid mode. +status job-control full1 +status --job-control=1none + +# Now set it to a valid mode. +status job-control none diff --git a/tests/status.out b/tests/status.out index a6546ffd0..e69de29bb 100644 --- a/tests/status.out +++ b/tests/status.out @@ -1,2 +0,0 @@ -top level -block From 609100c19644201c7ef306d2d03c0e017108f2ac Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Sat, 5 Nov 2016 22:03:20 -0700 Subject: [PATCH 112/112] detect if the magic fish wide chars can be encoded Verified on Cygwin on MS Windows 7 when invoked as `env LANG=zh_CN.GBK@cjknarrow fish`. No regression seen when run on other systems with UTF-8 locales. Fixes #3503 --- src/common.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index b54f58bf0..76d2b752a 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -282,7 +282,7 @@ std::string wcs2string(const wcstring &input) { result.reserve(input.size()); mbstate_t state = {}; - char converted[MB_LEN_MAX + 1]; + char converted[MB_LEN_MAX]; for (size_t i = 0; i < input.size(); i++) { wchar_t wc = input[i]; @@ -300,8 +300,8 @@ std::string wcs2string(const wcstring &input) { } else { memset(converted, 0, sizeof converted); size_t len = wcrtomb(converted, wc, &state); - if (len == (size_t)(-1)) { - debug(1, L"Wide character %d has no narrow representation", wc); + if (len == (size_t)-1) { + debug(1, L"Wide character U+%4X has no narrow representation", wc); memset(&state, 0, sizeof(state)); } else { result.append(converted, len); @@ -341,7 +341,7 @@ static char *wcs2str_internal(const wchar_t *in, char *out) { } else { size_t len = wcrtomb(&out[out_pos], in[in_pos], &state); if (len == (size_t)-1) { - debug(1, L"Wide character %d has no narrow representation", in[in_pos]); + debug(1, L"Wide character U+%4X has no narrow representation", in[in_pos]); memset(&state, 0, sizeof(state)); } else { out_pos += len; @@ -354,6 +354,14 @@ static char *wcs2str_internal(const wchar_t *in, char *out) { return out; } +/// Test if the character can be encoded using the current locale. +static bool can_be_encoded(wchar_t wc) { + char converted[MB_LEN_MAX]; + mbstate_t state = {}; + + return wcrtomb(converted, wc, &state) != (size_t)-1; +} + wcstring format_string(const wchar_t *format, ...) { va_list va; va_start(va, format); @@ -444,11 +452,11 @@ wchar_t *quote_end(const wchar_t *pos) { } void fish_setlocale() { - // Use ellipsis if on known unicode system, otherwise use $. - ellipsis_char = (fish_wcwidth(L'\x2026') > 0) ? L'\x2026' : L'$'; + // Use the Unicode "ellipsis" symbol if it can be encoded using the current locale. + ellipsis_char = can_be_encoded(L'\x2026') ? L'\x2026' : L'$'; - // U+23CE is the "return" character - omitted_newline_char = (fish_wcwidth(L'\x23CE') > 0) ? L'\x23CE' : L'~'; + // Use the Unicode "return" symbol if it can be encoded using the current locale. + omitted_newline_char = can_be_encoded(L'\x23CE') ? L'\x23CE' : L'~'; } bool contains_internal(const wchar_t *a, int vararg_handle, ...) {